import { isMinusZero } from './float'; export const MAX_INT8 = 0x7f; export const MIN_INT8 = -MAX_INT8 - 1; export const MAX_UINT8 = 0xff; export const MIN_UINT8 = 0; export const MAX_INT16 = 0x7fff; export const MIN_INT16 = -MAX_INT16 - 1; export const MAX_UINT16 = 0xffff; export const MIN_UINT16 = 0; export const MAX_INT32 = 0x7fffffff; export const MIN_INT32 = -MAX_INT32 - 1; export const MAX_UINT32 = 0xffffffff; export const MIN_UINT32 = 0; //! \see https://stackoverflow.com/questions/596467/how-do-i-convert-a-float-number-to-a-whole-number-in-javascript export function trunc(n: number) { return n - n % 1; } function isqrtHelper(n: number, lo: number, hi: number): number { if (lo === hi) return lo; const mid = trunc((lo + hi + 1) / 2); return n / mid < mid ? // n < mid * mid isqrtHelper(n, lo, mid - 1) : isqrtHelper(n, mid, hi); } //! \see https://stackoverflow.com/questions/8622256/in-c11-is-sqrt-defined-as-constexpr export function isqrt(n: number) { if (n < 0) return NaN; return isqrtHelper(trunc(n), 0, trunc(n / 2) + 1); } //! \see https://stackoverflow.com/questions/199333/how-to-detect-integer-overflow //! \see https://stackoverflow.com/questions/1815367/catch-and-compute-overflow-during-multiplication-of-two-large-integers export function isMulOverflow(a: number, b: number, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER) { if (b === 0) return false; const a_gt_0 = a > 0; if (a_gt_0 === b > 0) return a_gt_0 ? a > max / b : a < max / b; return a_gt_0 ? a > min / b : a < min / b; } export function isAddOverflow(a: number, b: number, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER) { return (b > 0 && a > max - b) || (b < 0 && a < min - b); } export function isSubOverflow(a: number, b: number, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER) { return (b < 0) && (a > max + b) || (b > 0) && (a < min + b); } export function isInteger(x: number) { // Number.isInteger() w/o typecheck, w/ -0 check return isFinite(x) && Math.floor(x) === x && !isMinusZero(x); } export function isSafeInteger(x: number) { // Number.isSafeInteger() w/o typecheck, w/ -0 check return isInteger(x) && Math.abs(x) <= Number.MAX_SAFE_INTEGER; } export function isInt32(x: number) { return ((x | 0) === x) && !isMinusZero(x); } export function isUint32(x: number) { return ((x >>> 0) === x) && !isMinusZero(x); }