diff --git a/.gitignore b/.gitignore index 6ee9be0..fb47a29 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ Makefile depend zarith_version.ml +html diff --git a/README.md b/README.md index d552663..f2a4607 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,8 @@ Source files | Description --------------------|----------------------------------------- configure | configuration script z.ml[i] | Z module and implementation for small integers - caml_z.c | C implementation + caml_z.c | C implementation using GMP/MPIR + caml_z_tommath.c | C implementation using LibTomMath big_int_z.ml[i] | wrapper to provide a Big_int compatible API to Z q.ml[i] | rational library, pure OCaml on top of Z zarith_top.ml | toplevel module to provide pretty-printing @@ -127,3 +128,20 @@ Source files | Description zarith.opam | package description for opam z_mlgmpidl.ml[i] | conversion between Zarith and MLGMPIDL tests/ | simple regression tests and benchmarks + + +## BACK-END COMPATIBILITY + +Zarith supports several back-ends to implement multi-word integers: GMP, MPIR, and LibTomMath. +GMP is the default. +The `configure` script will try them in the following order: GMP, MPIR, LibTomMath. +The choice of back-end can be overridden with the `-gmp`, `-mpir`, and `-tommath` configure options. + +GMP and MPIR support all functions and should give identical results. +The hashing function is identical and the marshalling format is compatible for GMP and MPIR, and for 32-bit and 64-bit. + +LibTomMath support is partial and experimental. +Not all functions are implemented. +Unsupported functions raise a `Failure` exception. +The hashing function is different from the GMP/MPIR one, and the hashed value actually depends on the digit bit-size used by LibTomMath (which can be queried with `digit_bits ()`). +Additionally, the marshaling format is incompatible with the GMP/MPIR one, although it is independent from the digit bit-size. diff --git a/caml_z.c b/caml_z.c index a60637c..9d37599 100644 --- a/caml_z.c +++ b/caml_z.c @@ -3538,6 +3538,11 @@ CAMLprim value ml_z_init() return Val_unit; } +CAMLprim value ml_z_digit_bits() +{ + return Val_long(sizeof(mp_limb_t) * 8); +} + #ifdef __cplusplus } #endif diff --git a/caml_z_tommath.c b/caml_z_tommath.c new file mode 100644 index 0000000..3ca36c8 --- /dev/null +++ b/caml_z_tommath.c @@ -0,0 +1,2348 @@ +/** + Implementation of Z module. + + This version uses LibTomMath instead of GMP / MPIR. + Not all functions are supported. + Requires LibTomMath 1.2.0. + + This file is part of the Zarith library + http://forge.ocamlcore.org/projects/zarith . + It is distributed under LGPL 2 licensing, with static linking exception. + See the LICENSE file included in the distribution. + + Copyright (c) 2010-2011 Antoine Miné, Abstraction project. + Abstraction is part of the LIENS (Laboratoire d'Informatique de l'ENS), + a joint laboratory by: + CNRS (Centre national de la recherche scientifique, France), + ENS (École normale supérieure, Paris, France), + INRIA Rocquencourt (Institut national de recherche en informatique, France). + +*/ + + +/*--------------------------------------------------- + INCLUDES + ---------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define inline __inline + +#ifdef _MSC_VER +#include +#include +#endif + +/* The "__has_builtin" special macro from Clang */ +#ifdef __has_builtin +#define HAS_BUILTIN(x) __has_builtin(x) +#else +#define HAS_BUILTIN(x) 0 +#endif + +/* Whether the fast path (arguments and result are small integers) + has already be handled in OCaml, so that there is no need to + re-test for it in C functions. + Applies to: neg, abs, add, sub, mul, div, rem, succ, pred, + logand, logor, logxor, lognot, shifts, divexact. +*/ +#define Z_FAST_PATH_IN_OCAML 1 + + +/*--------------------------------------------------- + DATA STRUCTURES + ---------------------------------------------------*/ + + +/* bounds of an Ocaml int */ +#ifdef ARCH_SIXTYFOUR +#define Z_MAX_INT 0x3fffffffffffffff +#define Z_MIN_INT (-0x4000000000000000) +#else +#define Z_MAX_INT 0x3fffffff +#define Z_MIN_INT (-0x40000000) +#endif +#define Z_FITS_INT(v) ((v) >= Z_MIN_INT && (v) <= Z_MAX_INT) + +static mp_int z_max_int, z_min_int; +static mp_int z_max_intnat, z_min_intnat; +static mp_int z_max_int32, z_min_int32; +static mp_int z_max_int64, z_min_int64; +static mp_int z_max_intnat_unsigned; +static mp_int z_max_int32_unsigned; +static mp_int z_max_int64_unsigned; + +/* greatest/smallest double that can fit in an int */ +#ifdef ARCH_SIXTYFOUR +#define Z_MAX_INT_FL 0x3ffffffffffffe00 +#define Z_MIN_INT_FL (-0x4000000000000000) +#else +#define Z_MAX_INT_FL Z_MAX_INT +#define Z_MIN_INT_FL Z_MIN_INT +#endif + +/* safe bounds to avoid overflow in multiplication */ +#ifdef ARCH_SIXTYFOUR +#define Z_MAX_HINT 0x3fffffff +#else +#define Z_MAX_HINT 0x3fff +#endif +#define Z_MIN_HINT (-Z_MAX_HINT) +#define Z_FITS_HINT(v) ((v) >= Z_MIN_HINT && (v) <= Z_MAX_HINT) + +/* hi bit of OCaml int32, int64 & nativeint */ +#define Z_HI_INT32 0x80000000 +#define Z_HI_UINT32 0x100000000LL +#define Z_HI_INT64 0x8000000000000000LL +#ifdef ARCH_SIXTYFOUR +#define Z_HI_INTNAT Z_HI_INT64 +#define Z_HI_INT 0x4000000000000000 +#define Z_INTNAT_BITS 64 +#else +#define Z_HI_INTNAT Z_HI_INT32 +#define Z_HI_INT 0x40000000 +#define Z_INTNAT_BITS 32 +#endif + +/* safe bounds for the length of a base n string fitting in a native + int. Defined as the result of (n - 2) log_base(2) with n = 64 or + 32. +*/ +#ifdef ARCH_SIXTYFOUR +#define Z_BASE16_LENGTH_OP 15 +#define Z_BASE10_LENGTH_OP 18 +#define Z_BASE8_LENGTH_OP 20 +#define Z_BASE2_LENGTH_OP 62 +#else +#define Z_BASE16_LENGTH_OP 7 +#define Z_BASE10_LENGTH_OP 9 +#define Z_BASE8_LENGTH_OP 10 +#define Z_BASE2_LENGTH_OP 30 +#endif + +#ifdef _MSC_VER +#define UNUSED_PARAM +#else +#define UNUSED_PARAM __attribute__((unused)) +#endif + +#define Z_MP(x) ((mp_int*)Data_custom_val((x))) +#define Z_SIGN(x) (Z_MP((x))->sign) +#define Z_LIMB(x) (Z_MP((x))->dp) + +#define Z_ISZERO(x) (Is_long((x)) ? Long_val((x)) == 0 : mp_iszero(Z_MP((x)))) +#define Z_ISNEG(x) (Is_long((x)) ? Long_val((x)) < 0 : mp_isneg(Z_MP((x)))) + + +/*--------------------------------------------------- + UTILITIES + ---------------------------------------------------*/ + + +extern struct custom_operations ml_z_custom_ops; + +static void ml_z_raise_overflow() +{ + caml_raise_constant(*caml_named_value("ml_z_overflow")); +} + +#define ml_z_raise_divide_by_zero() \ + caml_raise_zero_divide() + +#define ml_z_raise_out_of_memory() \ + caml_raise_out_of_memory() + +static value ml_z_alloc() +{ + value v; + v = caml_alloc_custom(&ml_z_custom_ops, sizeof(mp_int), 0, 1); + if (mp_init(Z_MP(v)) != MP_OKAY) + ml_z_raise_out_of_memory(); + return v; +} + + +#ifdef ARCH_SIXTYFOUR +#define MP_INIT_VALUE mp_init_i64 +#else +#define MP_INIT_VALUE mp_init_i32 +#endif + +#define Z_DECL(arg) \ + const mp_int *mp_##arg; \ + mp_int mp_s_##arg \ + +#define Z_ARG(arg) \ + if (Is_long(arg)) { \ + mp_##arg = & mp_s_##arg; \ + if (MP_INIT_VALUE((mp_int*)mp_##arg, Long_val(arg)) != MP_OKAY) \ + ml_z_raise_out_of_memory(); \ + } \ + else { \ + mp_##arg = Z_MP(arg); \ + } + +#define Z_REFRESH(arg) \ + if (!Is_long(arg)) \ + mp_##arg = Z_MP(arg); + +#define Z_END_ARG(arg) \ + if (Is_long(arg)) { \ + mp_clear((mp_int*)mp_##arg); \ + } + +static value ml_z_reduce(value r) +{ + if (mp_cmp(Z_MP(r), &z_min_int) >= 0 && + mp_cmp(Z_MP(r), &z_max_int) <= 0) { + /* can be represented in a value, we free the mp_int */ + intnat x = mp_get_i64(Z_MP(r)); + mp_clear(Z_MP(r)); + return Val_long(x); + } + return r; +} + + +/*--------------------------------------------------- + CONVERSION FUNCTIONS + ---------------------------------------------------*/ + +CAMLprim value ml_z_of_int(value v) +{ + return v; +} + +CAMLprim value ml_z_of_nativeint(value v) +{ + intnat x; + value r; + x = Nativeint_val(v); + if (Z_FITS_INT(x)) return Val_long(x); + r = ml_z_alloc(); +#ifdef ARCH_SIXTYFOUR + mp_set_i64(Z_MP(r), x); +#else + mp_set_i32(Z_MP(r), x); +#endif + return r; +} + +CAMLprim value ml_z_of_int32(value v) +{ + int32_t x; + value r; + x = Int32_val(v); +#ifdef ARCH_SIXTYFOUR + return Val_long(x); +#else + if (Z_FITS_INT(x)) return Val_long(x); +#endif + r = ml_z_alloc(); + mp_set_i32(Z_MP(r), x); + return r; +} + +CAMLprim value ml_z_of_int64(value v) +{ + int64_t x; + value r; + x = Int64_val(v); + if (Z_FITS_INT(x)) return Val_long(x); + r = ml_z_alloc(); + mp_set_i64(Z_MP(r), x); + return r; +} + +CAMLprim value ml_z_of_float(value v) +{ + double x; + value r; + x = Double_val(v); + if (x >= Z_MIN_INT_FL && x <= Z_MAX_INT_FL) return Val_long((intnat) x); + r = ml_z_alloc(); + if (mp_set_double(Z_MP(r), x) != MP_OKAY) { + mp_clear(Z_MP(r)); + ml_z_raise_overflow(); + } + return r; +} + +CAMLprim value ml_z_of_substring_base(value b, value v, value offset, value length) +{ + CAMLparam1(v); + CAMLlocal1(r); + intnat ofs = Long_val(offset); + intnat len = Long_val(length); + /* make sure the ofs/length make sense */ + if (ofs < 0 + || len < 0 + || (intnat)caml_string_length(v) < ofs + len) + caml_invalid_argument("Z.of_substring_base: invalid offset or length"); + /* process the string */ + const char *d = String_val(v) + ofs; + const char *end = d + len; + ptrdiff_t i, j, sz; + int sign = 0; + intnat base = Long_val(b); + /* We allow [d] to advance beyond [end] while parsing the prefix: + sign, base, and/or leading zeros. + This simplifies the code, and reading these locations is safe since + we don't progress beyond a terminating null character. + At the end of the prefix, if we ran past the end, we return 0. + */ + /* get optional sign */ + if (*d == '-') { sign = 1; d++; } + if (*d == '+') d++; + /* get optional base */ + if (!base) { + base = 10; + if (*d == '0') { + d++; + if (*d == 'o' || *d == 'O') { base = 8; d++; } + else if (*d == 'x' || *d == 'X') { base = 16; d++; } + else if (*d == 'b' || *d == 'B') { base = 2; d++; } + else { + /* The leading zero is not part of a base prefix. This is an + important distinction for the check below looking at + leading underscore + */ + d--; } + } + } + if (base < 2 || base > 16) + caml_invalid_argument("Z.of_substring_base: base must be between 2 and 16"); + /* we do not allow leading underscore */ + if (*d == '_') + caml_invalid_argument("Z.of_substring_base: invalid digit"); + while (*d == '0' || *d == '_') d++; + /* sz is the length of the substring that has not been consumed above. */ + sz = end - d; + if (sz <= 0) { + /* "+", "-", "0x" are parsed as 0. */ + r = Val_long(0); + } + /* Process common cases (fits into a native integer) */ + else if ((base == 10 && sz <= Z_BASE10_LENGTH_OP) + || (base == 16 && sz <= Z_BASE16_LENGTH_OP) + || (base == 8 && sz <= Z_BASE8_LENGTH_OP) + || (base == 2 && sz <= Z_BASE2_LENGTH_OP)) { + intnat ret = 0; + for (i = 0; i < sz; i++) { + int digit = 0; + if (d[i] == '_') continue; + if (d[i] >= '0' && d[i] <= '9') digit = d[i] - '0'; + else if (d[i] >= 'a' && d[i] <= 'f') digit = d[i] - 'a' + 10; + else if (d[i] >= 'A' && d[i] <= 'F') digit = d[i] - 'A' + 10; + else caml_invalid_argument("Z.of_substring_base: invalid digit"); + if (digit >= base) + caml_invalid_argument("Z.of_substring_base: invalid digit"); + ret = ret * base + digit; + } + r = Val_long(ret * (sign ? -1 : 1)); + } else { + /* copy the substring, ignoring underscores */ + char* dd = (char*)malloc(sz + 1); + if (!dd) caml_raise_out_of_memory(); + for (i = 0, j = 0; i < sz; i++) { + if (d[i] == '_') continue; + dd[j++] = d[i]; + } + dd[j] = 0; + r = ml_z_alloc(); + if (mp_read_radix(Z_MP(r), dd, base) != MP_OKAY) { + free(dd); + mp_clear(Z_MP(r)); + caml_invalid_argument("Z.of_substring_base: invalid string"); + } + free(dd); + if (sign) { + if (mp_neg(Z_MP(r), Z_MP(r)) != MP_OKAY) { + mp_clear(Z_MP(r)); + caml_failwith("Z.of_substring_base: internal error"); + } + } + r = ml_z_reduce(r); + } + CAMLreturn(r); +} + +CAMLprim value ml_z_to_int(value v) +{ + if (Is_long(v)) return v; + if (mp_cmp(Z_MP(v), &z_min_int) >= 0 && + mp_cmp(Z_MP(v), &z_max_int) <= 0) { +#ifdef ARCH_SIXTYFOUR + return Val_long(mp_get_i64(Z_MP(v))); +#else + return Val_long(mp_get_i32(Z_MP(v))); +#endif + } + ml_z_raise_overflow(); + return 0; +} + +CAMLprim value ml_z_to_nativeint(value v) +{ + if (Is_long(v)) return caml_copy_nativeint(Long_val(v)); + if (mp_cmp(Z_MP(v), &z_min_intnat) >= 0 && + mp_cmp(Z_MP(v), &z_max_intnat) <= 0) { +#ifdef ARCH_SIXTYFOUR + return caml_copy_nativeint(mp_get_i64(Z_MP(v))); +#else + return caml_copy_nativeint(mp_get_i32(Z_MP(v))); +#endif + } + ml_z_raise_overflow(); + return 0; +} + +CAMLprim value ml_z_to_int32(value v) +{ + if (Is_long(v)) { + intnat x = Long_val(v); +#ifdef ARCH_SIXTYFOUR + if (x >= (intnat)Z_HI_INT32 || x < -(intnat)Z_HI_INT32) + ml_z_raise_overflow(); +#endif + return caml_copy_int32(x); + } + if (mp_cmp(Z_MP(v), &z_min_int32) >= 0 && + mp_cmp(Z_MP(v), &z_max_int32) <= 0) { + return caml_copy_int32(mp_get_i32(Z_MP(v))); + } + ml_z_raise_overflow(); + return 0; +} + +CAMLprim value ml_z_to_int64(value v) +{ + if (Is_long(v)) return caml_copy_int64(Long_val(v)); + if (mp_cmp(Z_MP(v), &z_min_int64) >= 0 && + mp_cmp(Z_MP(v), &z_max_int64) <= 0) { + return caml_copy_int64(mp_get_i64(Z_MP(v))); + } + ml_z_raise_overflow(); + return 0; +} + +CAMLprim value ml_z_to_nativeint_unsigned(value v) +{ + if (Is_long(v)) { + if (Long_val(v) < 0) + ml_z_raise_overflow(); + return caml_copy_nativeint(Long_val(v)); + } + if (!mp_isneg(Z_MP(v)) && + mp_cmp(Z_MP(v), &z_max_intnat_unsigned) <= 0) { +#ifdef ARCH_SIXTYFOUR + return caml_copy_nativeint(mp_get_u64(Z_MP(v))); +#else + return caml_copy_nativeint(mp_get_u32(Z_MP(v))); +#endif + } + ml_z_raise_overflow(); + return 0; +} + +CAMLprim value ml_z_to_int32_unsigned(value v) +{ + if (Is_long(v)) { + intnat x = Long_val(v); +#ifdef ARCH_SIXTYFOUR + if (x >= (intnat)Z_HI_UINT32 || x < 0) + ml_z_raise_overflow(); +#endif + return caml_copy_int32(x); + } + if (!mp_isneg(Z_MP(v)) && + mp_cmp(Z_MP(v), &z_max_int32_unsigned) <= 0) { + return caml_copy_int32(mp_get_u32(Z_MP(v))); + } + ml_z_raise_overflow(); + return 0; +} + +CAMLprim value ml_z_to_int64_unsigned(value v) +{ + if (Is_long(v)) { + if (Long_val(v) < 0) + ml_z_raise_overflow(); + return caml_copy_int64(Long_val(v)); + } + if (!mp_isneg(Z_MP(v)) && + mp_cmp(Z_MP(v), &z_max_int64_unsigned) <= 0) { + return caml_copy_int64(mp_get_u64(Z_MP(v))); + } + ml_z_raise_overflow(); + return 0; +} + +CAMLprim value ml_z_format(value f, value v) +{ + CAMLparam2(f,v); + Z_DECL(v); + char* buf, *dst; + int sz = 0; + size_t i, max_size, size_dst = 0; + value r; + const char* fmt = String_val(f); + int base = 10; /* base */ + int cas = 0; /* uppercase X / lowercase x */ + ptrdiff_t width = 0; + int alt = 0; /* alternate # */ + int dir = 0; /* right / left adjusted */ + char sign = 0; /* sign char */ + char pad = ' '; /* padding char */ + char *prefix = ""; + Z_ARG(v); + + /* parse format */ + while (*fmt == '%') fmt++; + for (; ; fmt++) { + if (*fmt == '#') alt = 1; + else if (*fmt == '0') pad = '0'; + else if (*fmt == '-') dir = 1; + else if (*fmt == ' ' || *fmt == '+') sign = *fmt; + else break; + } + if (mp_isneg(mp_v)) sign = '-'; + for (;*fmt>='0' && *fmt<='9';fmt++) + width = 10*width + *fmt-'0'; + switch (*fmt) { + case 'i': case 'd': case 'u': break; + case 'b': base = 2; if (alt) prefix = "0b"; break; + case 'o': base = 8; if (alt) prefix = "0o"; break; + case 'x': base = 16; if (alt) prefix = "0x"; cas = 1; break; + case 'X': base = 16; if (alt) prefix = "0X"; break; + default: Z_END_ARG(v); caml_invalid_argument("Z.format: invalid format"); + } + if (dir) pad = ' '; + + /* get number of digits (can be overapproximated) */ + if (mp_radix_size(mp_v, base, &sz) != MP_OKAY || sz == 0) { + Z_END_ARG(v); + caml_failwith("Z.format: internal error"); + } + + /* we need space for sign + prefix + digits + 1 + padding + terminal 0 */ + max_size = 1 + 2 + sz + 1 + 2*width + 1; + buf = (char*) malloc(max_size); + if (!buf) caml_raise_out_of_memory(); + dst = buf + 1 + 2 + width; + + /* get digits */ + if (mp_to_radix (mp_v, dst, sz, &size_dst, base) != MP_OKAY || + size_dst == 0 || + dst + size_dst >= buf + max_size) { + Z_END_ARG(v); + free(buf); + caml_failwith("Z.format: internal error"); + } + size_dst--; + + /* undo sign */ + if (mp_isneg(mp_v)) { + dst++; + size_dst--; + } + + /* lower-case conversion */ + if (cas) { + for (i = 0; i < size_dst; i++) + if (dst[i] >= 'A') + dst[i] += ('a' - 'A'); + } + + /* add prefix, sign & padding */ + if (pad == ' ') { + if (dir) { + /* left alignment */ + for (i = strlen(prefix); i > 0; i--, size_dst++) + *(--dst) = prefix[i-1]; + if (sign) { *(--dst) = sign; size_dst++; } + for (; (ptrdiff_t)size_dst < width; size_dst++) + dst[size_dst] = pad; + } + else { + /* right alignment, space padding */ + for (i = strlen(prefix); i > 0; i--, size_dst++) + *(--dst) = prefix[i-1]; + if (sign) { *(--dst) = sign; size_dst++; } + for (; (ptrdiff_t)size_dst < width; size_dst++) *(--dst) = pad; + } + } + else { + /* right alignment, non-space padding */ + width -= strlen(prefix) + (sign ? 1 : 0); + for (; (ptrdiff_t)size_dst < width; size_dst++) *(--dst) = pad; + for (i = strlen(prefix); i > 0; i--, size_dst++) + *(--dst) = prefix[i-1]; + if (sign) { *(--dst) = sign; size_dst++; } + } + dst[size_dst] = 0; + if (dst < buf || dst + size_dst >= buf + max_size) + caml_failwith("Z.format: internal error"); + r = caml_copy_string(dst); + free(buf); + Z_END_ARG(v); + CAMLreturn(r); +} + +/* common part to ml_z_extract and ml_z_extract_internal */ +void ml_z_extract_internal(mp_int* dst, value arg, uintnat o, uintnat l) { + Z_DECL(arg); + size_t sz, i; + mp_int rem; + + sz = (l + MP_DIGIT_BIT - 1) / MP_DIGIT_BIT; + + if (mp_init(&rem) != MP_OKAY) + ml_z_raise_out_of_memory(); + + /* shift */ + Z_ARG(arg); + if (mp_div_2d(mp_arg, o, dst, &rem) != MP_OKAY || + mp_grow(dst, sz) != MP_OKAY) { + mp_clear(&rem); + mp_clear(dst); + Z_END_ARG(arg); + caml_failwith("Z.extract: internal error"); + } + + /* 0-pad */ + for (i = dst->used; i < sz; i++) + dst->dp[i] = 0; + dst->used = sz; + dst->sign = MP_ZPOS; + + /* 2's complement */ + if (mp_isneg(mp_arg)) { + for (i = 0; i < sz; i++) + dst->dp[i] = (~dst->dp[i]) & MP_MASK; + if (mp_iszero(&rem)) { + /* all shifted-out bits are 0 */ + if (mp_incr(dst) != MP_OKAY) { + mp_clear(dst); + mp_clear(&rem); + Z_END_ARG(arg); + caml_failwith("Z.extract: internal error"); + } + /* in case of overflow in incr, ignore the new digit */ + dst->used = sz; + } + } + + /* mask out high bits */ + l %= MP_DIGIT_BIT; + if (l) dst->dp[sz-1] &= MP_MASK >> (MP_DIGIT_BIT - l); + mp_clamp(dst); + mp_clear(&rem); + Z_END_ARG(arg); +} + + +CAMLprim value ml_z_extract(value arg, value off, value len) +{ + CAMLparam1(arg); + CAMLlocal1(r); + r = ml_z_alloc(); + ml_z_extract_internal(Z_MP(r), arg, (uintnat)Long_val(off), (uintnat)Long_val(len)); + r = ml_z_reduce(r); + CAMLreturn(r); +} + +/* version without OCaml allocation */ +CAMLprim value ml_z_extract_small(value arg, value off, value len) +{ + mp_int r; + if (mp_init(&r) != MP_OKAY) + ml_z_raise_out_of_memory(); + + ml_z_extract_internal(&r, arg, (uintnat)Long_val(off), (uintnat)Long_val(len)); + + if (mp_cmp(&r, &z_min_int) < 0 || + mp_cmp(&r, &z_max_int) > 0) { + /* The result should fit in an integer */ + mp_clear(&r); + caml_failwith("Z.extract: internal error"); + } + intnat x = mp_get_i64(&r); + mp_clear(&r); + return Val_long(x); +} + +CAMLprim value ml_z_to_bits(value arg) +{ + CAMLparam1(arg); + CAMLlocal1(r); + Z_DECL(arg); + size_t sz; + Z_ARG(arg); + sz = mp_pack_count(mp_arg, 0, 1); + r = caml_alloc_string(sz); + if (mp_pack((void*)String_val(r), sz, NULL, MP_LSB_FIRST, 1, MP_NATIVE_ENDIAN, 0, mp_arg) != MP_OKAY) { + Z_END_ARG(arg); + caml_failwith("Z.to_bits: internal error"); + } + Z_END_ARG(arg); + CAMLreturn(r); +} + +CAMLprim value ml_z_of_bits(value arg) +{ + CAMLparam1(arg); + CAMLlocal1(r); + r = ml_z_alloc(); + if (mp_unpack(Z_MP(r), caml_string_length(arg), MP_LSB_FIRST, 1, MP_NATIVE_ENDIAN, 0, String_val(arg)) != MP_OKAY) { + mp_clear(Z_MP(r)); + caml_failwith("Z.of_bits: internal error"); + } + r = ml_z_reduce(r); + CAMLreturn(r); +} + + +/*--------------------------------------------------- + TESTS AND COMPARISONS + ---------------------------------------------------*/ + +CAMLprim value ml_z_compare(value arg1, value arg2) +{ + /* Value-equal small integers are equal. + Pointer-equal big integers are equal as well. */ + if (arg1 == arg2) return Val_long(0); + if (Is_long(arg2)) { + if (Is_long(arg1)) { + return arg1 > arg2 ? Val_long(1) : Val_long(-1); + } else { + /* Either arg1 is positive and arg1 > Z_MAX_INT >= arg2 -> result +1 + or arg1 is negative and arg1 < Z_MIN_INT <= arg2 -> result -1 */ + return Z_SIGN(arg1) ? Val_long(-1) : Val_long(1); + } + } + else if (Is_long(arg1)) { + /* Either arg2 is positive and arg2 > Z_MAX_INT >= arg1 -> result -1 + or arg2 is negative and arg2 < Z_MIN_INT <= arg1 -> result +1 */ + return Z_SIGN(arg2) ? Val_long(1) : Val_long(-1); + } + else { + /* slow path */ + mp_ord r; + Z_DECL(arg1); + Z_DECL(arg2); + Z_ARG(arg1); + Z_ARG(arg2); + r = mp_cmp(mp_arg1, mp_arg2); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + /* we assume MP_LT==-1, MP_EQ==0, MP_GT==1 */ + return Val_long(r); + } +} + + +CAMLprim value ml_z_equal(value arg1, value arg2) +{ + mp_ord r; + Z_DECL(arg1); + Z_DECL(arg2); + /* Value-equal small integers are equal. + Pointer-equal big integers are equal as well. */ + if (arg1 == arg2) return Val_true; + /* If both arg1 and arg2 are small integers but failed the equality + test above, they are different. + If one of arg1/arg2 is a small integer and the other is a big integer, + they are different: one is in the range [Z_MIN_INT,Z_MAX_INT] + and the other is outside this range. */ + if (Is_long(arg2) || Is_long(arg1)) return Val_false; + /* slow path */ + Z_ARG(arg1); + Z_ARG(arg2); + r = mp_cmp(mp_arg1, mp_arg2); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + return (r == MP_EQ) ? Val_true : Val_false; +} + +CAMLprim value ml_z_sign(value arg) +{ + if (Is_long(arg)) { + if (arg > Val_long(0)) return Val_long(1); + else if (arg < Val_long(0)) return Val_long(-1); + else return Val_long(0); + } + else { + /* zero is a small integer, treated above */ + if (mp_isneg(Z_MP(arg))) return Val_long(-1); + return Val_long(1); + } +} + +CAMLprim value ml_z_fits_int(value v) +{ + if (Is_long(v)) return Val_true; + if (mp_cmp(Z_MP(v), &z_min_int) >= 0 && + mp_cmp(Z_MP(v), &z_max_int) <= 0) + return Val_true; + return Val_false; +} + +CAMLprim value ml_z_fits_nativeint(value v) +{ + if (Is_long(v)) return Val_true; + if (mp_cmp(Z_MP(v), &z_min_intnat) >= 0 && + mp_cmp(Z_MP(v), &z_max_intnat) <= 0) + return Val_true; + return Val_false; +} + +CAMLprim value ml_z_fits_int32(value v) +{ + if (Is_long(v)) { +#ifdef ARCH_SIXTYFOUR + intnat x = Long_val(v); + if (x >= (intnat)Z_HI_INT32 || x < -(intnat)Z_HI_INT32) + return Val_false; +#endif + return Val_true; + } + if (mp_cmp(Z_MP(v), &z_min_int32) >= 0 && + mp_cmp(Z_MP(v), &z_max_int32) <= 0) + return Val_true; + return Val_false; +} + + +CAMLprim value ml_z_fits_int64(value v) +{ + if (Is_long(v)) return Val_true; + if (mp_cmp(Z_MP(v), &z_min_int64) >= 0 && + mp_cmp(Z_MP(v), &z_max_int64) <= 0) + return Val_true; + return Val_false; +} + +CAMLprim value ml_z_size(value v) +{ + if (Is_long(v)) return Val_long(1); + else return Val_long(Z_MP(v)->used); +} + + +CAMLprim value ml_z_fits_nativeint_unsigned(value v) +{ + if (Is_long(v)) + return Long_val(v) >= 0 ? Val_true : Val_false; + if (!mp_isneg(Z_MP(v)) && + mp_cmp(Z_MP(v), &z_max_intnat_unsigned) <= 0) + return Val_true; + return Val_false; +} + +CAMLprim value ml_z_fits_int32_unsigned(value v) +{ + if (Is_long(v)) { + intnat x = Long_val(v); +#ifdef ARCH_SIXTYFOUR + if (x >= (intnat)Z_HI_UINT32 || x < 0) + return Val_false; +#else + if (x < 0) + return Val_false; +#endif + return Val_true; + } + if (!mp_isneg(Z_MP(v)) && + mp_cmp(Z_MP(v), &z_max_int32_unsigned) <= 0) + return Val_true; + return Val_false; +} + +CAMLprim value ml_z_fits_int64_unsigned(value v) +{ + if (Is_long(v)) + return Long_val(v) >= 0 ? Val_true : Val_false; + if (!mp_isneg(Z_MP(v)) && + mp_cmp(Z_MP(v), &z_max_int64_unsigned) <= 0) + return Val_true; + return Val_false; +} + + + +/*--------------------------------------------------- + ARITHMETIC OPERATORS + ---------------------------------------------------*/ + +CAMLprim value ml_z_neg(value arg) +{ +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg)) { + /* fast path */ + if (arg > Val_long(Z_MIN_INT)) return 2 - arg; + } +#endif + { + /* slow path */ + CAMLparam1(arg); + value r; + Z_DECL(arg); + r = ml_z_alloc(); + Z_ARG(arg); + if (mp_neg(mp_arg, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg); + mp_clear(Z_MP(r)); + caml_failwith("Z.neg: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg); + CAMLreturn(r); + } +} + +CAMLprim value ml_z_abs(value arg) +{ +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg)) { + /* fast path */ + if (arg >= Val_long(0)) return arg; + if (arg > Val_long(Z_MIN_INT)) return 2 - arg; + } +#endif + { + /* slow path */ + CAMLparam1(arg); + value r; + if (Z_ISNEG(arg)) { + Z_DECL(arg); + r = ml_z_alloc(); + Z_ARG(arg); + if (mp_neg(mp_arg, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg); + mp_clear(Z_MP(r)); + caml_failwith("Z.neg: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg); + } + else r = arg; + CAMLreturn(r); + } +} + +CAMLprim value ml_z_add(value arg1, value arg2) +{ +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg1) && Is_long(arg2)) { + /* fast path */ + intnat a1 = Long_val(arg1); + intnat a2 = Long_val(arg2); + intnat v = a1 + a2; + if (Z_FITS_INT(v)) return Val_long(v); + } +#endif + { + /* slow path */ + CAMLparam2(arg1,arg2); + value r; + Z_DECL(arg1); + Z_DECL(arg2); + r = ml_z_alloc(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_add(mp_arg1, mp_arg2, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(r)); + caml_failwith("Z.add: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + CAMLreturn(r); + } +} + +CAMLprim value ml_z_sub(value arg1, value arg2) +{ +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg1) && Is_long(arg2)) { + /* fast path */ + intnat a1 = Long_val(arg1); + intnat a2 = Long_val(arg2); + intnat v = a1 - a2; + if (Z_FITS_INT(v)) return Val_long(v); + } +#endif + { + /* slow path */ + CAMLparam2(arg1,arg2); + value r; + Z_DECL(arg1); + Z_DECL(arg2); + r = ml_z_alloc(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_sub(mp_arg1, mp_arg2, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(r)); + caml_failwith("Z.sub: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + CAMLreturn(r); + } +} + +CAMLprim value ml_z_mul_overflows(value vx, value vy) +{ +#if HAS_BUILTIN(__builtin_mul_overflow) || __GNUC__ >= 5 + intnat z; + return Val_bool(__builtin_mul_overflow(vx - 1, vy >> 1, &z)); +#elif defined(__GNUC__) && defined(__x86_64__) + intnat z; + unsigned char o; + asm("imulq %1, %3; seto %0" + : "=q" (o), "=r" (z) + : "1" (vx - 1), "r" (vy >> 1) + : "cc"); + return Val_int(o); +#elif defined(_MSC_VER) && defined(_M_X64) + intnat hi, lo; + lo = _mul128(vx - 1, vy >> 1, &hi); + return Val_bool(hi != lo >> 63); +#else + /* Portable C code */ + intnat x = Long_val(vx); + intnat y = Long_val(vy); + /* Quick approximate check for small values of x and y. + Also catches the cases x = 0, x = 1, y = 0, y = 1. */ + if (Z_FITS_HINT(x)) { + if (Z_FITS_HINT(y)) return Val_false; + if ((uintnat) x <= 1) return Val_false; + } + if ((uintnat) y <= 1) return Val_false; +#if 1 + /* Give up at this point; we'll go through the general case in ml_z_mul */ + return Val_true; +#else + /* The product x*y is representable as an unboxed integer if + it is in [Z_MIN_INT, Z_MAX_INT]. + x >= 0 y >= 0: x*y >= 0 and x*y <= Z_MAX_INT <-> y <= Z_MAX_INT / x + x < 0 y >= 0: x*y <= 0 and x*y >= Z_MIN_INT <-> x >= Z_MIN_INT / y + x >= 0 y < 0 : x*y <= 0 and x*y >= Z_MIN_INT <-> y >= Z_MIN_INT / x + x < 0 y < 0 : x*y >= 0 and x*y <= Z_MAX_INT <-> x >= Z_MAX_INT / y */ + if (x >= 0) + if (y >= 0) + return Val_bool(y > Z_MAX_INT / x); + else + return Val_bool(y < Z_MIN_INT / x); + else + if (y >= 0) + return Val_bool(x < Z_MIN_INT / y); + else + return Val_bool(x < Z_MAX_INT / y); +#endif +#endif +} + +CAMLprim value ml_z_mul(value arg1, value arg2) +{ +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg1) && Is_long(arg2) && + ml_z_mul_overflows(arg1, arg2) == Val_false)) { + /* fast path */ + return Val_long(Long_val(arg1) * Long_var(arg2)); + } +#endif + { + /* slow path */ + CAMLparam2(arg1,arg2); + value r; + Z_DECL(arg1); + Z_DECL(arg2); + r = ml_z_alloc(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_mul(mp_arg1, mp_arg2, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(r)); + caml_failwith("Z.mul: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + CAMLreturn(r); + } +} + +CAMLprim value ml_z_div_rem(value arg1, value arg2) +{ + if (Z_ISZERO(arg2)) ml_z_raise_divide_by_zero(); + if (Is_long(arg1) && Is_long(arg2)) { + /* fast path */ + intnat a1 = Long_val(arg1); + intnat a2 = Long_val(arg2); + intnat q,r; + q = a1 / a2; + r = a1 % a2; + if (Z_FITS_INT(q) && Z_FITS_INT(r)) { + value p = caml_alloc_small(2, 0); + Field(p,0) = Val_long(q); + Field(p,1) = Val_long(r); + return p; + } + } + /* slow path */ + { + CAMLparam2(arg1, arg2); + CAMLlocal3(q, r, p); + Z_DECL(arg1); + Z_DECL(arg2); + q = ml_z_alloc(); + r = ml_z_alloc(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_div(mp_arg1, mp_arg2, Z_MP(q), Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(q)); + mp_clear(Z_MP(r)); + caml_failwith("Z.div_rem: internal error"); + } + q = ml_z_reduce(q); + r = ml_z_reduce(r); + p = caml_alloc_small(2, 0); + Field(p,0) = q; + Field(p,1) = r; + Z_END_ARG(arg1); + Z_END_ARG(arg2); + CAMLreturn(p); + } +} + +CAMLprim value ml_z_div(value arg1, value arg2) +{ + if (Z_ISZERO(arg2)) ml_z_raise_divide_by_zero(); + if (Is_long(arg1) && Is_long(arg2)) { + /* fast path */ + intnat a1 = Long_val(arg1); + intnat a2 = Long_val(arg2); + intnat q = a1 / a2; + if (Z_FITS_INT(q)) return Val_long(q); + } + /* slow path */ + { + CAMLparam2(arg1, arg2); + CAMLlocal1(q); + Z_DECL(arg1); + Z_DECL(arg2); + q = ml_z_alloc(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_div(mp_arg1, mp_arg2, Z_MP(q), NULL) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(q)); + caml_failwith("Z.div: internal error"); + } + q = ml_z_reduce(q); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + CAMLreturn(q); + } +} + + +CAMLprim value ml_z_rem(value arg1, value arg2) +{ + if (Z_ISZERO(arg2)) ml_z_raise_divide_by_zero(); + if (Is_long(arg1) && Is_long(arg2)) { + /* fast path */ + intnat a1 = Long_val(arg1); + intnat a2 = Long_val(arg2); + intnat r = a1 % a2; + if (Z_FITS_INT(r)) return Val_long(r); + } + /* slow path */ + { + CAMLparam2(arg1, arg2); + CAMLlocal1(r); + Z_DECL(arg1); + Z_DECL(arg2); + r = ml_z_alloc(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_div(mp_arg1, mp_arg2, NULL, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(r)); + caml_failwith("Z.rem: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + CAMLreturn(r); + } +} + + +/* helper function for division with rounding towards +oo / -oo */ +static value ml_z_rdiv(value arg1, value arg2, intnat dir) +{ + CAMLparam2(arg1, arg2); + CAMLlocal2(q, r); + Z_DECL(arg1); + Z_DECL(arg2); + q = ml_z_alloc(); + r = ml_z_alloc(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_div(mp_arg1, mp_arg2, Z_MP(q), Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(q)); + mp_clear(Z_MP(r)); + caml_failwith("Z.[cf]div: internal error"); + } + + if (!mp_iszero(Z_MP(r))) { + if (dir > 0 && mp_isneg(mp_arg1) == mp_isneg(mp_arg2)) { + if (mp_incr(Z_MP(q)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(q)); + mp_clear(Z_MP(r)); + caml_failwith("Z.[cf]div: internal error"); + } + } + if (dir < 0 && mp_isneg(mp_arg1) != mp_isneg(mp_arg2)) + if (mp_decr(Z_MP(q)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(q)); + mp_clear(Z_MP(r)); + caml_failwith("Z.[cf]div: internal error"); + } + } + q = ml_z_reduce(q); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(r)); + CAMLreturn(q); +} + +CAMLprim value ml_z_cdiv(value arg1, value arg2) +{ + if (Z_ISZERO(arg2)) ml_z_raise_divide_by_zero(); + if (Is_long(arg1) && Is_long(arg2)) { + /* fast path */ + intnat a1 = Long_val(arg1); + intnat a2 = Long_val(arg2); + intnat q; + /* adjust to round towards +oo */ + if (a1 > 0 && a2 > 0) a1 += a2-1; + else if (a1 < 0 && a2 < 0) a1 += a2+1; + q = a1 / a2; + if (Z_FITS_INT(q)) return Val_long(q); + } + /* slow path */ + return ml_z_rdiv(arg1, arg2, 1); +} + +CAMLprim value ml_z_fdiv(value arg1, value arg2) +{ + if (Z_ISZERO(arg2)) ml_z_raise_divide_by_zero(); + if (Is_long(arg1) && Is_long(arg2)) { + /* fast path */ + intnat a1 = Long_val(arg1); + intnat a2 = Long_val(arg2); + intnat q; + /* adjust to round towards -oo */ + if (a1 < 0 && a2 > 0) a1 -= a2-1; + else if (a1 > 0 && a2 < 0) a1 -= a2+1; + q = a1 / a2; + if (Z_FITS_INT(q)) return Val_long(q); + } + /* slow path */ + return ml_z_rdiv(arg1, arg2, -1); +} + + +CAMLprim value ml_z_succ(value arg) +{ +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg)) { + /* fast path */ + if (arg < Val_long(Z_MAX_INT)) return arg + 2; + } +#endif + { + /* slow path */ + CAMLparam1(arg); + value r; + Z_DECL(arg); + r = ml_z_alloc(); + Z_ARG(arg); + if (mp_add_d(mp_arg, 1, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg); + mp_clear(Z_MP(r)); + caml_failwith("Z.succ: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg); + CAMLreturn(r); + } +} + + +CAMLprim value ml_z_pred(value arg) +{ +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg)) { + /* fast path */ + if (arg > Val_long(Z_MIN_INT)) return arg - 2; + } +#endif + { + /* slow path */ + CAMLparam1(arg); + value r; + Z_DECL(arg); + r = ml_z_alloc(); + Z_ARG(arg); + if (mp_sub_d(mp_arg, 1, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg); + mp_clear(Z_MP(r)); + caml_failwith("Z.pred: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg); + CAMLreturn(r); + } +} + +CAMLprim value ml_z_sqrt(value arg) +{ + CAMLparam1(arg); + Z_DECL(arg); + value r; + Z_ARG(arg); + if (mp_isneg(mp_arg)) { + Z_END_ARG(arg); + caml_invalid_argument("Z.sqrt: square root of a negative number"); + } + r = ml_z_alloc(); + Z_REFRESH(arg); + if (mp_sqrt(mp_arg, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg); + mp_clear(Z_MP(r)); + caml_failwith("Z.sqrt: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg); + CAMLreturn(r); +} + +CAMLprim value ml_z_sqrt_rem(value arg) +{ + CAMLparam1(arg); + CAMLlocal3(r1,r2,r); + Z_DECL(arg); + Z_ARG(arg); + if (mp_isneg(mp_arg)) { + Z_END_ARG(arg); + caml_invalid_argument("Z.sqrt_rem: square root of a negative number"); + } + r1 = ml_z_alloc(); + r2 = ml_z_alloc(); + Z_REFRESH(arg); + if (mp_sqrt(mp_arg, Z_MP(r1)) != MP_OKAY || + mp_mul(Z_MP(r1),Z_MP(r1),Z_MP(r2)) != MP_OKAY || + mp_sub(mp_arg,Z_MP(r2),Z_MP(r2)) != MP_OKAY) { + mp_clear(Z_MP(r1)); + mp_clear(Z_MP(r2)); + Z_END_ARG(arg); + caml_failwith("Z.sqrt_rem: internal error"); + } + r1 = ml_z_reduce(r1); + r2 = ml_z_reduce(r2); + r = caml_alloc_small(2, 0); + Field(r,0) = r1; + Field(r,1) = r2; + Z_END_ARG(arg); + CAMLreturn(r); +} + +CAMLprim value ml_z_gcd(value arg1, value arg2) +{ + if (Is_long(arg1) && Is_long(arg2)) { + /* fast path */ + intnat a1 = Long_val(arg1); + intnat a2 = Long_val(arg2); + if (a1 < 0) a1 = -a1; + if (a2 < 0) a2 = -a2; + if (a1 < a2) { intnat t = a1; a1 = a2; a2 = t; } + while (a2) { + intnat r = a1 % a2; + a1 = a2; a2 = r; + } + /* If arg1 = arg2 = min_int, the result a1 is -min_int, not representable +  as a tagged integer; fall through the slow case, then. */ + if (a1 <= Z_MAX_INT) return Val_long(a1); + } + { + /* slow path */ + CAMLparam2(arg1, arg2); + CAMLlocal1(r); + Z_DECL(arg1); + Z_DECL(arg2); + r = ml_z_alloc(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_gcd(mp_arg1, mp_arg2, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(r)); + caml_failwith("Z.gcd: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + CAMLreturn(r); + } +} + +/* only computes one cofactor */ +CAMLprim value ml_z_gcdext_intern(value arg1, value arg2) +{ + CAMLparam2(arg1, arg2); + CAMLlocal3(r, s, p); + Z_DECL(arg1); + Z_DECL(arg2); + if (Z_ISZERO(arg1)) ml_z_raise_divide_by_zero(); + if (Z_ISZERO(arg2)) ml_z_raise_divide_by_zero(); + r = ml_z_alloc(); + s = ml_z_alloc(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_exteuclid(mp_arg1, mp_arg2, Z_MP(s), NULL, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(r)); + mp_clear(Z_MP(s)); + caml_failwith("Z.gcdext: internal error"); + } + r = ml_z_reduce(r); + s = ml_z_reduce(s); + p = caml_alloc_small(3, 0); + Field(p,0) = r; + Field(p,1) = s; + Field(p,2) = Val_true; + Z_END_ARG(arg1); + Z_END_ARG(arg2); + CAMLreturn(p); +} + + +/*--------------------------------------------------- + BITWISE OPERATORS + ---------------------------------------------------*/ + +CAMLprim value ml_z_logand(value arg1, value arg2) +{ +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg1) && Is_long(arg2)) { + /* fast path */ + return arg1 & arg2; + } +#endif + { + /* slow path */ + CAMLparam2(arg1,arg2); + value r; + Z_DECL(arg1); + Z_DECL(arg2); + r = ml_z_alloc(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_and(mp_arg1, mp_arg2, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(r)); + caml_failwith("Z.logand: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + CAMLreturn(r); + } +} + +CAMLprim value ml_z_logor(value arg1, value arg2) +{ +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg1) && Is_long(arg2)) { + /* fast path */ + return arg1 | arg2; + } +#endif + { + /* slow path */ + CAMLparam2(arg1,arg2); + value r; + Z_DECL(arg1); + Z_DECL(arg2); + r = ml_z_alloc(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_or(mp_arg1, mp_arg2, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(r)); + caml_failwith("Z.logor: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + CAMLreturn(r); + } +} + +CAMLprim value ml_z_logxor(value arg1, value arg2) +{ +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg1) && Is_long(arg2)) { + /* fast path */ + return (arg1 ^ arg2) | 1; + } +#endif + { + /* slow path */ + CAMLparam2(arg1,arg2); + value r; + Z_DECL(arg1); + Z_DECL(arg2); + r = ml_z_alloc(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_xor(mp_arg1, mp_arg2, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(Z_MP(r)); + caml_failwith("Z.logxor: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + CAMLreturn(r); + } +} + +CAMLprim value ml_z_lognot(value arg) +{ +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg)) { + /* fast path */ + return (~arg) | 1; + } +#endif + { + /* slow path */ + CAMLparam1(arg); + value r; + Z_DECL(arg); + r = ml_z_alloc(); + Z_ARG(arg); + if (mp_complement(mp_arg, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg); + mp_clear(Z_MP(r)); + caml_failwith("Z.lognot: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg); + CAMLreturn(r); + } +} + +CAMLprim value ml_z_shift_left(value arg, value count) +{ + intnat c = Long_val(count); + if (c < 0) + caml_invalid_argument("Z.shift_left: count argument must be positive"); + if (c > INT_MAX) + caml_invalid_argument("Z.shift_left: count argument too large"); + if (!c) return arg; +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg) && c < Z_INTNAT_BITS) { + /* fast path */ + value a = arg - 1; + value r = arg << c; + if (a == (r >> c)) return r | 1; + } +#endif + { + /* slow path */ + CAMLparam1(arg); + Z_DECL(arg); + value r; + r = ml_z_alloc(); + Z_ARG(arg); + if (mp_mul_2d(mp_arg, c, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg); + mp_clear(Z_MP(r)); + caml_failwith("Z.shift_left: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg); + CAMLreturn(r); + } +} + +CAMLprim value ml_z_shift_right(value arg, value count) +{ + intnat c = Long_val(count); + if (c < 0) + caml_invalid_argument("Z.shift_right: count argument must be positive"); + if (c > INT_MAX) + caml_invalid_argument("Z.shift_left: count argument too large"); + if (!c) return arg; +#if !Z_FAST_PATH_IN_OCAML + if (Is_long(arg)) { + /* fast path */ + if (c >= Z_INTNAT_BITS) { + if (arg < 0) return Val_long(-1); + else return Val_long(0); + } + return (arg >> c) | 1; + } +#endif + { + /* slow path */ + CAMLparam1(arg); + Z_DECL(arg); + value r; + r = ml_z_alloc(); + Z_ARG(arg); + if (mp_signed_rsh(mp_arg, c, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(arg); + mp_clear(Z_MP(r)); + caml_failwith("Z.shift_right: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg); + CAMLreturn(r); + } +} + +CAMLprim value ml_z_shift_right_trunc(value arg, value count) +{ + intnat c = Long_val(count); + if (c < 0) + caml_invalid_argument("Z.shift_right_trunc: count argument must be positive"); + if (c > INT_MAX) + caml_invalid_argument("Z.shift_left: count argument too large"); + if (!c) return arg; + if (Is_long(arg)) { + /* fast path */ + if (c >= Z_INTNAT_BITS) return Val_long(0); + if (arg >= 1) return (arg >> c) | 1; + else return Val_long(- ((- Long_val(arg)) >> c)); + } + { + /* slow path */ + CAMLparam1(arg); + Z_DECL(arg); + value r; + r = ml_z_alloc(); + Z_ARG(arg); + if (mp_div_2d(mp_arg, c, Z_MP(r), NULL) != MP_OKAY) { + Z_END_ARG(arg); + mp_clear(Z_MP(r)); + caml_failwith("Z.shift_right_trunc: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(arg); + CAMLreturn(r); + } +} + + +/* Helper function for numbits: number of leading 0 bits in x */ + +#ifdef ARCH_SIXTYFOUR +#define BUILTIN_CLZ __builtin_clzll +#else +#define BUILTIN_CLZ __builtin_clzl +#endif + +/* Use GCC or Clang built-in if available. The argument must be != 0. */ +#if defined(__clang__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define ml_z_clz BUILTIN_CLZ +#else +/* Portable C implementation - Hacker's Delight fig 5.12 */ +int ml_z_clz(uintnat x) +{ + int n; + uintnat y; +#ifdef ARCH_SIXTYFOUR + n = 64; + y = x >> 32; if (y != 0) { n = n - 32; x = y; } +#else + n = 32; +#endif + y = x >> 16; if (y != 0) { n = n - 16; x = y; } + y = x >> 8; if (y != 0) { n = n - 8; x = y; } + y = x >> 4; if (y != 0) { n = n - 4; x = y; } + y = x >> 2; if (y != 0) { n = n - 2; x = y; } + y = x >> 1; if (y != 0) return n - 2; + return n - x; +} +#endif + +CAMLprim value ml_z_numbits(value arg) +{ + if (Is_long(arg)) { + intnat r = Long_val(arg); + if (r == 0) { + return Val_int(0); + } else { + int n = ml_z_clz(r > 0 ? r : -r); + return Val_long(sizeof(intnat) * 8 - n); + } + } + else { + if (mp_iszero(Z_MP(arg))) return Val_long(0); + return Val_long(mp_count_bits(Z_MP(arg))); + } +} + + +/* Helper function for trailing_zeros: number of trailing 0 bits in x */ + +#ifdef ARCH_SIXTYFOUR +#define BUILTIN_CTZ __builtin_ctzll +#else +#define BUILTIN_CTZ __builtin_ctzl +#endif + +/* Use GCC or Clang built-in if available. The argument must be != 0. */ +#if defined(__clang__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define ml_z_ctz BUILTIN_CTZ +#else +/* Portable C implementation - Hacker's Delight fig 5.21 */ +int ml_z_ctz(uintnat x) +{ + int n; + uintnat y; + CAMLassert (x != 0); +#ifdef ARCH_SIXTYFOUR + n = 63; + y = x << 32; if (y != 0) { n = n - 32; x = y; } +#else + n = 31; +#endif + y = x << 16; if (y != 0) { n = n - 16; x = y; } + y = x << 8; if (y != 0) { n = n - 8; x = y; } + y = x << 4; if (y != 0) { n = n - 4; x = y; } + y = x << 2; if (y != 0) { n = n - 2; x = y; } + y = x << 1; if (y != 0) { n = n - 1; } + return n; +} +#endif + +CAMLprim value ml_z_trailing_zeros(value arg) +{ + if (Is_long(arg)) { + /* fast path */ + intnat r = Long_val(arg); + if (r == 0) { + return Val_long (Max_long); + } else { + /* No need to take absolute value of r, as ctz(-x) = ctz(x) */ + return Val_long (ml_z_ctz(r)); + } + } + else { + if (mp_iszero(Z_MP(arg))) return Val_long(Max_long); + return Val_long(mp_cnt_lsb(Z_MP(arg))); + } +} + + +/* helper function for popcount & hamdist: number of bits at 1 in x */ +/* maybe we should use the mpn_ function even for small arguments, in case + the CPU has a fast popcount opcode? + */ +uintnat ml_z_count(uintnat x) +{ +#ifdef ARCH_SIXTYFOUR + x = (x & 0x5555555555555555UL) + ((x >> 1) & 0x5555555555555555UL); + x = (x & 0x3333333333333333UL) + ((x >> 2) & 0x3333333333333333UL); + x = (x & 0x0f0f0f0f0f0f0f0fUL) + ((x >> 4) & 0x0f0f0f0f0f0f0f0fUL); + x = (x & 0x00ff00ff00ff00ffUL) + ((x >> 8) & 0x00ff00ff00ff00ffUL); + x = (x & 0x0000ffff0000ffffUL) + ((x >> 16) & 0x0000ffff0000ffffUL); + x = (x & 0x00000000ffffffffUL) + ((x >> 32) & 0x00000000ffffffffUL); +#else + x = (x & 0x55555555UL) + ((x >> 1) & 0x55555555UL); + x = (x & 0x33333333UL) + ((x >> 2) & 0x33333333UL); + x = (x & 0x0f0f0f0fUL) + ((x >> 4) & 0x0f0f0f0fUL); + x = (x & 0x00ff00ffUL) + ((x >> 8) & 0x00ff00ffUL); + x = (x & 0x0000ffffUL) + ((x >> 16) & 0x0000ffffUL); +#endif + return x; +} + +CAMLprim value ml_z_popcount(value arg) +{ + if (Is_long(arg)) { + /* fast path */ + intnat r = Long_val(arg); + if (r < 0) ml_z_raise_overflow(); + return Val_long(ml_z_count(r)); + } + else { + intnat r; + int i; + mp_digit* p; + if (mp_isneg(Z_MP(arg))) ml_z_raise_overflow(); + for (i=0, r=0, p=Z_MP(arg)->dp; i < Z_MP(arg)->used; i++, p++) + r += ml_z_count(*p); + if (r < 0 || !Z_FITS_INT(r)) ml_z_raise_overflow(); + return Val_long(r); + } +} + +CAMLprim value ml_z_hamdist(value arg1, value arg2) +{ + if (Z_ISNEG(arg1) != Z_ISNEG(arg2)) + ml_z_raise_overflow(); + /* XXX TODO: case where arg1 & arg2 are both negative */ + if (Z_ISNEG(arg1) || Z_ISNEG(arg2)) + caml_invalid_argument("Z.hamdist: negative arguments"); + if (Is_long(arg1) && Is_long(arg2)) { + return Val_long(ml_z_count(Long_val(arg1) ^ Long_val(arg2))); + } + else { + Z_DECL(arg1); + Z_DECL(arg2); + intnat r = 0; + mp_digit *a1, *a2; + size_t len1, len2; + Z_ARG(arg1); + Z_ARG(arg2); + /* a1 is the shortest one */ + if (mp_arg1->used <= mp_arg2->used) { + a1 = mp_arg1->dp; len1 = mp_arg1->used; + a2 = mp_arg2->dp; len2 = mp_arg2->used; + } + else { + a1 = mp_arg2->dp; len1 = mp_arg2->used; + a2 = mp_arg1->dp; len2 = mp_arg1->used; + } + for (size_t i = 0; i < len1; i++) + r += ml_z_count(a1[i] ^ a2[i]); + for (size_t i = len1; i < len2; i++) + r += ml_z_count(a2[i]); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + if (r < 0 || !Z_FITS_INT(r)) ml_z_raise_overflow(); + return Val_long(r); + } +} + +CAMLprim value ml_z_testbit(value arg, value index) +{ + intnat b_idx = Long_val(index); /* Caml code checked index >= 0 */ + intnat l_idx = b_idx / MP_DIGIT_BIT; + mp_digit d; + if (Is_long(arg)) { + if (b_idx >= Z_INTNAT_BITS) b_idx = Z_INTNAT_BITS - 1; + return Val_int((Long_val(arg) >> b_idx) & 1); + } + if (l_idx >= Z_MP(arg)->used) return Val_bool(mp_isneg(Z_MP(arg))); + d = Z_LIMB(arg)[l_idx]; + if (mp_isneg(Z_MP(arg))) { + for (intnat i = 0; i < l_idx; i++) { + if (Z_LIMB(arg)[i] != 0) { d = ~d; goto extract; } + } + d = -d; + } + extract: + return Val_int((d >> (b_idx % MP_DIGIT_BIT)) & 1); +} + +CAMLprim value ml_z_divexact(value arg1, value arg2) +{ + return ml_z_div(arg1,arg2); +} + +CAMLprim value ml_z_powm(value base, value exp, value mod) +{ + CAMLparam3(base,exp,mod); + CAMLlocal1(r); + Z_DECL(base); + Z_DECL(exp); + Z_DECL(mod); + + r = ml_z_alloc(); + Z_ARG(base); + Z_ARG(exp); + Z_ARG(mod); + if (mp_exptmod(mp_base, mp_exp, mp_mod, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(base); + Z_END_ARG(exp); + Z_END_ARG(mod); + mp_clear(Z_MP(r)); + caml_failwith("Z.powm: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(base); + Z_END_ARG(exp); + Z_END_ARG(mod); + CAMLreturn(r); +} + +CAMLprim value ml_z_powm_sec(value base, value exp, value mod) +{ + return ml_z_powm(base, exp, mod); +} + +CAMLprim value ml_z_pow(value base, value exp) +{ + CAMLparam2(base,exp); + CAMLlocal1(r); + Z_DECL(base); + intnat e = Long_val(exp); + if (e < 0) + caml_invalid_argument("Z.pow: exponent must be nonnegative"); +#ifdef ARCH_SIXTYFOUR + if (e > 0x7fffffff) + caml_invalid_argument("Z.pow: exponent too large"); +#endif + r = ml_z_alloc(); + Z_ARG(base); + if (mp_expt_u32(mp_base, e, Z_MP(r)) != MP_OKAY) { + Z_END_ARG(base); + mp_clear(Z_MP(r)); + caml_failwith("Z.pow: internal error"); + } + r = ml_z_reduce(r); + Z_END_ARG(base); + CAMLreturn(r); +} + +CAMLprim value ml_z_root(UNUSED_PARAM value a, UNUSED_PARAM value b) +{ + caml_failwith("Z.root: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_rootrem(UNUSED_PARAM value a, UNUSED_PARAM value b) +{ + caml_failwith("Z.rootrem: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_perfect_power(UNUSED_PARAM value a) +{ + caml_failwith("Z.perfect_power: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_perfect_square(UNUSED_PARAM value a) +{ + caml_failwith("Z.perfect_square: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_probab_prime(UNUSED_PARAM value a, UNUSED_PARAM int b) +{ + caml_failwith("Z.probab_prime: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_nextprime(UNUSED_PARAM value a) +{ + caml_failwith("Z.nextprime: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_invert(UNUSED_PARAM value base, UNUSED_PARAM value mod) +{ + caml_failwith("Z.invert: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_divisible(value arg1, value arg2) +{ + if (Z_ISZERO(arg2)) ml_z_raise_divide_by_zero(); + if (Is_long(arg1) && Is_long(arg2)) { + /* fast path */ + intnat a1 = Long_val(arg1); + intnat a2 = Long_val(arg2); + return Val_bool(a1 % a2 == 0); + } + /* slow path */ + { + Z_DECL(arg1); + Z_DECL(arg2); + mp_int r; + int res; + if (mp_init(&r) != MP_OKAY) + ml_z_raise_out_of_memory(); + Z_ARG(arg1); + Z_ARG(arg2); + if (mp_div(mp_arg1, mp_arg2, NULL, &r) != MP_OKAY) { + Z_END_ARG(arg1); + Z_END_ARG(arg2); + mp_clear(&r); + caml_failwith("Z.divisible: internal error"); + } + res = mp_iszero(&r); + mp_clear(&r); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + return Val_bool(res); + } +} + +CAMLprim value ml_z_congruent(UNUSED_PARAM value a, UNUSED_PARAM value b, UNUSED_PARAM value c) +{ + caml_failwith("Z.congruent: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_jacobi(UNUSED_PARAM value a, UNUSED_PARAM value b) +{ + caml_failwith("Z.jacobi: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_legendre(UNUSED_PARAM value a, UNUSED_PARAM value b) +{ + caml_failwith("Z.legendre: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_kronecker(UNUSED_PARAM value a, UNUSED_PARAM value b) +{ + caml_failwith("Z.kronecker: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_remove(UNUSED_PARAM value a, UNUSED_PARAM value b) +{ + caml_failwith("Z.remove: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_fac(UNUSED_PARAM value a) +{ + caml_failwith("Z.fac: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_fac2(UNUSED_PARAM value a) +{ + caml_failwith("Z.fac2: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_facM(UNUSED_PARAM value a, UNUSED_PARAM value b) +{ + caml_failwith("Z.facM: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_primorial(UNUSED_PARAM value a) +{ + caml_failwith("Z.primorial: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_bin(UNUSED_PARAM value a, UNUSED_PARAM value b) +{ + caml_failwith("Z.bin: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_fib(UNUSED_PARAM value a) +{ + caml_failwith("Z.fib: not implemented in LibTomMath backend"); +} + +CAMLprim value ml_z_lucnum(UNUSED_PARAM value a) +{ + caml_failwith("Z.lucnum: not implemented in LibTomMath backend"); +} + + +/*--------------------------------------------------- + CUSTOMS BLOCKS + ---------------------------------------------------*/ + +static void ml_z_custom_finalize(value v) { + mp_clear(Z_MP(v)); +} + +/* With OCaml < 3.12.1, comparing a block an int with OCaml's + polymorphic compare will give erroneous results (int always + strictly smaller than block). OCaml 3.12.1 and above + give the correct result. +*/ +int ml_z_custom_compare(value arg1, value arg2) +{ + /* Value-equal small integers are equal. + Pointer-equal big integers are equal as well. */ + if (arg1 == arg2) return 0; + if (Is_long(arg2)) { + if (Is_long(arg1)) { + return arg1 > arg2 ? 1 : -1; + } else { + /* Either arg1 is positive and arg1 > Z_MAX_INT >= arg2 -> result +1 + or arg1 is negative and arg1 < Z_MIN_INT <= arg2 -> result -1 */ + return Z_SIGN(arg1) ? -1 : 1; + } + } + else if (Is_long(arg1)) { + /* Either arg2 is positive and arg2 > Z_MAX_INT >= arg1 -> result -1 + or arg2 is negative and arg2 < Z_MIN_INT <= arg1 -> result +1 */ + return Z_SIGN(arg2) ? 1 : -1; + } + else { + /* slow path */ + int r; + Z_DECL(arg1); + Z_DECL(arg2); + Z_ARG(arg1); + Z_ARG(arg2); + r = mp_cmp(mp_arg1, mp_arg2); + Z_END_ARG(arg1); + Z_END_ARG(arg2); + /* we assume MP_LT==-1, MP_EQ==0, MP_GT==1 */ + return r; + } +} + + +#if 1 /* Select the ml_z_custom_hash implementation */ + +/* + This version of hash does not give the same result as the GMP one. + Moreover, the hash value depends on MP_DIGIT_BIT. + However, it is simple and fast, and so, enabled by default. +*/ + +static intnat ml_z_custom_hash(value v) +{ + if (Is_long(v)) { +#ifdef ARCH_SIXTYFOUR + return caml_hash_mix_uint32((uint32_t)v, (uint32_t)(v >> 32)); +#else + return v; +#endif + } + else { + uint32_t r = 0; + int i; + mp_digit* p; + if (mp_isneg(Z_MP(v))) r = 1; + for (i=0, p=Z_MP(v)->dp; i < Z_MP(v)->used; i++, p++) { +#ifdef MP_64BIT + r = caml_hash_mix_uint32(r, (uint32_t)*p); + r = caml_hash_mix_uint32(r, (uint32_t)((*p) >> 32)); +#else + r = caml_hash_mix_uint32(r, (uint32_t)*p); +#endif + } + return r; + } +} + +#else + +/* + This version of hash gives the same result as the GMP one and + does not depend on the value of MP_DIGIT_BITS. + However, it is complex, slower and not much tested. + It is currently disabled by #if +*/ + +static intnat ml_z_custom_hash(value v) +{ + if (Is_long(v)) { + intnat n = Long_val(v); + intnat a = n >= 0 ? n : -n; + uint32_t h; +#ifdef ARCH_SIXTYFOUR + h = caml_hash_mix_uint32((uint32_t)a, (uint32_t)(a >> 32)); +#else + h = a; +#endif + if (n < 0) h++; + return h; + } + else { + uint32_t acc = 0; + mp_digit* p; + uint32_t word = 0; // 32-bit word in construction + int bits = 0; // actual bits in word + size_t nb = 0; // nb words + size_t i; + + for (p = Z_MP(v)->dp, i = Z_MP(v)->used; i > 0; p++, i--) { + // eat a new digit + mp_digit d = *p; + word |= (uint32_t)d << bits; + bits += MP_DIGIT_BIT; + if (bits >= 32) { + // word complete + nb++; + acc = caml_hash_mix_uint32(acc, word); + // remaining bits in d + bits -= 32; + d >>= MP_DIGIT_BIT - bits; + while (bits >= 32 && (d || i > 1)) { + // additional words + nb++; + acc = caml_hash_mix_uint32(acc, d); + bits -= 32; + d >>= 32; + } + word = d; + } + } + if (bits > 0 && word) { + // last piece of digit + nb++; + acc = caml_hash_mix_uint32(acc, word); + } + /* ensure an even number of words (compatibility with 64-bit GMP) */ + if (nb % 2 != 0) { + acc = caml_hash_mix_uint32(acc, 0); + } + if (mp_isneg(Z_MP(v))) acc++; + return acc; + } +} + +#endif + +CAMLprim value ml_z_hash(value v) +{ + return Val_long(ml_z_custom_hash(v)); +} + +static void ml_z_custom_serialize(value v, + uintnat * wsize_32, + uintnat * wsize_64) +{ + size_t i, nb; + uint8_t* buf; + Z_DECL(v); + Z_ARG(v); + nb = mp_sbin_size(mp_v); + if (nb != (uint32_t)nb) { + caml_failwith("Z.serialize: number is too large"); + } + buf = (uint8_t*)malloc(nb); + if (!buf) caml_raise_out_of_memory(); + if (mp_to_sbin(mp_v, buf, nb, NULL) != MP_OKAY) { + free(buf); + Z_END_ARG(v); + ml_z_raise_out_of_memory(); + } + caml_serialize_int_4(nb); + for (i = 0; i < nb; i++) + caml_serialize_int_1(buf[i]); + /* struct { int; int; enum; ptr; } */ + *wsize_32 = 16; + *wsize_64 = 24; + free(buf); + Z_END_ARG(v); +} + +static uintnat ml_z_custom_deserialize(void * dst) +{ + uint32_t i, nb; + uint8_t* buf; + if (mp_init(dst) != MP_OKAY) + ml_z_raise_out_of_memory(); + nb = caml_deserialize_uint_4(); + buf = (uint8_t*)malloc(nb); + if (!buf) caml_raise_out_of_memory(); + for (i = 0; i < nb; i++) + buf[i] = caml_deserialize_uint_1(); + if (mp_from_sbin((mp_int*)dst, buf, nb) != MP_OKAY) { + free(buf); + ml_z_raise_out_of_memory(); + } + free(buf); + return sizeof(mp_int); +} + +struct custom_operations ml_z_custom_ops = { + /* Identifiers starting with _ are normally reserved for the OCaml runtime + system, but we got authorization form Gallium to use "_z". + It is very compact and stays in the spirit of identifiers used for + int32 & co ("_i" & co.). + */ + "_z", + ml_z_custom_finalize, + ml_z_custom_compare, + ml_z_custom_hash, + ml_z_custom_serialize, + ml_z_custom_deserialize, + ml_z_custom_compare, +#ifndef Z_OCAML_LEGACY_CUSTOM_OPERATIONS + custom_fixed_length_default +#endif +}; + + +/*--------------------------------------------------- + INIT / EXIT + ---------------------------------------------------*/ +CAMLprim value ml_z_init() +{ + mp_err err = MP_OKAY; + /* checks */ + if (MP_LT!=-1 || MP_EQ!=0 || MP_GT!=1) + caml_failwith("Z.init: invalid values for MP_LT, MP_EQ, MP_GT"); + /* useful constants */ + err |= mp_init_i32(&z_max_int32, 0x7fffffff); + err |= mp_init_i32(&z_min_int32, -0x80000000); + err |= mp_init_i64(&z_max_int64, 0x7fffffffffffffffLL); + err |= mp_init_i64(&z_min_int64, -0x7fffffffffffffffLL - 1); + err |= mp_init_u32(&z_max_int32_unsigned, 0xffffffffU); + err |= mp_init_u64(&z_max_int64_unsigned, 0xffffffffffffffffLLU); +#ifdef ARCH_SIXTYFOUR + err |= mp_init_i64(&z_max_int, 0x3fffffffffffffffLL); + err |= mp_init_i64(&z_min_int, -0x4000000000000000LL); + err |= mp_init_i64(&z_max_intnat, 0x7fffffffffffffffLL); + err |= mp_init_i64(&z_min_intnat, -0x7fffffffffffffffLL - 1); + err |= mp_init_u64(&z_max_intnat_unsigned, 0xffffffffffffffffLLU); +#else + err |= mp_init_i32(&z_max_int, 0x3fffffff); + err |= mp_init_i32(&z_min_int, -0x40000000); + err |= mp_init_i32(&z_max_intnat, 0x7fffffff); + err |= mp_init_i32(&z_min_intnat, -0x80000000); + err |= mp_init_u32(&z_max_intnat_unsigned, 0xffffffffU); +#endif + if (err != MP_OKAY) { + caml_failwith("Z.init: failed to create constants"); + } + /* install functions */ + caml_register_custom_operations(&ml_z_custom_ops); + return Val_unit; +} + +CAMLprim value ml_z_digit_bits() +{ + return Val_long(MP_DIGIT_BIT); +} diff --git a/configure b/configure index 76b997f..13b6c77 100755 --- a/configure +++ b/configure @@ -54,6 +54,7 @@ where options include: -ocamllibdir dir ocaml library directory -gmp use GMP library (default if found) -mpir use MPIR library instead of GMP + -tommath use TomMath library instead of GMP -perf enable performance statistics -prefixnonocaml add for non ocaml tool, e.g. -prefixnonocaml x86_64-w64-mingw32- @@ -88,6 +89,8 @@ while : ; do gmp='gmp';; -mpir|--mpir) gmp='mpir';; + -tommath|--tommath) + gmp='tommath';; -perf|--perf) perf='yes';; -prefixnonocaml|--prefixnonocaml) @@ -275,11 +278,14 @@ echo "OCaml's word size is $wordsize" rm -f tmp.ml -# check GMP, MPIR +# check GMP, MPIR, TomMath + +csrc="caml_z.c" if test "$gmp" = 'gmp' || test "$gmp" = 'auto'; then if pkg-config gmp 2>/dev/null; then echo 'package gmp: found' + backend='GMP' gmp='OK' cclib="$cclib $(pkg-config --libs gmp)" ccinc="$ccinc $(pkg-config --cflags gmp)" @@ -289,6 +295,7 @@ if test "$gmp" = 'gmp' || test "$gmp" = 'auto'; then if test $? -eq 1; then checklib gmp if test $? -eq 1; then + backend='GMP' gmp='OK' cclib="$cclib -lgmp" ccdef="-DHAS_GMP $ccdef" @@ -301,13 +308,27 @@ if test "$gmp" = 'mpir' || test "$gmp" = 'auto'; then if test $? -eq 1; then checklib mpir if test $? -eq 1; then + backend='MPIR' gmp='OK' cclib="$cclib -lmpir" ccdef="-DHAS_MPIR $ccdef" fi fi fi -if test "$gmp" != 'OK'; then echo "cannot find GMP nor MPIR"; exit 2; fi +if test "$gmp" = 'tommath' -o "$gmp" = 'auto'; then + checkinc tommath.h + if test $? -eq 1; then + checklib tommath + if test $? -eq 1; then + backend='LibTomMath' + gmp='OK' + cclib="$cclib -ltommath" + ccdef="-DHAS_TOMMATH $ccdef" + csrc="caml_z_tommath.c" + fi + fi +fi +if test "$gmp" != 'OK'; then echo "cannot find GMP nor MPIR nor TomMath"; exit 2; fi # OCaml version @@ -338,6 +359,14 @@ case "$ocamlver" in ;; esac + +# zarith version + +version=`grep "version" META | head -1` +echo "let $version" > zarith_version.ml +echo "let backend = \"$backend\"" >> zarith_version.ml + + # dump Makefile cat > Makefile < zarith_version.ml + # install targets ################# diff --git a/tests/Makefile b/tests/Makefile index 73ee2cb..07402bf 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,6 @@ -WORDSIZE:=$(shell echo 'print_int Sys.word_size' | ocaml -stdin) +WORDSIZE:=$(shell echo print_int Sys.word_size | ocaml -stdin) +BACKEND:=$(shell echo print_string Z.backend | ocaml -I .. zarith.cma -stdin) +DIGITSIZE:=$(shell echo print_int \(Z.digit_bits \(\)\) | ocaml -I .. zarith.cma -stdin) STDLIBDIR:=$(shell ocamlc -where) ifeq ($(wildcard $(STDLIBDIR)/big_int.cmi),) HAS_NUM=false @@ -11,12 +13,12 @@ NUMS_CMXA=nums.cmxa endif test:: zq.exe - @echo "Testing zq (native)..." - @if ./zq.exe | cmp -s zq.output$(WORDSIZE) - ; then echo "zq: passed"; else echo "zq: FAILED"; exit 2; fi + @echo "Testing zq (native) for $(WORDSIZE)-bit OCaml, $(BACKEND) backend with $(DIGITSIZE)-bit limbs/digits..." + @if ./zq.exe | diff -u zq.output-$(BACKEND)-$(WORDSIZE)-$(DIGITSIZE) - ; then echo "zq: passed"; else echo "zq: FAILED"; exit 2; fi test:: zq.byt - @echo "Testing zq (bytecode)..." - @if ocamlrun -I .. ./zq.byt | cmp -s zq.output$(WORDSIZE) - ; then echo "zq: passed"; else echo "zq: FAILED"; exit 2; fi + @echo "Testing zq (bytecode) for $(WORDSIZE)-bit OCaml, $(BACKEND) backend with $(DIGITSIZE)-bit limbs/digits..." + @if ocamlrun -I .. ./zq.byt | diff -u zq.output-$(BACKEND)-$(WORDSIZE)-$(DIGITSIZE) - ; then echo "zq: passed"; else echo "zq: FAILED"; exit 2; fi ifeq ($(HAS_NUM),true) test:: bi.exe @@ -26,7 +28,7 @@ endif test:: pi.exe @echo "Testing pi..." - @if ./pi.exe 500 | cmp -s pi.output - ; then echo "pi: passed"; else echo "pi: FAILED"; exit 2; fi + @if ./pi.exe 500 | diff -u pi.output - ; then echo "pi: passed"; else echo "pi: FAILED"; exit 2; fi test:: tofloat.exe @echo "Testing tofloat..." diff --git a/tests/ofstring.ml b/tests/ofstring.ml index bf8684b..f38f04b 100644 --- a/tests/ofstring.ml +++ b/tests/ofstring.ml @@ -12,7 +12,7 @@ let p121 = pow2 121 let test_of_string_Z () = let round_trip_Z () = - let round_trip fmt x= + let round_trip fmt x = (Z.equal (Z.of_string (Z.format fmt x)) x) in let formats = [ @@ -95,19 +95,19 @@ let test_of_string_Z () = succ "Z.of_string" Z.of_string "0x" Z.zero; succ "Z.of_string" Z.of_string "0b" Z.zero; - fail "Z.of_substring" (Z.of_substring ~pos:1 ~len:2) "0b2"; - fail "Z.of_substring" (Z.of_substring ~pos:1 ~len:2) "0o8"; - fail "Z.of_substring" (Z.of_substring ~pos:1 ~len:2) "0xg"; - fail "Z.of_substring" (Z.of_substring ~pos:1 ~len:2) "0xG"; - fail "Z.of_substring" (Z.of_substring ~pos:1 ~len:1) "0A"; - succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:0) "+" Z.zero; - succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:1) "-+" Z.zero; - succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:2)"--1-" (Z.minus_one); - succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:2)"--1\000" (Z.minus_one); - succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:2)"\000-1\000" (Z.minus_one); - succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:1)"00b1" Z.zero; - succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:2)"00b1" Z.zero; - succ "Z.of_substring" (Z.of_substring ~pos:1 ~len:3)"00b1" Z.one; + fail "Z.of_substring(1,2)" (Z.of_substring ~pos:1 ~len:2) "0b2"; + fail "Z.of_substring(1,2)" (Z.of_substring ~pos:1 ~len:2) "0o8"; + fail "Z.of_substring(1,2)" (Z.of_substring ~pos:1 ~len:2) "0xg"; + fail "Z.of_substring(1,2)" (Z.of_substring ~pos:1 ~len:2) "0xG"; + fail "Z.of_substring(1,1)" (Z.of_substring ~pos:1 ~len:1) "0A"; + succ "Z.of_substring(1,0)" (Z.of_substring ~pos:1 ~len:0) "+" Z.zero; + succ "Z.of_substring(1,1)" (Z.of_substring ~pos:1 ~len:1) "-+" Z.zero; + succ "Z.of_substring(1,2)" (Z.of_substring ~pos:1 ~len:2)"--1-" (Z.minus_one); + succ "Z.of_substring(1,2)" (Z.of_substring ~pos:1 ~len:2)"--1\000" (Z.minus_one); + succ "Z.of_substring(1,2)" (Z.of_substring ~pos:1 ~len:2)"\000-1\000" (Z.minus_one); + succ "Z.of_substring(1,1)" (Z.of_substring ~pos:1 ~len:1)"00b1" Z.zero; + succ "Z.of_substring(1,2)" (Z.of_substring ~pos:1 ~len:2)"00b1" Z.zero; + succ "Z.of_substring(1,3)" (Z.of_substring ~pos:1 ~len:3)"00b1" Z.one; z_and_int_agree "_123"; z_and_int_agree "1_23"; @@ -119,7 +119,7 @@ let test_of_string_Z () = let s = Z.format "%#b" p120 in let n = String.length s in for i = 0 to n - 3 do - succ "Z.of_substring" + succ ("Z.of_substring(0,"^(string_of_int (n-i))^")") (Z.of_substring ~pos:0 ~len:(n - i)) s (Z.shift_right p120 i) diff --git a/tests/zq.ml b/tests/zq.ml index fb007ca..722ebd8 100644 --- a/tests/zq.ml +++ b/tests/zq.ml @@ -16,6 +16,11 @@ *) +let failure_harness f = + try f () + with Failure f -> Printf.printf "Failure: %s\n" f + + (* testing Z *) module I = Z @@ -666,7 +671,6 @@ let test_Z() = Printf.printf "divisible (2^300-1) 32\n = %B\n" (I.divisible (I.pred p300) (I.of_int 32)); Printf.printf "divisible min_int (max_int+1)\n = %B\n" (I.divisible (I.of_int min_int) (I.succ (I.of_int max_int))); Printf.printf "divisible (max_int+1) min_int\n = %B\n" (I.divisible (I.succ (I.of_int max_int)) (I.of_int min_int)); - (* always 0 when not using custom blocks *) Printf.printf "hash(2^120)\n = %i\n" (Hashtbl.hash p120); Printf.printf "hash(2^121)\n = %i\n" (Hashtbl.hash p121); @@ -796,7 +800,6 @@ let test_Z() = c,0,1; c,0,64; c,128,1; c,128,5; c,131,32; c,175,63; c,277,123] in List.iter chk_extract extract_testdata; List.iter chk_signed_extract extract_testdata; - chk_bits I.zero; chk_bits p2; chk_bits (I.neg p2); @@ -815,19 +818,16 @@ let test_Z() = chk_bits mini64; chk_bits maxni; chk_bits minni; - List.iter chk_testbit [ - I.zero; I.one; I.of_int (-42); - I.of_string "31415926535897932384626433832795028841971693993751058209749445923078164062862089986"; - I.neg (I.shift_left (I.of_int 123456) 64); - ]; - + I.zero; I.one; I.of_int (-42); + I.of_string "31415926535897932384626433832795028841971693993751058209749445923078164062862089986"; + I.neg (I.shift_left (I.of_int 123456) 64); + ]; List.iter chk_numbits_tz [ - I.zero; I.one; I.of_int (-42); - I.shift_left (I.of_int 9999) 77; - I.neg (I.shift_left (I.of_int 123456) 64); - ]; - + I.zero; I.one; I.of_int (-42); + I.shift_left (I.of_int 9999) 77; + I.neg (I.shift_left (I.of_int 123456) 64); + ]; Printf.printf "random_bits 45 = %a\n" pr (I.random_bits_gen ~fill:pr_bytes 45); Printf.printf "random_bits 45 = %a\n" @@ -838,7 +838,6 @@ let test_Z() = pr (I.random_int_gen ~fill:pr_bytes (I.of_int 123456)); Printf.printf "random_int 9999999 = %a\n" pr (I.random_int_gen ~fill:pr_bytes (I.of_int 9999999)); - () @@ -918,3 +917,5 @@ let test_Q () = let _ = test_Z() let _ = test_Q() +let _ = Gc.full_major () + diff --git a/tests/zq.output32 b/tests/zq.output-GMP-32-32 similarity index 100% rename from tests/zq.output32 rename to tests/zq.output-GMP-32-32 diff --git a/tests/zq.output64 b/tests/zq.output-GMP-64-64 similarity index 100% rename from tests/zq.output64 rename to tests/zq.output-GMP-64-64 diff --git a/tests/zq.output-LibTomMath-64-28 b/tests/zq.output-LibTomMath-64-28 new file mode 100644 index 0000000..5847b83 --- /dev/null +++ b/tests/zq.output-LibTomMath-64-28 @@ -0,0 +1,1284 @@ +0 + = 0 +1 + = 1 +-1 + = -1 +42 + = 42 +1+1 + = 2 +1-1 + = 0 +- 1 + = -1 +0-1 + = -1 +max_int + = 4611686018427387903 +min_int + = -4611686018427387904 +-max_int + = -4611686018427387903 +-min_int + = 4611686018427387904 +2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^120 + = 1329227995784915872903807060280344576 +2^300+2^120 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300-2^120 + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +2^300+(-(2^120)) + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +2^120-2^300 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +2^120+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-(2^120)+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +-(2^120)-2^300 + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300-2^300 + = 0 +2^121 + = 2658455991569831745807614120560689152 +2^121+2^120 + = 3987683987354747618711421180841033728 +2^121-2^120 + = 1329227995784915872903807060280344576 +2^121+(-(2^120)) + = 1329227995784915872903807060280344576 +2^120-2^121 + = -1329227995784915872903807060280344576 +2^120+(-(2^121)) + = -1329227995784915872903807060280344576 +-(2^120)+(-(2^121)) + = -3987683987354747618711421180841033728 +-(2^120)-2^121 + = -3987683987354747618711421180841033728 +2^121+0 + = 2658455991569831745807614120560689152 +2^121-0 + = 2658455991569831745807614120560689152 +0+2^121 + = 2658455991569831745807614120560689152 +0-2^121 + = -2658455991569831745807614120560689152 +2^300+1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +2^300-1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +1+2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +1-2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +2^300+(-1) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +2^300-(-1) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +(-1)+2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +(-1)-2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)+1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +-(2^300)-1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +1+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +1-(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)+(-1) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)-(-1) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +(-1)+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +(-1)-(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +max_int+1 + = 4611686018427387904 +min_int-1 + = -4611686018427387905 +-max_int-1 + = -4611686018427387904 +-min_int-1 + = 4611686018427387903 +5! = 120 +12! = 479001600 +15! = 1307674368000 +20! = 2432902008176640000 +25! = 15511210043330985984000000 +50! = 30414093201713378043612608166064768844377641568960512000000000000 +2^300*2^120 + = 2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^120*2^300 + = 2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^300*(-(2^120)) + = -2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^120*(-(2^300)) + = -2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +-(2^120)*(-(2^300)) + = 2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^121*2^120 + = 3533694129556768659166595001485837031654967793751237916243212402585239552 +2^120*2^121 + = 3533694129556768659166595001485837031654967793751237916243212402585239552 +2^121*0 + = 0 +0*2^121 + = 0 +2^300*1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1*2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^300*(-1) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +(-1)*2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-(2^300)*1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1*(-(2^300)) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-(2^300)*(-1) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +(-1)*(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1*(2^30) + = 1073741824 +1*(2^62) + = 4611686018427387904 +(2^30)*(2^30) + = 1152921504606846976 +(2^62)*(2^62) + = 21267647932558653966460912964485513216 +0+1 + = 1 +1+1 + = 2 +-1+1 + = 0 +2+1 + = 3 +-2+1 + = -1 +(2^300)+1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)+1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +0-1 + = -1 +1-1 + = 0 +-1-1 + = -2 +2-1 + = 1 +-2-1 + = -3 +(2^300)-1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +-(2^300)-1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +max_int+1 + = 4611686018427387904 +min_int-1 + = -4611686018427387905 +-max_int-1 + = -4611686018427387904 +-min_int-1 + = 4611686018427387903 +abs(0) + = 0 +abs(1) + = 1 +abs(-1) + = 1 +abs(min_int) + = 4611686018427387904 +abs(2^300) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +abs(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +max_natint + = 9223372036854775807 +max_int32 + = 2147483647 +max_int64 + = 9223372036854775807 +to_int 1 + = 1 +to_int max_int + = 4611686018427387903 +to_int max_natint + = ovf +to_int max_int32 + = 2147483647 +to_int max_int64 + = ovf +to_int32 1 + = 1 +to_int32 max_int + = ovf +to_int32 max_natint + = ovf +to_int32 max_int32 + = 2147483647 +to_int32 max_int64 + = ovf +to_int64 1 + = 1 +to_int64 max_int + = 4611686018427387903 +to_int64 max_natint + = 9223372036854775807 +to_int64 max_int32 + = 2147483647 +to_int64 max_int64 + = 9223372036854775807 +to_natint 1 + = 1 +to_natint max_int + = 4611686018427387903 +to_natint max_natint + = 9223372036854775807 +to_natint max_int32 + = 2147483647 +to_natint max_int64 + = 9223372036854775807 +to_int -min_int + = ovf +to_int -min_natint + = ovf +to_int -min_int32 + = 2147483648 +to_int -min_int64 + = ovf +to_int32 -min_int + = ovf +to_int32 -min_natint + = ovf +to_int32 -min_int32 + = ovf +to_int32 -min_int64 + = ovf +to_int64 -min_int + = 4611686018427387904 +to_int64 -min_natint + = ovf +to_int64 -min_int32 + = 2147483648 +to_int64 -min_int64 + = ovf +to_natint -min_int + = 4611686018427387904 +to_natint -min_natint + = ovf +to_natint -min_int32 + = 2147483648 +to_natint -min_int64 + = ovf +of_float 1. + = 1 +of_float -1. + = -1 +of_float pi + = 3 +of_float 2^30 + = 1073741824 +of_float 2^31 + = 2147483648 +of_float 2^32 + = 4294967296 +of_float 2^33 + = 8589934592 +of_float -2^30 + = -1073741824 +of_float -2^31 + = -2147483648 +of_float -2^32 + = -4294967296 +of_float -2^33 + = -8589934592 +of_float 2^61 + = 2305843009213693952 +of_float 2^62 + = 4611686018427387904 +of_float 2^63 + = 9223372036854775808 +of_float 2^64 + = 18446744073709551616 +of_float 2^65 + = 36893488147419103232 +of_float -2^61 + = -2305843009213693952 +of_float -2^62 + = -4611686018427387904 +of_float -2^63 + = -9223372036854775808 +of_float -2^64 + = -18446744073709551616 +of_float -2^65 + = -36893488147419103232 +of_float 2^120 + = 1329227995784915872903807060280344576 +of_float 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +of_float -2^120 + = -1329227995784915872903807060280344576 +of_float -2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +of_float 0.5 + = 0 +of_float -0.5 + = 0 +of_float 200.5 + = 200 +of_float -200.5 + = -200 +to_float 0 + = OK +to_float 1 + = OK +to_float -1 + = OK +to_float 2^120 + = OK +to_float -2^120 + = OK +to_float (2^120-1) + = OK +to_float (-2^120+1) + = OK +to_float 2^63 + = OK +to_float -2^63 + = OK +to_float (2^63-1) + = OK +to_float (-2^63-1) + = OK +to_float (-2^63+1) + = OK +to_float 2^300 + = OK +to_float -2^300 + = OK +to_float (2^300-1) + = OK +to_float (-2^300+1) + = OK +of_string 12 + = 12 +of_string 0x12 + = 18 +of_string 0b10 + = 2 +of_string 0o12 + = 10 +of_string -12 + = -12 +of_string -0x12 + = -18 +of_string -0b10 + = -2 +of_string -0o12 + = -10 +of_string 000123456789012345678901234567890 + = 123456789012345678901234567890 +2^120 / 2^300 (trunc) + = 0 +max_int / 2 (trunc) + = 2305843009213693951 +(2^300+1) / 2^120 (trunc) + = 1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / 2^120 (trunc) + = -1532495540865888858358347027150309183618739122183602176 +(2^300+1) / (-(2^120)) (trunc) + = -1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / (-(2^120)) (trunc) + = 1532495540865888858358347027150309183618739122183602176 +2^120 / 2^300 (ceil) + = 1 +max_int / 2 (ceil) + = 2305843009213693952 +(2^300+1) / 2^120 (ceil) + = 1532495540865888858358347027150309183618739122183602177 +(-(2^300+1)) / 2^120 (ceil) + = -1532495540865888858358347027150309183618739122183602176 +(2^300+1) / (-(2^120)) (ceil) + = -1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / (-(2^120)) (ceil) + = 1532495540865888858358347027150309183618739122183602177 +2^120 / 2^300 (floor) + = 0 +max_int / 2 (floor) + = 2305843009213693951 +(2^300+1) / 2^120 (floor) + = 1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / 2^120 (floor) + = -1532495540865888858358347027150309183618739122183602177 +(2^300+1) / (-(2^120)) (floor) + = -1532495540865888858358347027150309183618739122183602177 +(-(2^300+1)) / (-(2^120)) (floor) + = 1532495540865888858358347027150309183618739122183602176 +2^120 % 2^300 + = 1329227995784915872903807060280344576 +max_int % 2 + = 1 +(2^300+1) % 2^120 + = 1 +(-(2^300+1)) % 2^120 + = -1 +(2^300+1) % (-(2^120)) + = 1 +(-(2^300+1)) % (-(2^120)) + = -1 +2^120 /,% 2^300 + = 0, 1329227995784915872903807060280344576 +max_int /,% 2 + = 2305843009213693951, 1 +(2^300+1) /,% 2^120 + = 1532495540865888858358347027150309183618739122183602176, 1 +(-(2^300+1)) /,% 2^120 + = -1532495540865888858358347027150309183618739122183602176, -1 +(2^300+1) /,% (-(2^120)) + = -1532495540865888858358347027150309183618739122183602176, 1 +(-(2^300+1)) /,% (-(2^120)) + = 1532495540865888858358347027150309183618739122183602176, -1 +1 & 2 + = 0 +1 & 2^300 + = 0 +2^120 & 2^300 + = 0 +2^300 & 2^120 + = 0 +2^300 & 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^300 & 0 + = 0 +-2^120 & 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 + 2^120 & -2^300 + = 0 +-2^120 & -2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^300 & 2^120 + = 0 + 2^300 & -2^120 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^300 & -2^120 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1 | 2 + = 3 +1 | 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +2^120 | 2^300 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 | 2^120 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 | 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^300 | 0 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^120 | 2^300 + = -1329227995784915872903807060280344576 + 2^120 | -2^300 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-2^120 | -2^300 + = -1329227995784915872903807060280344576 +-2^300 | 2^120 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 + 2^300 | -2^120 + = -1329227995784915872903807060280344576 +-2^300 | -2^120 + = -1329227995784915872903807060280344576 +1 ^ 2 + = 3 +1 ^ 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +2^120 ^ 2^300 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 ^ 2^120 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 ^ 2^300 + = 0 +2^300 ^ 0 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^120 ^ 2^300 + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 + 2^120 ^ -2^300 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-2^120 ^ -2^300 + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-2^300 ^ 2^120 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 + 2^300 ^ -2^120 + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +-2^300 ^ -2^120 + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +~0 + = -1 +~1 + = -2 +~2 + = -3 +~2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +~(-1) + = 0 +~(-2) + = 1 +~(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +0 >> 1 + = 0 +0 >> 100 + = 0 +2 >> 1 + = 1 +2 >> 2 + = 0 +2 >> 100 + = 0 +2^300 >> 1 + = 1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +2^300 >> 2 + = 509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +2^300 >> 100 + = 1606938044258990275541962092341162602522202993782792835301376 +2^300 >> 200 + = 1267650600228229401496703205376 +2^300 >> 300 + = 1 +2^300 >> 400 + = 0 +-1 >> 1 + = -1 +-2 >> 1 + = -1 +-2 >> 2 + = -1 +-2 >> 100 + = -1 +-2^300 >> 1 + = -1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +-2^300 >> 2 + = -509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +-2^300 >> 100 + = -1606938044258990275541962092341162602522202993782792835301376 +-2^300 >> 200 + = -1267650600228229401496703205376 +-2^300 >> 300 + = -1 +-2^300 >> 400 + = -1 +0 >>0 1 + = 0 +0 >>0 100 + = 0 +2 >>0 1 + = 1 +2 >>0 2 + = 0 +2 >>0 100 + = 0 +2^300 >>0 1 + = 1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +2^300 >>0 2 + = 509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +2^300 >>0 100 + = 1606938044258990275541962092341162602522202993782792835301376 +2^300 >>0 200 + = 1267650600228229401496703205376 +2^300 >>0 300 + = 1 +2^300 >>0 400 + = 0 +-1 >>0 1 + = 0 +-2 >>0 1 + = -1 +-2 >>0 2 + = 0 +-2 >>0 100 + = 0 +-2^300 >>0 1 + = -1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +-2^300 >>0 2 + = -509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +-2^300 >>0 100 + = -1606938044258990275541962092341162602522202993782792835301376 +-2^300 >>0 200 + = -1267650600228229401496703205376 +-2^300 >>0 300 + = -1 +-2^300 >>0 400 + = 0 +0 << 1 + = 0 +0 << 100 + = 0 +2 << 1 + = 4 +2 << 32 + = 8589934592 +2 << 64 + = 36893488147419103232 +2 << 299 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^120 << 1 + = 2658455991569831745807614120560689152 +2^120 << 180 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +compare 1 2 + = -1 +compare 1 1 + = 0 +compare 2 1 + = 1 +compare 2^300 2^120 + = 1 +compare 2^120 2^120 + = 0 +compare 2^120 2^300 + = -1 +compare 2^121 2^120 + = 1 +compare 2^120 2^121 + = -1 +compare 2^300 -2^120 + = 1 +compare 2^120 -2^120 + = 1 +compare 2^120 -2^300 + = 1 +compare -2^300 2^120 + = -1 +compare -2^120 2^120 + = -1 +compare -2^120 2^300 + = -1 +compare -2^300 -2^120 + = -1 +compare -2^120 -2^120 + = 0 +compare -2^120 -2^300 + = 1 +equal 1 2 + = false +equal 1 1 + = true +equal 2 1 + = false +equal 2^300 2^120 + = false +equal 2^120 2^120 + = true +equal 2^120 2^300 + = false +equal 2^121 2^120 + = false +equal 2^120 2^121 + = false +equal 2^120 -2^120 + = false +equal -2^120 2^120 + = false +equal -2^120 -2^120 + = true +sign 0 + = 0 +sign 1 + = 1 +sign -1 + = -1 +sign 2^300 + = 1 +sign -2^300 + = -1 +gcd 0 0 + = 0 +gcd 0 -137 + = 137 +gcd 12 27 + = 3 +gcd 27 12 + = 3 +gcd 27 27 + = 27 +gcd -12 27 + = 3 +gcd 12 -27 + = 3 +gcd -12 -27 + = 3 +gcd 0 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +gcd 2^120 2^300 + = 1329227995784915872903807060280344576 +gcd 2^300 2^120 + = 1329227995784915872903807060280344576 +gcd 0 -2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +gcd 2^120 -2^300 + = 1329227995784915872903807060280344576 +gcd 2^300 -2^120 + = 1329227995784915872903807060280344576 +gcd -2^120 2^300 + = 1329227995784915872903807060280344576 +gcd -2^300 2^120 + = 1329227995784915872903807060280344576 +gcd -2^120 -2^300 + = 1329227995784915872903807060280344576 +gcd -2^300 -2^120 + = 1329227995784915872903807060280344576 +gcdext 12 27 + = 3, -2, 1 +gcdext 27 12 + = 3, 1, -2 +gcdext 27 27 + = 27, 0, 1 +gcdext -12 27 + = 3, 2, 1 +gcdext 12 -27 + = 3, -2, -1 +gcdext -12 -27 + = 3, 2, -1 +gcdext 2^120 2^300 + = 1329227995784915872903807060280344576, 1, 0 +gcdext 2^300 2^120 + = 1329227995784915872903807060280344576, 0, 1 +gcdext 12 0 + = 12, 1, 0 +gcdext 0 27 + = 27, 0, 1 +gcdext -12 0 + = 12, -1, 0 +gcdext 0 -27 + = 27, 0, -1 +gcdext 2^120 0 + = 1329227995784915872903807060280344576, 1, 0 +gcdext 0 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, 0, 1 +gcdext -2^120 0 + = 1329227995784915872903807060280344576, -1, 0 +gcdext 0 -2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, 0, -1 +gcdext 0 0 + = 0, 0, 0 +lcm 0 0 = 0 +lcm 10 12 = 60 +lcm -10 12 = 60 +lcm 10 -12 = 60 +lcm -10 -12 = 60 +lcm 0 12 = 0 +lcm 0 -12 = 0 +lcm 10 0 = 0 +lcm -10 0 = 0 +lcm 2^120 2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm 2^120 -2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm -2^120 2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm -2^120 -2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm 2^120 0 = 0 +lcm -2^120 0 = 0 +is_odd 0 + = false +is_odd 1 + = true +is_odd 2 + = false +is_odd 3 + = true +is_odd 2^120 + = false +is_odd 2^120+1 + = true +is_odd 2^300 + = false +is_odd 2^300+1 + = true +sqrt 0 + = 0 +sqrt 1 + = 1 +sqrt 2 + = 1 +sqrt 2^120 + = 1152921504606846976 +sqrt 2^121 + = 1630477228166597776 +Failure: Z.sqrt_rem: not implemented in LibTomMath backend +popcount 0 + = 0 +popcount 1 + = 1 +popcount 2 + = 1 +popcount max_int32 + = 31 +popcount 2^120 + = 1 +popcount (2^120-1) + = 120 +Failure: Z.hamdist: not implemented in LibTomMath backend +hash(2^120) + = 337659727 +hash(2^121) + = 2072150 +hash(2^300) + = 684456904 +2^120 = 2^300 + = false +2^120 = 2^120 + = true +2^120 = 2^120 + = true +2^120 > 2^300 + = false +2^120 < 2^300 + = true +2^120 = 1 + = false +2^120 > 1 + = true +2^120 < 1 + = false +-2^120 > 1 + = false +-2^120 < 1 + = true +demarshal 2^120, 2^300, 1 + = 1329227995784915872903807060280344576, 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, 1 +demarshal -2^120, -2^300, -1 + = -1329227995784915872903807060280344576, -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, -1 +format %i 0 = /0/ +format %i 1 = /1/ +format %i -1 = /-1/ +format %i 2^30 = /1073741824/ +format %i -2^30 = /-1073741824/ +format % i 1 = / 1/ +format %+i 1 = /+1/ +format %x 0 = /0/ +format %x 1 = /1/ +format %x -1 = /-1/ +format %x 2^30 = /40000000/ +format %x -2^30 = /-40000000/ +format %X 0 = /0/ +format %X 1 = /1/ +format %X -1 = /-1/ +format %X 2^30 = /40000000/ +format %X -2^30 = /-40000000/ +format %o 0 = /0/ +format %o 1 = /1/ +format %o -1 = /-1/ +format %o 2^30 = /10000000000/ +format %o -2^30 = /-10000000000/ +format %10i 0 = / 0/ +format %10i 1 = / 1/ +format %10i -1 = / -1/ +format %10i 2^30 = /1073741824/ +format %10i -2^30 = /-1073741824/ +format %-10i 0 = /0 / +format %-10i 1 = /1 / +format %-10i -1 = /-1 / +format %-10i 2^30 = /1073741824/ +format %-10i -2^30 = /-1073741824/ +format %+10i 0 = / +0/ +format %+10i 1 = / +1/ +format %+10i -1 = / -1/ +format %+10i 2^30 = /+1073741824/ +format %+10i -2^30 = /-1073741824/ +format % 10i 0 = / 0/ +format % 10i 1 = / 1/ +format % 10i -1 = / -1/ +format % 10i 2^30 = / 1073741824/ +format % 10i -2^30 = /-1073741824/ +format %010i 0 = /0000000000/ +format %010i 1 = /0000000001/ +format %010i -1 = /-000000001/ +format %010i 2^30 = /1073741824/ +format %010i -2^30 = /-1073741824/ +format %#x 0 = /0x0/ +format %#x 1 = /0x1/ +format %#x -1 = /-0x1/ +format %#x 2^30 = /0x40000000/ +format %#x -2^30 = /-0x40000000/ +format %#X 0 = /0X0/ +format %#X 1 = /0X1/ +format %#X -1 = /-0X1/ +format %#X 2^30 = /0X40000000/ +format %#X -2^30 = /-0X40000000/ +format %#o 0 = /0o0/ +format %#o 1 = /0o1/ +format %#o -1 = /-0o1/ +format %#o 2^30 = /0o10000000000/ +format %#o -2^30 = /-0o10000000000/ +format %#10x 0 = / 0x0/ +format %#10x 1 = / 0x1/ +format %#10x -1 = / -0x1/ +format %#10x 2^30 = /0x40000000/ +format %#10x -2^30 = /-0x40000000/ +format %#10X 0 = / 0X0/ +format %#10X 1 = / 0X1/ +format %#10X -1 = / -0X1/ +format %#10X 2^30 = /0X40000000/ +format %#10X -2^30 = /-0X40000000/ +format %#10o 0 = / 0o0/ +format %#10o 1 = / 0o1/ +format %#10o -1 = / -0o1/ +format %#10o 2^30 = /0o10000000000/ +format %#10o -2^30 = /-0o10000000000/ +format %#-10x 0 = /0x0 / +format %#-10x 1 = /0x1 / +format %#-10x -1 = /-0x1 / +format %#-10x 2^30 = /0x40000000/ +format %#-10x -2^30 = /-0x40000000/ +format %#-10X 0 = /0X0 / +format %#-10X 1 = /0X1 / +format %#-10X -1 = /-0X1 / +format %#-10X 2^30 = /0X40000000/ +format %#-10X -2^30 = /-0X40000000/ +format %#-10o 0 = /0o0 / +format %#-10o 1 = /0o1 / +format %#-10o -1 = /-0o1 / +format %#-10o 2^30 = /0o10000000000/ +format %#-10o -2^30 = /-0o10000000000/ +Failure: Z.extract: not implemented in LibTomMath backend +to_bits 0 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip 0 + = OK +to_bits 2 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip 2 + = OK +to_bits -2 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip -2 + = OK +to_bits 1073741824 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip 1073741824 + = OK +to_bits -1073741824 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip -1073741824 + = OK +to_bits 4611686018427387904 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip 4611686018427387904 + = OK +to_bits -4611686018427387904 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip -4611686018427387904 + = OK +to_bits 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 + = OK +to_bits 1329227995784915872903807060280344576 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip 1329227995784915872903807060280344576 + = OK +to_bits 2658455991569831745807614120560689152 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip 2658455991569831745807614120560689152 + = OK +to_bits 4611686018427387903 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip 4611686018427387903 + = OK +to_bits -4611686018427387904 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip -4611686018427387904 + = OK +to_bits 2147483647 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip 2147483647 + = OK +to_bits -2147483648 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip -2147483648 + = OK +to_bits 9223372036854775807 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip 9223372036854775807 + = OK +to_bits -9223372036854775808 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip -9223372036854775808 + = OK +to_bits 9223372036854775807 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip 9223372036854775807 + = OK +to_bits -9223372036854775808 + =Failure: Z.to_bits: not implemented in LibTomMath backend +marshal round trip -9223372036854775808 + = OK +testbit 0 Failure: Z.extract: not implemented in LibTomMath backend +numbits / trailing_zeros 0 (passed) +numbits / trailing_zeros 1 (passed) +numbits / trailing_zeros -42 Failure: Z.extract: not implemented in LibTomMath backend +- 0 = 0 +- 1 = -1 +- -1 = 1 +- +inf = -inf +- -inf = +inf +- undef = undef +1/ 0 = +inf +1/ 1 = 1 +1/ -1 = -1 +1/ +inf = 0 +1/ -inf = 0 +1/ undef = undef +abs 0 = 0 +abs 1 = 1 +abs -1 = 1 +abs +inf = +inf +abs -inf = +inf +abs undef = undef +0 + 0 = 0 +0 + 1 = 1 +0 + -1 = -1 +0 + +inf = +inf +0 + -inf = -inf +0 + undef = undef +1 + 0 = 1 +1 + 1 = 2 +1 + -1 = 0 +1 + +inf = +inf +1 + -inf = -inf +1 + undef = undef +-1 + 0 = -1 +-1 + 1 = 0 +-1 + -1 = -2 +-1 + +inf = +inf +-1 + -inf = -inf +-1 + undef = undef ++inf + 0 = +inf ++inf + 1 = +inf ++inf + -1 = +inf ++inf + +inf = +inf ++inf + -inf = undef ++inf + undef = undef +-inf + 0 = -inf +-inf + 1 = -inf +-inf + -1 = -inf +-inf + +inf = undef +-inf + -inf = -inf +-inf + undef = undef +undef + 0 = undef +undef + 1 = undef +undef + -1 = undef +undef + +inf = undef +undef + -inf = undef +undef + undef = undef +0 - 0 = 0 +0 - 1 = -1 +0 - -1 = 1 +0 - +inf = -inf +0 - -inf = +inf +0 - undef = undef +1 - 0 = 1 +1 - 1 = 0 +1 - -1 = 2 +1 - +inf = -inf +1 - -inf = +inf +1 - undef = undef +-1 - 0 = -1 +-1 - 1 = -2 +-1 - -1 = 0 +-1 - +inf = -inf +-1 - -inf = +inf +-1 - undef = undef ++inf - 0 = +inf ++inf - 1 = +inf ++inf - -1 = +inf ++inf - +inf = undef ++inf - -inf = +inf ++inf - undef = undef +-inf - 0 = -inf +-inf - 1 = -inf +-inf - -1 = -inf +-inf - +inf = -inf +-inf - -inf = undef +-inf - undef = undef +undef - 0 = undef +undef - 1 = undef +undef - -1 = undef +undef - +inf = undef +undef - -inf = undef +undef - undef = undef +0 * 0 = 0 +0 * 1 = 0 +0 * -1 = 0 +0 * +inf = undef +0 * -inf = undef +0 * undef = undef +1 * 0 = 0 +1 * 1 = 1 +1 * -1 = -1 +1 * +inf = +inf +1 * -inf = -inf +1 * undef = undef +-1 * 0 = 0 +-1 * 1 = -1 +-1 * -1 = 1 +-1 * +inf = -inf +-1 * -inf = +inf +-1 * undef = undef ++inf * 0 = undef ++inf * 1 = +inf ++inf * -1 = -inf ++inf * +inf = +inf ++inf * -inf = -inf ++inf * undef = undef +-inf * 0 = undef +-inf * 1 = -inf +-inf * -1 = +inf +-inf * +inf = -inf +-inf * -inf = +inf +-inf * undef = undef +undef * 0 = undef +undef * 1 = undef +undef * -1 = undef +undef * +inf = undef +undef * -inf = undef +undef * undef = undef +0 / 0 = undef +0 / 1 = 0 +0 / -1 = 0 +0 / +inf = 0 +0 / -inf = 0 +0 / undef = undef +1 / 0 = +inf +1 / 1 = 1 +1 / -1 = -1 +1 / +inf = 0 +1 / -inf = 0 +1 / undef = undef +-1 / 0 = -inf +-1 / 1 = -1 +-1 / -1 = 1 +-1 / +inf = 0 +-1 / -inf = 0 +-1 / undef = undef ++inf / 0 = +inf ++inf / 1 = +inf ++inf / -1 = -inf ++inf / +inf = undef ++inf / -inf = undef ++inf / undef = undef +-inf / 0 = -inf +-inf / 1 = -inf +-inf / -1 = +inf +-inf / +inf = undef +-inf / -inf = undef +-inf / undef = undef +undef / 0 = undef +undef / 1 = undef +undef / -1 = undef +undef / +inf = undef +undef / -inf = undef +undef / undef = undef +0 * 1/ 0 = undef +0 * 1/ 1 = 0 +0 * 1/ -1 = 0 +0 * 1/ +inf = 0 +0 * 1/ -inf = 0 +0 * 1/ undef = undef +1 * 1/ 0 = +inf +1 * 1/ 1 = 1 +1 * 1/ -1 = -1 +1 * 1/ +inf = 0 +1 * 1/ -inf = 0 +1 * 1/ undef = undef +-1 * 1/ 0 = -inf +-1 * 1/ 1 = -1 +-1 * 1/ -1 = 1 +-1 * 1/ +inf = 0 +-1 * 1/ -inf = 0 +-1 * 1/ undef = undef ++inf * 1/ 0 = +inf ++inf * 1/ 1 = +inf ++inf * 1/ -1 = -inf ++inf * 1/ +inf = undef ++inf * 1/ -inf = undef ++inf * 1/ undef = undef +-inf * 1/ 0 = -inf +-inf * 1/ 1 = -inf +-inf * 1/ -1 = +inf +-inf * 1/ +inf = undef +-inf * 1/ -inf = undef +-inf * 1/ undef = undef +undef * 1/ 0 = undef +undef * 1/ 1 = undef +undef * 1/ -1 = undef +undef * 1/ +inf = undef +undef * 1/ -inf = undef +undef * 1/ undef = undef +mul_2exp (1) 0 = 0 +mul_2exp (1) 1 = 2 +mul_2exp (1) -1 = -2 +mul_2exp (1) +inf = +inf +mul_2exp (1) -inf = -inf +mul_2exp (1) undef = undef +mul_2exp (2) 0 = 0 +mul_2exp (2) 1 = 4 +mul_2exp (2) -1 = -4 +mul_2exp (2) +inf = +inf +mul_2exp (2) -inf = -inf +mul_2exp (2) undef = undef +div_2exp (1) 0 = 0 +div_2exp (1) 1 = 1/2 +div_2exp (1) -1 = -1/2 +div_2exp (1) +inf = +inf +div_2exp (1) -inf = -inf +div_2exp (1) undef = undef +div_2exp (2) 0 = 0 +div_2exp (2) 1 = 1/4 +div_2exp (2) -1 = -1/4 +div_2exp (2) +inf = +inf +div_2exp (2) -inf = -inf +div_2exp (2) undef = undef +identity checking 0 0 +identity checking 0 1 +identity checking 0 -1 +identity checking 0 +inf +identity checking 0 -inf +identity checking 0 undef +identity checking 1 0 +identity checking 1 1 +identity checking 1 -1 +identity checking 1 +inf +identity checking 1 -inf +identity checking 1 undef +identity checking -1 0 +identity checking -1 1 +identity checking -1 -1 +identity checking -1 +inf +identity checking -1 -inf +identity checking -1 undef +identity checking +inf 0 +identity checking +inf 1 +identity checking +inf -1 +identity checking +inf +inf +identity checking +inf -inf +identity checking +inf undef +identity checking -inf 0 +identity checking -inf 1 +identity checking -inf -1 +identity checking -inf +inf +identity checking -inf -inf +identity checking -inf undef +identity checking undef 0 +identity checking undef 1 +identity checking undef -1 +identity checking undef +inf +identity checking undef -inf +identity checking undef undef diff --git a/tests/zq.output-LibTomMath-64-60 b/tests/zq.output-LibTomMath-64-60 new file mode 100644 index 0000000..bfcd1a2 --- /dev/null +++ b/tests/zq.output-LibTomMath-64-60 @@ -0,0 +1,1452 @@ +0 + = 0 +1 + = 1 +-1 + = -1 +42 + = 42 +1+1 + = 2 +1-1 + = 0 +- 1 + = -1 +0-1 + = -1 +max_int + = 4611686018427387903 +min_int + = -4611686018427387904 +-max_int + = -4611686018427387903 +-min_int + = 4611686018427387904 +2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^120 + = 1329227995784915872903807060280344576 +2^300+2^120 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300-2^120 + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +2^300+(-(2^120)) + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +2^120-2^300 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +2^120+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-(2^120)+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +-(2^120)-2^300 + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300-2^300 + = 0 +2^121 + = 2658455991569831745807614120560689152 +2^121+2^120 + = 3987683987354747618711421180841033728 +2^121-2^120 + = 1329227995784915872903807060280344576 +2^121+(-(2^120)) + = 1329227995784915872903807060280344576 +2^120-2^121 + = -1329227995784915872903807060280344576 +2^120+(-(2^121)) + = -1329227995784915872903807060280344576 +-(2^120)+(-(2^121)) + = -3987683987354747618711421180841033728 +-(2^120)-2^121 + = -3987683987354747618711421180841033728 +2^121+0 + = 2658455991569831745807614120560689152 +2^121-0 + = 2658455991569831745807614120560689152 +0+2^121 + = 2658455991569831745807614120560689152 +0-2^121 + = -2658455991569831745807614120560689152 +2^300+1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +2^300-1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +1+2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +1-2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +2^300+(-1) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +2^300-(-1) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +(-1)+2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +(-1)-2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)+1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +-(2^300)-1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +1+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +1-(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)+(-1) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)-(-1) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +(-1)+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +(-1)-(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +max_int+1 + = 4611686018427387904 +min_int-1 + = -4611686018427387905 +-max_int-1 + = -4611686018427387904 +-min_int-1 + = 4611686018427387903 +5! = 120 +12! = 479001600 +15! = 1307674368000 +20! = 2432902008176640000 +25! = 15511210043330985984000000 +50! = 30414093201713378043612608166064768844377641568960512000000000000 +2^300*2^120 + = 2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^120*2^300 + = 2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^300*(-(2^120)) + = -2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^120*(-(2^300)) + = -2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +-(2^120)*(-(2^300)) + = 2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^121*2^120 + = 3533694129556768659166595001485837031654967793751237916243212402585239552 +2^120*2^121 + = 3533694129556768659166595001485837031654967793751237916243212402585239552 +2^121*0 + = 0 +0*2^121 + = 0 +2^300*1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1*2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^300*(-1) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +(-1)*2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-(2^300)*1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1*(-(2^300)) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-(2^300)*(-1) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +(-1)*(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1*(2^30) + = 1073741824 +1*(2^62) + = 4611686018427387904 +(2^30)*(2^30) + = 1152921504606846976 +(2^62)*(2^62) + = 21267647932558653966460912964485513216 +0+1 + = 1 +1+1 + = 2 +-1+1 + = 0 +2+1 + = 3 +-2+1 + = -1 +(2^300)+1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)+1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +0-1 + = -1 +1-1 + = 0 +-1-1 + = -2 +2-1 + = 1 +-2-1 + = -3 +(2^300)-1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +-(2^300)-1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +max_int+1 + = 4611686018427387904 +min_int-1 + = -4611686018427387905 +-max_int-1 + = -4611686018427387904 +-min_int-1 + = 4611686018427387903 +abs(0) + = 0 +abs(1) + = 1 +abs(-1) + = 1 +abs(min_int) + = 4611686018427387904 +abs(2^300) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +abs(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +max_nativeint + = 9223372036854775807 +max_int32 + = 2147483647 +max_int64 + = 9223372036854775807 +to_int 1 + = true,1 +to_int max_int + = true,4611686018427387903 +to_int max_nativeint + = false,ovf +to_int max_int32 + = true,2147483647 +to_int max_int64 + = false,ovf +to_int32 1 + = true,1 +to_int32 max_int + = false,ovf +to_int32 max_nativeint + = false,ovf +to_int32 max_int32 + = true,2147483647 +to_int32 max_int64 + = false,ovf +to_int64 1 + = true,1 +to_int64 max_int + = true,4611686018427387903 +to_int64 max_nativeint + = true,9223372036854775807 +to_int64 max_int32 + = true,2147483647 +to_int64 max_int64 + = true,9223372036854775807 +to_nativeint 1 + = true,1 +to_nativeint max_int + = true,4611686018427387903 +to_nativeint max_nativeint + = true,9223372036854775807 +to_nativeint max_int32 + = true,2147483647 +to_nativeint max_int64 + = true,9223372036854775807 +to_int -min_int + = false,ovf +to_int -min_nativeint + = false,ovf +to_int -min_int32 + = true,2147483648 +to_int -min_int64 + = false,ovf +to_int32 -min_int + = false,ovf +to_int32 -min_nativeint + = false,ovf +to_int32 -min_int32 + = false,ovf +to_int32 -min_int64 + = false,ovf +to_int64 -min_int + = true,4611686018427387904 +to_int64 -min_nativeint + = false,ovf +to_int64 -min_int32 + = true,2147483648 +to_int64 -min_int64 + = false,ovf +to_nativeint -min_int + = true,4611686018427387904 +to_nativeint -min_nativeint + = false,ovf +to_nativeint -min_int32 + = true,2147483648 +to_nativeint -min_int64 + = false,ovf +to_int32_unsigned 1 + = true,1 +to_int32_unsigned -1 + = false,ovf +to_int32_unsigned max_int + = false,ovf +to_int32_unsigned max_nativeint + = false,ovf +to_int32_unsigned max_int32 + = true,2147483647 +to_int32_unsigned 2max_int32 + = true,-2 +to_int32_unsigned 3max_int32 + = false,ovf +to_int32_unsigned max_int64 + = false,ovf +to_int64_unsigned 1 + = true,1 +to_int64_unsigned -1 + = false,ovf +to_int64_unsigned max_int + = true,4611686018427387903 +to_int64_unsigned max_nativeint + = true,9223372036854775807 +to_int64_unsigned max_int32 + = true,2147483647 +to_int64_unsigned max_int64 + = true,9223372036854775807 +to_int64_unsigned 2max_int64 + = true,-2 +to_int64_unsigned 3max_int64 + = false,ovf +to_nativeint_unsigned 1 + = true,1 +to_nativeint_unsigned -1 + = false,ovf +to_nativeint_unsigned max_int + = true,4611686018427387903 +to_nativeint_unsigned max_nativeint + = true,9223372036854775807 +to_nativeint_unsigned 2max_nativeint + = true,-2 +to_nativeint_unsigned max_int32 + = true,2147483647 +to_nativeint_unsigned max_int64 + = true,9223372036854775807 +to_nativeint_unsigned 2max_int64 + = true,-2 +to_nativeint_unsigned 3max_int64 + = false,ovf +of_int32_unsigned -1 + = 4294967295 +of_int64_unsigned -1 + = 18446744073709551615 +of_nativeint_unsigned -1 + = 18446744073709551615 +of_float 1. + = 1 +of_float -1. + = -1 +of_float pi + = 3 +of_float 2^30 + = 1073741824 +of_float 2^31 + = 2147483648 +of_float 2^32 + = 4294967296 +of_float 2^33 + = 8589934592 +of_float -2^30 + = -1073741824 +of_float -2^31 + = -2147483648 +of_float -2^32 + = -4294967296 +of_float -2^33 + = -8589934592 +of_float 2^61 + = 2305843009213693952 +of_float 2^62 + = 4611686018427387904 +of_float 2^63 + = 9223372036854775808 +of_float 2^64 + = 18446744073709551616 +of_float 2^65 + = 36893488147419103232 +of_float -2^61 + = -2305843009213693952 +of_float -2^62 + = -4611686018427387904 +of_float -2^63 + = -9223372036854775808 +of_float -2^64 + = -18446744073709551616 +of_float -2^65 + = -36893488147419103232 +of_float 2^120 + = 1329227995784915872903807060280344576 +of_float 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +of_float -2^120 + = -1329227995784915872903807060280344576 +of_float -2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +of_float 0.5 + = 0 +of_float -0.5 + = 0 +of_float 200.5 + = 200 +of_float -200.5 + = -200 +to_float 0 + = OK +to_float 1 + = OK +to_float -1 + = OK +to_float 2^120 + = OK +to_float -2^120 + = OK +to_float (2^120-1) + = OK +to_float (-2^120+1) + = OK +to_float 2^63 + = OK +to_float -2^63 + = OK +to_float (2^63-1) + = OK +to_float (-2^63-1) + = OK +to_float (-2^63+1) + = OK +to_float 2^300 + = OK +to_float -2^300 + = OK +to_float (2^300-1) + = OK +to_float (-2^300+1) + = OK +of_string 12 + = 12 +of_string 0x12 + = 18 +of_string 0b10 + = 2 +of_string 0o12 + = 10 +of_string -12 + = -12 +of_string -0x12 + = -18 +of_string -0b10 + = -2 +of_string -0o12 + = -10 +of_string 000123456789012345678901234567890 + = 123456789012345678901234567890 +2^120 / 2^300 (trunc) + = 0 +max_int / 2 (trunc) + = 2305843009213693951 +(2^300+1) / 2^120 (trunc) + = 1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / 2^120 (trunc) + = -1532495540865888858358347027150309183618739122183602176 +(2^300+1) / (-(2^120)) (trunc) + = -1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / (-(2^120)) (trunc) + = 1532495540865888858358347027150309183618739122183602176 +2^120 / 2^300 (ceil) + = 1 +max_int / 2 (ceil) + = 2305843009213693952 +(2^300+1) / 2^120 (ceil) + = 1532495540865888858358347027150309183618739122183602177 +(-(2^300+1)) / 2^120 (ceil) + = -1532495540865888858358347027150309183618739122183602176 +(2^300+1) / (-(2^120)) (ceil) + = -1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / (-(2^120)) (ceil) + = 1532495540865888858358347027150309183618739122183602177 +2^120 / 2^300 (floor) + = 0 +max_int / 2 (floor) + = 2305843009213693951 +(2^300+1) / 2^120 (floor) + = 1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / 2^120 (floor) + = -1532495540865888858358347027150309183618739122183602177 +(2^300+1) / (-(2^120)) (floor) + = -1532495540865888858358347027150309183618739122183602177 +(-(2^300+1)) / (-(2^120)) (floor) + = 1532495540865888858358347027150309183618739122183602176 +2^120 % 2^300 + = 1329227995784915872903807060280344576 +max_int % 2 + = 1 +(2^300+1) % 2^120 + = 1 +(-(2^300+1)) % 2^120 + = -1 +(2^300+1) % (-(2^120)) + = 1 +(-(2^300+1)) % (-(2^120)) + = -1 +2^120 /,% 2^300 + = 0, 1329227995784915872903807060280344576 +max_int /,% 2 + = 2305843009213693951, 1 +(2^300+1) /,% 2^120 + = 1532495540865888858358347027150309183618739122183602176, 1 +(-(2^300+1)) /,% 2^120 + = -1532495540865888858358347027150309183618739122183602176, -1 +(2^300+1) /,% (-(2^120)) + = -1532495540865888858358347027150309183618739122183602176, 1 +(-(2^300+1)) /,% (-(2^120)) + = 1532495540865888858358347027150309183618739122183602176, -1 +1 & 2 + = 0 +1 & 2^300 + = 0 +2^120 & 2^300 + = 0 +2^300 & 2^120 + = 0 +2^300 & 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^300 & 0 + = 0 +-2^120 & 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 + 2^120 & -2^300 + = 0 +-2^120 & -2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^300 & 2^120 + = 0 + 2^300 & -2^120 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^300 & -2^120 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1 | 2 + = 3 +1 | 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +2^120 | 2^300 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 | 2^120 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 | 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^300 | 0 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^120 | 2^300 + = -1329227995784915872903807060280344576 + 2^120 | -2^300 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-2^120 | -2^300 + = -1329227995784915872903807060280344576 +-2^300 | 2^120 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 + 2^300 | -2^120 + = -1329227995784915872903807060280344576 +-2^300 | -2^120 + = -1329227995784915872903807060280344576 +1 ^ 2 + = 3 +1 ^ 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +2^120 ^ 2^300 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 ^ 2^120 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 ^ 2^300 + = 0 +2^300 ^ 0 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^120 ^ 2^300 + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 + 2^120 ^ -2^300 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-2^120 ^ -2^300 + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-2^300 ^ 2^120 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 + 2^300 ^ -2^120 + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +-2^300 ^ -2^120 + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +~0 + = -1 +~1 + = -2 +~2 + = -3 +~2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +~(-1) + = 0 +~(-2) + = 1 +~(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +0 >> 1 + = 0 +0 >> 100 + = 0 +2 >> 1 + = 1 +2 >> 2 + = 0 +2 >> 100 + = 0 +2^300 >> 1 + = 1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +2^300 >> 2 + = 509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +2^300 >> 100 + = 1606938044258990275541962092341162602522202993782792835301376 +2^300 >> 200 + = 1267650600228229401496703205376 +2^300 >> 300 + = 1 +2^300 >> 400 + = 0 +-1 >> 1 + = -1 +-2 >> 1 + = -1 +-2 >> 2 + = -1 +-2 >> 100 + = -1 +-2^300 >> 1 + = -1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +-2^300 >> 2 + = -509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +-2^300 >> 100 + = -1606938044258990275541962092341162602522202993782792835301376 +-2^300 >> 200 + = -1267650600228229401496703205376 +-2^300 >> 300 + = -1 +-2^300 >> 400 + = -1 +0 >>0 1 + = 0 +0 >>0 100 + = 0 +2 >>0 1 + = 1 +2 >>0 2 + = 0 +2 >>0 100 + = 0 +2^300 >>0 1 + = 1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +2^300 >>0 2 + = 509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +2^300 >>0 100 + = 1606938044258990275541962092341162602522202993782792835301376 +2^300 >>0 200 + = 1267650600228229401496703205376 +2^300 >>0 300 + = 1 +2^300 >>0 400 + = 0 +-1 >>0 1 + = 0 +-2 >>0 1 + = -1 +-2 >>0 2 + = 0 +-2 >>0 100 + = 0 +-2^300 >>0 1 + = -1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +-2^300 >>0 2 + = -509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +-2^300 >>0 100 + = -1606938044258990275541962092341162602522202993782792835301376 +-2^300 >>0 200 + = -1267650600228229401496703205376 +-2^300 >>0 300 + = -1 +-2^300 >>0 400 + = 0 +0 << 1 + = 0 +0 << 100 + = 0 +2 << 1 + = 4 +2 << 32 + = 8589934592 +2 << 64 + = 36893488147419103232 +2 << 299 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^120 << 1 + = 2658455991569831745807614120560689152 +2^120 << 180 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +compare 1 2 + = -1 +compare 1 1 + = 0 +compare 2 1 + = 1 +compare 2^300 2^120 + = 1 +compare 2^120 2^120 + = 0 +compare 2^120 2^300 + = -1 +compare 2^121 2^120 + = 1 +compare 2^120 2^121 + = -1 +compare 2^300 -2^120 + = 1 +compare 2^120 -2^120 + = 1 +compare 2^120 -2^300 + = 1 +compare -2^300 2^120 + = -1 +compare -2^120 2^120 + = -1 +compare -2^120 2^300 + = -1 +compare -2^300 -2^120 + = -1 +compare -2^120 -2^120 + = 0 +compare -2^120 -2^300 + = 1 +equal 1 2 + = false +equal 1 1 + = true +equal 2 1 + = false +equal 2^300 2^120 + = false +equal 2^120 2^120 + = true +equal 2^120 2^300 + = false +equal 2^121 2^120 + = false +equal 2^120 2^121 + = false +equal 2^120 -2^120 + = false +equal -2^120 2^120 + = false +equal -2^120 -2^120 + = true +sign 0 + = 0 +sign 1 + = 1 +sign -1 + = -1 +sign 2^300 + = 1 +sign -2^300 + = -1 +gcd 0 0 + = 0 +gcd 0 -137 + = 137 +gcd 12 27 + = 3 +gcd 27 12 + = 3 +gcd 27 27 + = 27 +gcd -12 27 + = 3 +gcd 12 -27 + = 3 +gcd -12 -27 + = 3 +gcd 0 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +gcd 2^120 2^300 + = 1329227995784915872903807060280344576 +gcd 2^300 2^120 + = 1329227995784915872903807060280344576 +gcd 0 -2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +gcd 2^120 -2^300 + = 1329227995784915872903807060280344576 +gcd 2^300 -2^120 + = 1329227995784915872903807060280344576 +gcd -2^120 2^300 + = 1329227995784915872903807060280344576 +gcd -2^300 2^120 + = 1329227995784915872903807060280344576 +gcd -2^120 -2^300 + = 1329227995784915872903807060280344576 +gcd -2^300 -2^120 + = 1329227995784915872903807060280344576 +gcdext 12 27 + = 3, -2, 1 +gcdext 27 12 + = 3, 1, -2 +gcdext 27 27 + = 27, 0, 1 +gcdext -12 27 + = 3, 2, 1 +gcdext 12 -27 + = 3, -2, -1 +gcdext -12 -27 + = 3, 2, -1 +gcdext 2^120 2^300 + = 1329227995784915872903807060280344576, 1, 0 +gcdext 2^300 2^120 + = 1329227995784915872903807060280344576, 0, 1 +gcdext 12 0 + = 12, 1, 0 +gcdext 0 27 + = 27, 0, 1 +gcdext -12 0 + = 12, -1, 0 +gcdext 0 -27 + = 27, 0, -1 +gcdext 2^120 0 + = 1329227995784915872903807060280344576, 1, 0 +gcdext 0 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, 0, 1 +gcdext -2^120 0 + = 1329227995784915872903807060280344576, -1, 0 +gcdext 0 -2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, 0, -1 +gcdext 0 0 + = 0, 0, 0 +lcm 0 0 = 0 +lcm 10 12 = 60 +lcm -10 12 = 60 +lcm 10 -12 = 60 +lcm -10 -12 = 60 +lcm 0 12 = 0 +lcm 0 -12 = 0 +lcm 10 0 = 0 +lcm -10 0 = 0 +lcm 2^120 2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm 2^120 -2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm -2^120 2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm -2^120 -2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm 2^120 0 = 0 +lcm -2^120 0 = 0 +is_odd 0 + = false +is_odd 1 + = true +is_odd 2 + = false +is_odd 3 + = true +is_odd 2^120 + = false +is_odd 2^120+1 + = true +is_odd 2^300 + = false +is_odd 2^300+1 + = true +sqrt 0 + = 0 +sqrt 1 + = 1 +sqrt 2 + = 1 +sqrt 2^120 + = 1152921504606846976 +sqrt 2^121 + = 1630477228166597776 +sqrt_rem 0 + = 0, 0 +sqrt_rem 1 + = 1, 0 +sqrt_rem 2 + = 1, 1 +sqrt_rem 2^120 + = 1152921504606846976, 0 +sqrt_rem 2^121 + = 1630477228166597776, 1772969445592542976 +popcount 0 + = 0 +popcount 1 + = 1 +popcount 2 + = 1 +popcount max_int32 + = 31 +popcount 2^120 + = 1 +popcount (2^120-1) + = 120 +hamdist 0 0 + = 0 +hamdist 0 1 + = 1 +hamdist 0 2^300 + = 1 +hamdist 2^120 2^120 + = 0 +hamdist 2^120 (2^120-1) + = 121 +hamdist 2^120 2^300 + = 2 +hamdist (2^120-1) (2^300-1) + = 180 +divisible 42 7 + = true +divisible 43 7 + = false +divisible 0 0 + = true +divisible 0 2^120 + = true +divisible 2 2^120 + = false +divisible 2^300 2^120 + = true +divisible (2^300-1) 32 + = false +divisible min_int (max_int+1) + = true +divisible (max_int+1) min_int + = true +hash(2^120) + = 900619431 +hash(2^121) + = 324032971 +hash(2^300) + = 49167343 +2^120 = 2^300 + = false +2^120 = 2^120 + = true +2^120 = 2^120 + = true +2^120 > 2^300 + = false +2^120 < 2^300 + = true +2^120 = 1 + = false +2^120 > 1 + = true +2^120 < 1 + = false +-2^120 > 1 + = false +-2^120 < 1 + = true +demarshal 2^120, 2^300, 1 + = 1329227995784915872903807060280344576, 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, 1 +demarshal -2^120, -2^300, -1 + = -1329227995784915872903807060280344576, -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, -1 +format %i 0 = /0/ +format %i 1 = /1/ +format %i -1 = /-1/ +format %i 2^30 = /1073741824/ +format %i -2^30 = /-1073741824/ +format % i 1 = / 1/ +format %+i 1 = /+1/ +format %x 0 = /0/ +format %x 1 = /1/ +format %x -1 = /-1/ +format %x 2^30 = /40000000/ +format %x -2^30 = /-40000000/ +format %X 0 = /0/ +format %X 1 = /1/ +format %X -1 = /-1/ +format %X 2^30 = /40000000/ +format %X -2^30 = /-40000000/ +format %o 0 = /0/ +format %o 1 = /1/ +format %o -1 = /-1/ +format %o 2^30 = /10000000000/ +format %o -2^30 = /-10000000000/ +format %10i 0 = / 0/ +format %10i 1 = / 1/ +format %10i -1 = / -1/ +format %10i 2^30 = /1073741824/ +format %10i -2^30 = /-1073741824/ +format %-10i 0 = /0 / +format %-10i 1 = /1 / +format %-10i -1 = /-1 / +format %-10i 2^30 = /1073741824/ +format %-10i -2^30 = /-1073741824/ +format %+10i 0 = / +0/ +format %+10i 1 = / +1/ +format %+10i -1 = / -1/ +format %+10i 2^30 = /+1073741824/ +format %+10i -2^30 = /-1073741824/ +format % 10i 0 = / 0/ +format % 10i 1 = / 1/ +format % 10i -1 = / -1/ +format % 10i 2^30 = / 1073741824/ +format % 10i -2^30 = /-1073741824/ +format %010i 0 = /0000000000/ +format %010i 1 = /0000000001/ +format %010i -1 = /-000000001/ +format %010i 2^30 = /1073741824/ +format %010i -2^30 = /-1073741824/ +format %#x 0 = /0x0/ +format %#x 1 = /0x1/ +format %#x -1 = /-0x1/ +format %#x 2^30 = /0x40000000/ +format %#x -2^30 = /-0x40000000/ +format %#X 0 = /0X0/ +format %#X 1 = /0X1/ +format %#X -1 = /-0X1/ +format %#X 2^30 = /0X40000000/ +format %#X -2^30 = /-0X40000000/ +format %#o 0 = /0o0/ +format %#o 1 = /0o1/ +format %#o -1 = /-0o1/ +format %#o 2^30 = /0o10000000000/ +format %#o -2^30 = /-0o10000000000/ +format %#10x 0 = / 0x0/ +format %#10x 1 = / 0x1/ +format %#10x -1 = / -0x1/ +format %#10x 2^30 = /0x40000000/ +format %#10x -2^30 = /-0x40000000/ +format %#10X 0 = / 0X0/ +format %#10X 1 = / 0X1/ +format %#10X -1 = / -0X1/ +format %#10X 2^30 = /0X40000000/ +format %#10X -2^30 = /-0X40000000/ +format %#10o 0 = / 0o0/ +format %#10o 1 = / 0o1/ +format %#10o -1 = / -0o1/ +format %#10o 2^30 = /0o10000000000/ +format %#10o -2^30 = /-0o10000000000/ +format %#-10x 0 = /0x0 / +format %#-10x 1 = /0x1 / +format %#-10x -1 = /-0x1 / +format %#-10x 2^30 = /0x40000000/ +format %#-10x -2^30 = /-0x40000000/ +format %#-10X 0 = /0X0 / +format %#-10X 1 = /0X1 / +format %#-10X -1 = /-0X1 / +format %#-10X 2^30 = /0X40000000/ +format %#-10X -2^30 = /-0X40000000/ +format %#-10o 0 = /0o0 / +format %#-10o 1 = /0o1 / +format %#-10o -1 = /-0o1 / +format %#-10o 2^30 = /0o10000000000/ +format %#-10o -2^30 = /-0o10000000000/ +extract 42 0 1 = 0 (passed) +extract 42 0 5 = 10 (passed) +extract 42 0 32 = 42 (passed) +extract 42 0 64 = 42 (passed) +extract 42 1 1 = 1 (passed) +extract 42 1 5 = 21 (passed) +extract 42 1 32 = 21 (passed) +extract 42 1 63 = 21 (passed) +extract 42 1 64 = 21 (passed) +extract 42 1 127 = 21 (passed) +extract 42 1 128 = 21 (passed) +extract 42 69 12 = 0 (passed) +extract -42 0 1 = 0 (passed) +extract -42 0 5 = 22 (passed) +extract -42 0 32 = 4294967254 (passed) +extract -42 0 64 = 18446744073709551574 (passed) +extract -42 1 1 = 1 (passed) +extract -42 1 5 = 11 (passed) +extract -42 1 32 = 4294967275 (passed) +extract -42 1 63 = 9223372036854775787 (passed) +extract -42 1 64 = 18446744073709551595 (passed) +extract -42 1 127 = 170141183460469231731687303715884105707 (passed) +extract -42 1 128 = 340282366920938463463374607431768211435 (passed) +extract -42 69 12 = 4095 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 0 1 = 1 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 0 64 = 15536040655639606317 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 128 1 = 1 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 128 5 = 19 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 131 32 = 2516587394 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 175 63 = 7690089207107781587 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 277 123 = 9888429935207999867003931753264634841 (passed) +signed_extract 42 0 1 = 0 (passed) +signed_extract 42 0 5 = 10 (passed) +signed_extract 42 0 32 = 42 (passed) +signed_extract 42 0 64 = 42 (passed) +signed_extract 42 1 1 = -1 (passed) +signed_extract 42 1 5 = -11 (passed) +signed_extract 42 1 32 = 21 (passed) +signed_extract 42 1 63 = 21 (passed) +signed_extract 42 1 64 = 21 (passed) +signed_extract 42 1 127 = 21 (passed) +signed_extract 42 1 128 = 21 (passed) +signed_extract 42 69 12 = 0 (passed) +signed_extract -42 0 1 = 0 (passed) +signed_extract -42 0 5 = -10 (passed) +signed_extract -42 0 32 = -42 (passed) +signed_extract -42 0 64 = -42 (passed) +signed_extract -42 1 1 = -1 (passed) +signed_extract -42 1 5 = 11 (passed) +signed_extract -42 1 32 = -21 (passed) +signed_extract -42 1 63 = -21 (passed) +signed_extract -42 1 64 = -21 (passed) +signed_extract -42 1 127 = -21 (passed) +signed_extract -42 1 128 = -21 (passed) +signed_extract -42 69 12 = -1 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 0 1 = -1 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 0 64 = -2910703418069945299 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 128 1 = -1 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 128 5 = -13 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 131 32 = -1778379902 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 175 63 = -1533282829746994221 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 277 123 = -745394031071327116226524728978121767 (passed) +to_bits 0 + = +marshal round trip 0 + = OK +to_bits 2 + = 02 +marshal round trip 2 + = OK +to_bits -2 + = 02 +marshal round trip -2 + = OK +to_bits 1073741824 + = 00 00 00 40 +marshal round trip 1073741824 + = OK +to_bits -1073741824 + = 00 00 00 40 +marshal round trip -1073741824 + = OK +to_bits 4611686018427387904 + = 00 00 00 00 00 00 00 40 +marshal round trip 4611686018427387904 + = OK +to_bits -4611686018427387904 + = 00 00 00 00 00 00 00 40 +marshal round trip -4611686018427387904 + = OK +to_bits 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 +marshal round trip 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 + = OK +to_bits 1329227995784915872903807060280344576 + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 +marshal round trip 1329227995784915872903807060280344576 + = OK +to_bits 2658455991569831745807614120560689152 + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 +marshal round trip 2658455991569831745807614120560689152 + = OK +to_bits 4611686018427387903 + = ff ff ff ff ff ff ff 3f +marshal round trip 4611686018427387903 + = OK +to_bits -4611686018427387904 + = 00 00 00 00 00 00 00 40 +marshal round trip -4611686018427387904 + = OK +to_bits 2147483647 + = ff ff ff 7f +marshal round trip 2147483647 + = OK +to_bits -2147483648 + = 00 00 00 80 +marshal round trip -2147483648 + = OK +to_bits 9223372036854775807 + = ff ff ff ff ff ff ff 7f +marshal round trip 9223372036854775807 + = OK +to_bits -9223372036854775808 + = 00 00 00 00 00 00 00 80 +marshal round trip -9223372036854775808 + = OK +to_bits 9223372036854775807 + = ff ff ff ff ff ff ff 7f +marshal round trip 9223372036854775807 + = OK +to_bits -9223372036854775808 + = 00 00 00 00 00 00 00 80 +marshal round trip -9223372036854775808 + = OK +testbit 0 (passed) +testbit 1 (passed) +testbit -42 (passed) +testbit 31415926535897932384626433832795028841971693993751058209749445923078164062862089986 (passed) +testbit -2277361236363886404304896 (passed) +numbits / trailing_zeros 0 (passed) +numbits / trailing_zeros 1 (passed) +numbits / trailing_zeros -42 (passed) +numbits / trailing_zeros 1511006158790834639735881728 (passed) +numbits / trailing_zeros -2277361236363886404304896 (passed) +random_bits 45 = 25076743995969 +random_bits 45 = 33510880286625 +random_bits 12 = 1263 +random_int 123456 = 103797 +random_int 9999999 = 1089068 +- 0 = 0 +- 1 = -1 +- -1 = 1 +- +inf = -inf +- -inf = +inf +- undef = undef +1/ 0 = +inf +1/ 1 = 1 +1/ -1 = -1 +1/ +inf = 0 +1/ -inf = 0 +1/ undef = undef +abs 0 = 0 +abs 1 = 1 +abs -1 = 1 +abs +inf = +inf +abs -inf = +inf +abs undef = undef +0 + 0 = 0 +0 + 1 = 1 +0 + -1 = -1 +0 + +inf = +inf +0 + -inf = -inf +0 + undef = undef +1 + 0 = 1 +1 + 1 = 2 +1 + -1 = 0 +1 + +inf = +inf +1 + -inf = -inf +1 + undef = undef +-1 + 0 = -1 +-1 + 1 = 0 +-1 + -1 = -2 +-1 + +inf = +inf +-1 + -inf = -inf +-1 + undef = undef ++inf + 0 = +inf ++inf + 1 = +inf ++inf + -1 = +inf ++inf + +inf = +inf ++inf + -inf = undef ++inf + undef = undef +-inf + 0 = -inf +-inf + 1 = -inf +-inf + -1 = -inf +-inf + +inf = undef +-inf + -inf = -inf +-inf + undef = undef +undef + 0 = undef +undef + 1 = undef +undef + -1 = undef +undef + +inf = undef +undef + -inf = undef +undef + undef = undef +0 - 0 = 0 +0 - 1 = -1 +0 - -1 = 1 +0 - +inf = -inf +0 - -inf = +inf +0 - undef = undef +1 - 0 = 1 +1 - 1 = 0 +1 - -1 = 2 +1 - +inf = -inf +1 - -inf = +inf +1 - undef = undef +-1 - 0 = -1 +-1 - 1 = -2 +-1 - -1 = 0 +-1 - +inf = -inf +-1 - -inf = +inf +-1 - undef = undef ++inf - 0 = +inf ++inf - 1 = +inf ++inf - -1 = +inf ++inf - +inf = undef ++inf - -inf = +inf ++inf - undef = undef +-inf - 0 = -inf +-inf - 1 = -inf +-inf - -1 = -inf +-inf - +inf = -inf +-inf - -inf = undef +-inf - undef = undef +undef - 0 = undef +undef - 1 = undef +undef - -1 = undef +undef - +inf = undef +undef - -inf = undef +undef - undef = undef +0 * 0 = 0 +0 * 1 = 0 +0 * -1 = 0 +0 * +inf = undef +0 * -inf = undef +0 * undef = undef +1 * 0 = 0 +1 * 1 = 1 +1 * -1 = -1 +1 * +inf = +inf +1 * -inf = -inf +1 * undef = undef +-1 * 0 = 0 +-1 * 1 = -1 +-1 * -1 = 1 +-1 * +inf = -inf +-1 * -inf = +inf +-1 * undef = undef ++inf * 0 = undef ++inf * 1 = +inf ++inf * -1 = -inf ++inf * +inf = +inf ++inf * -inf = -inf ++inf * undef = undef +-inf * 0 = undef +-inf * 1 = -inf +-inf * -1 = +inf +-inf * +inf = -inf +-inf * -inf = +inf +-inf * undef = undef +undef * 0 = undef +undef * 1 = undef +undef * -1 = undef +undef * +inf = undef +undef * -inf = undef +undef * undef = undef +0 / 0 = undef +0 / 1 = 0 +0 / -1 = 0 +0 / +inf = 0 +0 / -inf = 0 +0 / undef = undef +1 / 0 = +inf +1 / 1 = 1 +1 / -1 = -1 +1 / +inf = 0 +1 / -inf = 0 +1 / undef = undef +-1 / 0 = -inf +-1 / 1 = -1 +-1 / -1 = 1 +-1 / +inf = 0 +-1 / -inf = 0 +-1 / undef = undef ++inf / 0 = +inf ++inf / 1 = +inf ++inf / -1 = -inf ++inf / +inf = undef ++inf / -inf = undef ++inf / undef = undef +-inf / 0 = -inf +-inf / 1 = -inf +-inf / -1 = +inf +-inf / +inf = undef +-inf / -inf = undef +-inf / undef = undef +undef / 0 = undef +undef / 1 = undef +undef / -1 = undef +undef / +inf = undef +undef / -inf = undef +undef / undef = undef +0 * 1/ 0 = undef +0 * 1/ 1 = 0 +0 * 1/ -1 = 0 +0 * 1/ +inf = 0 +0 * 1/ -inf = 0 +0 * 1/ undef = undef +1 * 1/ 0 = +inf +1 * 1/ 1 = 1 +1 * 1/ -1 = -1 +1 * 1/ +inf = 0 +1 * 1/ -inf = 0 +1 * 1/ undef = undef +-1 * 1/ 0 = -inf +-1 * 1/ 1 = -1 +-1 * 1/ -1 = 1 +-1 * 1/ +inf = 0 +-1 * 1/ -inf = 0 +-1 * 1/ undef = undef ++inf * 1/ 0 = +inf ++inf * 1/ 1 = +inf ++inf * 1/ -1 = -inf ++inf * 1/ +inf = undef ++inf * 1/ -inf = undef ++inf * 1/ undef = undef +-inf * 1/ 0 = -inf +-inf * 1/ 1 = -inf +-inf * 1/ -1 = +inf +-inf * 1/ +inf = undef +-inf * 1/ -inf = undef +-inf * 1/ undef = undef +undef * 1/ 0 = undef +undef * 1/ 1 = undef +undef * 1/ -1 = undef +undef * 1/ +inf = undef +undef * 1/ -inf = undef +undef * 1/ undef = undef +mul_2exp (1) 0 = 0 +mul_2exp (1) 1 = 2 +mul_2exp (1) -1 = -2 +mul_2exp (1) +inf = +inf +mul_2exp (1) -inf = -inf +mul_2exp (1) undef = undef +mul_2exp (2) 0 = 0 +mul_2exp (2) 1 = 4 +mul_2exp (2) -1 = -4 +mul_2exp (2) +inf = +inf +mul_2exp (2) -inf = -inf +mul_2exp (2) undef = undef +div_2exp (1) 0 = 0 +div_2exp (1) 1 = 1/2 +div_2exp (1) -1 = -1/2 +div_2exp (1) +inf = +inf +div_2exp (1) -inf = -inf +div_2exp (1) undef = undef +div_2exp (2) 0 = 0 +div_2exp (2) 1 = 1/4 +div_2exp (2) -1 = -1/4 +div_2exp (2) +inf = +inf +div_2exp (2) -inf = -inf +div_2exp (2) undef = undef +identity checking 0 0 +identity checking 0 1 +identity checking 0 -1 +identity checking 0 +inf +identity checking 0 -inf +identity checking 0 undef +identity checking 1 0 +identity checking 1 1 +identity checking 1 -1 +identity checking 1 +inf +identity checking 1 -inf +identity checking 1 undef +identity checking -1 0 +identity checking -1 1 +identity checking -1 -1 +identity checking -1 +inf +identity checking -1 -inf +identity checking -1 undef +identity checking +inf 0 +identity checking +inf 1 +identity checking +inf -1 +identity checking +inf +inf +identity checking +inf -inf +identity checking +inf undef +identity checking -inf 0 +identity checking -inf 1 +identity checking -inf -1 +identity checking -inf +inf +identity checking -inf -inf +identity checking -inf undef +identity checking undef 0 +identity checking undef 1 +identity checking undef -1 +identity checking undef +inf +identity checking undef -inf +identity checking undef undef diff --git a/tests/zq.output-MPIR-32-32 b/tests/zq.output-MPIR-32-32 new file mode 100644 index 0000000..376984a --- /dev/null +++ b/tests/zq.output-MPIR-32-32 @@ -0,0 +1,1373 @@ +0 + = 0 +1 + = 1 +-1 + = -1 +42 + = 42 +1+1 + = 2 +1-1 + = 0 +- 1 + = -1 +0-1 + = -1 +max_int + = 1073741823 +min_int + = -1073741824 +-max_int + = -1073741823 +-min_int + = 1073741824 +2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^120 + = 1329227995784915872903807060280344576 +2^300+2^120 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300-2^120 + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +2^300+(-(2^120)) + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +2^120-2^300 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +2^120+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-(2^120)+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +-(2^120)-2^300 + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300-2^300 + = 0 +2^121 + = 2658455991569831745807614120560689152 +2^121+2^120 + = 3987683987354747618711421180841033728 +2^121-2^120 + = 1329227995784915872903807060280344576 +2^121+(-(2^120)) + = 1329227995784915872903807060280344576 +2^120-2^121 + = -1329227995784915872903807060280344576 +2^120+(-(2^121)) + = -1329227995784915872903807060280344576 +-(2^120)+(-(2^121)) + = -3987683987354747618711421180841033728 +-(2^120)-2^121 + = -3987683987354747618711421180841033728 +2^121+0 + = 2658455991569831745807614120560689152 +2^121-0 + = 2658455991569831745807614120560689152 +0+2^121 + = 2658455991569831745807614120560689152 +0-2^121 + = -2658455991569831745807614120560689152 +2^300+1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +2^300-1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +1+2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +1-2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +2^300+(-1) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +2^300-(-1) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +(-1)+2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +(-1)-2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)+1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +-(2^300)-1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +1+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +1-(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)+(-1) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)-(-1) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +(-1)+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +(-1)-(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +max_int+1 + = 1073741824 +min_int-1 + = -1073741825 +-max_int-1 + = -1073741824 +-min_int-1 + = 1073741823 +5! = 120 +12! = 479001600 +15! = 1307674368000 +20! = 2432902008176640000 +25! = 15511210043330985984000000 +50! = 30414093201713378043612608166064768844377641568960512000000000000 +2^300*2^120 + = 2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^120*2^300 + = 2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^300*(-(2^120)) + = -2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^120*(-(2^300)) + = -2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +-(2^120)*(-(2^300)) + = 2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^121*2^120 + = 3533694129556768659166595001485837031654967793751237916243212402585239552 +2^120*2^121 + = 3533694129556768659166595001485837031654967793751237916243212402585239552 +2^121*0 + = 0 +0*2^121 + = 0 +2^300*1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1*2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^300*(-1) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +(-1)*2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-(2^300)*1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1*(-(2^300)) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-(2^300)*(-1) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +(-1)*(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1*(2^30) + = 1073741824 +1*(2^62) + = 4611686018427387904 +(2^30)*(2^30) + = 1152921504606846976 +(2^62)*(2^62) + = 21267647932558653966460912964485513216 +0+1 + = 1 +1+1 + = 2 +-1+1 + = 0 +2+1 + = 3 +-2+1 + = -1 +(2^300)+1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)+1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +0-1 + = -1 +1-1 + = 0 +-1-1 + = -2 +2-1 + = 1 +-2-1 + = -3 +(2^300)-1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +-(2^300)-1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +max_int+1 + = 1073741824 +min_int-1 + = -1073741825 +-max_int-1 + = -1073741824 +-min_int-1 + = 1073741823 +abs(0) + = 0 +abs(1) + = 1 +abs(-1) + = 1 +abs(min_int) + = 1073741824 +abs(2^300) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +abs(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +max_natint + = 2147483647 +max_int32 + = 2147483647 +max_int64 + = 9223372036854775807 +to_int 1 + = 1 +to_int max_int + = 1073741823 +to_int max_natint + = ovf +to_int max_int32 + = ovf +to_int max_int64 + = ovf +to_int32 1 + = 1 +to_int32 max_int + = 1073741823 +to_int32 max_natint + = 2147483647 +to_int32 max_int32 + = 2147483647 +to_int32 max_int64 + = ovf +to_int64 1 + = 1 +to_int64 max_int + = 1073741823 +to_int64 max_natint + = 2147483647 +to_int64 max_int32 + = 2147483647 +to_int64 max_int64 + = 9223372036854775807 +to_natint 1 + = 1 +to_natint max_int + = 1073741823 +to_natint max_natint + = 2147483647 +to_natint max_int32 + = 2147483647 +to_natint max_int64 + = ovf +to_int -min_int + = ovf +to_int -min_natint + = ovf +to_int -min_int32 + = ovf +to_int -min_int64 + = ovf +to_int32 -min_int + = 1073741824 +to_int32 -min_natint + = ovf +to_int32 -min_int32 + = ovf +to_int32 -min_int64 + = ovf +to_int64 -min_int + = 1073741824 +to_int64 -min_natint + = 2147483648 +to_int64 -min_int32 + = 2147483648 +to_int64 -min_int64 + = ovf +to_natint -min_int + = 1073741824 +to_natint -min_natint + = ovf +to_natint -min_int32 + = ovf +to_natint -min_int64 + = ovf +of_float 1. + = 1 +of_float -1. + = -1 +of_float pi + = 3 +of_float 2^30 + = 1073741824 +of_float 2^31 + = 2147483648 +of_float 2^32 + = 4294967296 +of_float 2^33 + = 8589934592 +of_float -2^30 + = -1073741824 +of_float -2^31 + = -2147483648 +of_float -2^32 + = -4294967296 +of_float -2^33 + = -8589934592 +of_float 2^61 + = 2305843009213693952 +of_float 2^62 + = 4611686018427387904 +of_float 2^63 + = 9223372036854775808 +of_float 2^64 + = 18446744073709551616 +of_float 2^65 + = 36893488147419103232 +of_float -2^61 + = -2305843009213693952 +of_float -2^62 + = -4611686018427387904 +of_float -2^63 + = -9223372036854775808 +of_float -2^64 + = -18446744073709551616 +of_float -2^65 + = -36893488147419103232 +of_float 2^120 + = 1329227995784915872903807060280344576 +of_float 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +of_float -2^120 + = -1329227995784915872903807060280344576 +of_float -2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +of_float 0.5 + = 0 +of_float -0.5 + = 0 +of_float 200.5 + = 200 +of_float -200.5 + = -200 +to_float 0 + = OK +to_float 1 + = OK +to_float -1 + = OK +to_float 2^120 + = OK +to_float -2^120 + = OK +to_float (2^120-1) + = OK +to_float (-2^120+1) + = OK +to_float 2^63 + = OK +to_float -2^63 + = OK +to_float (2^63-1) + = OK +to_float (-2^63-1) + = OK +to_float (-2^63+1) + = OK +to_float 2^300 + = OK +to_float -2^300 + = OK +to_float (2^300-1) + = OK +to_float (-2^300+1) + = OK +of_string 12 + = 12 +of_string 0x12 + = 18 +of_string 0b10 + = 2 +of_string 0o12 + = 10 +of_string -12 + = -12 +of_string -0x12 + = -18 +of_string -0b10 + = -2 +of_string -0o12 + = -10 +of_string 000123456789012345678901234567890 + = 123456789012345678901234567890 +2^120 / 2^300 (trunc) + = 0 +max_int / 2 (trunc) + = 536870911 +(2^300+1) / 2^120 (trunc) + = 1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / 2^120 (trunc) + = -1532495540865888858358347027150309183618739122183602176 +(2^300+1) / (-(2^120)) (trunc) + = -1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / (-(2^120)) (trunc) + = 1532495540865888858358347027150309183618739122183602176 +2^120 / 2^300 (ceil) + = 1 +max_int / 2 (ceil) + = 536870912 +(2^300+1) / 2^120 (ceil) + = 1532495540865888858358347027150309183618739122183602177 +(-(2^300+1)) / 2^120 (ceil) + = -1532495540865888858358347027150309183618739122183602176 +(2^300+1) / (-(2^120)) (ceil) + = -1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / (-(2^120)) (ceil) + = 1532495540865888858358347027150309183618739122183602177 +2^120 / 2^300 (floor) + = 0 +max_int / 2 (floor) + = 536870911 +(2^300+1) / 2^120 (floor) + = 1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / 2^120 (floor) + = -1532495540865888858358347027150309183618739122183602177 +(2^300+1) / (-(2^120)) (floor) + = -1532495540865888858358347027150309183618739122183602177 +(-(2^300+1)) / (-(2^120)) (floor) + = 1532495540865888858358347027150309183618739122183602176 +2^120 % 2^300 + = 1329227995784915872903807060280344576 +max_int % 2 + = 1 +(2^300+1) % 2^120 + = 1 +(-(2^300+1)) % 2^120 + = -1 +(2^300+1) % (-(2^120)) + = 1 +(-(2^300+1)) % (-(2^120)) + = -1 +2^120 /,% 2^300 + = 0, 1329227995784915872903807060280344576 +max_int /,% 2 + = 536870911, 1 +(2^300+1) /,% 2^120 + = 1532495540865888858358347027150309183618739122183602176, 1 +(-(2^300+1)) /,% 2^120 + = -1532495540865888858358347027150309183618739122183602176, -1 +(2^300+1) /,% (-(2^120)) + = -1532495540865888858358347027150309183618739122183602176, 1 +(-(2^300+1)) /,% (-(2^120)) + = 1532495540865888858358347027150309183618739122183602176, -1 +1 & 2 + = 0 +1 & 2^300 + = 0 +2^120 & 2^300 + = 0 +2^300 & 2^120 + = 0 +2^300 & 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^300 & 0 + = 0 +-2^120 & 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 + 2^120 & -2^300 + = 0 +-2^120 & -2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^300 & 2^120 + = 0 + 2^300 & -2^120 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^300 & -2^120 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1 | 2 + = 3 +1 | 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +2^120 | 2^300 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 | 2^120 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 | 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^300 | 0 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^120 | 2^300 + = -1329227995784915872903807060280344576 + 2^120 | -2^300 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-2^120 | -2^300 + = -1329227995784915872903807060280344576 +-2^300 | 2^120 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 + 2^300 | -2^120 + = -1329227995784915872903807060280344576 +-2^300 | -2^120 + = -1329227995784915872903807060280344576 +1 ^ 2 + = 3 +1 ^ 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +2^120 ^ 2^300 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 ^ 2^120 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 ^ 2^300 + = 0 +2^300 ^ 0 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^120 ^ 2^300 + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 + 2^120 ^ -2^300 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-2^120 ^ -2^300 + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-2^300 ^ 2^120 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 + 2^300 ^ -2^120 + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +-2^300 ^ -2^120 + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +~0 + = -1 +~1 + = -2 +~2 + = -3 +~2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +~(-1) + = 0 +~(-2) + = 1 +~(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +0 >> 1 + = 0 +0 >> 100 + = 0 +2 >> 1 + = 1 +2 >> 2 + = 0 +2 >> 100 + = 0 +2^300 >> 1 + = 1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +2^300 >> 2 + = 509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +2^300 >> 100 + = 1606938044258990275541962092341162602522202993782792835301376 +2^300 >> 200 + = 1267650600228229401496703205376 +2^300 >> 300 + = 1 +2^300 >> 400 + = 0 +-1 >> 1 + = -1 +-2 >> 1 + = -1 +-2 >> 2 + = -1 +-2 >> 100 + = -1 +-2^300 >> 1 + = -1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +-2^300 >> 2 + = -509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +-2^300 >> 100 + = -1606938044258990275541962092341162602522202993782792835301376 +-2^300 >> 200 + = -1267650600228229401496703205376 +-2^300 >> 300 + = -1 +-2^300 >> 400 + = -1 +0 >>0 1 + = 0 +0 >>0 100 + = 0 +2 >>0 1 + = 1 +2 >>0 2 + = 0 +2 >>0 100 + = 0 +2^300 >>0 1 + = 1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +2^300 >>0 2 + = 509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +2^300 >>0 100 + = 1606938044258990275541962092341162602522202993782792835301376 +2^300 >>0 200 + = 1267650600228229401496703205376 +2^300 >>0 300 + = 1 +2^300 >>0 400 + = 0 +-1 >>0 1 + = 0 +-2 >>0 1 + = -1 +-2 >>0 2 + = 0 +-2 >>0 100 + = 0 +-2^300 >>0 1 + = -1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +-2^300 >>0 2 + = -509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +-2^300 >>0 100 + = -1606938044258990275541962092341162602522202993782792835301376 +-2^300 >>0 200 + = -1267650600228229401496703205376 +-2^300 >>0 300 + = -1 +-2^300 >>0 400 + = 0 +0 << 1 + = 0 +0 << 100 + = 0 +2 << 1 + = 4 +2 << 32 + = 8589934592 +2 << 64 + = 36893488147419103232 +2 << 299 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^120 << 1 + = 2658455991569831745807614120560689152 +2^120 << 180 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +compare 1 2 + = -1 +compare 1 1 + = 0 +compare 2 1 + = 1 +compare 2^300 2^120 + = 1 +compare 2^120 2^120 + = 0 +compare 2^120 2^300 + = -1 +compare 2^121 2^120 + = 1 +compare 2^120 2^121 + = -1 +compare 2^300 -2^120 + = 1 +compare 2^120 -2^120 + = 1 +compare 2^120 -2^300 + = 1 +compare -2^300 2^120 + = -1 +compare -2^120 2^120 + = -1 +compare -2^120 2^300 + = -1 +compare -2^300 -2^120 + = -1 +compare -2^120 -2^120 + = 0 +compare -2^120 -2^300 + = 1 +equal 1 2 + = false +equal 1 1 + = true +equal 2 1 + = false +equal 2^300 2^120 + = false +equal 2^120 2^120 + = true +equal 2^120 2^300 + = false +equal 2^121 2^120 + = false +equal 2^120 2^121 + = false +equal 2^120 -2^120 + = false +equal -2^120 2^120 + = false +equal -2^120 -2^120 + = true +sign 0 + = 0 +sign 1 + = 1 +sign -1 + = -1 +sign 2^300 + = 1 +sign -2^300 + = -1 +gcd 0 0 + = 0 +gcd 0 -137 + = 137 +gcd 12 27 + = 3 +gcd 27 12 + = 3 +gcd 27 27 + = 27 +gcd -12 27 + = 3 +gcd 12 -27 + = 3 +gcd -12 -27 + = 3 +gcd 0 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +gcd 2^120 2^300 + = 1329227995784915872903807060280344576 +gcd 2^300 2^120 + = 1329227995784915872903807060280344576 +gcd 0 -2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +gcd 2^120 -2^300 + = 1329227995784915872903807060280344576 +gcd 2^300 -2^120 + = 1329227995784915872903807060280344576 +gcd -2^120 2^300 + = 1329227995784915872903807060280344576 +gcd -2^300 2^120 + = 1329227995784915872903807060280344576 +gcd -2^120 -2^300 + = 1329227995784915872903807060280344576 +gcd -2^300 -2^120 + = 1329227995784915872903807060280344576 +gcdext 12 27 + = 3, -2, 1 +gcdext 27 12 + = 3, 1, -2 +gcdext 27 27 + = 27, 0, 1 +gcdext -12 27 + = 3, 2, 1 +gcdext 12 -27 + = 3, -2, -1 +gcdext -12 -27 + = 3, 2, -1 +gcdext 2^120 2^300 + = 1329227995784915872903807060280344576, 1, 0 +gcdext 2^300 2^120 + = 1329227995784915872903807060280344576, 0, 1 +gcdext 12 0 + = 12, 1, 0 +gcdext 0 27 + = 27, 0, 1 +gcdext -12 0 + = 12, -1, 0 +gcdext 0 -27 + = 27, 0, -1 +gcdext 2^120 0 + = 1329227995784915872903807060280344576, 1, 0 +gcdext 0 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, 0, 1 +gcdext -2^120 0 + = 1329227995784915872903807060280344576, -1, 0 +gcdext 0 -2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, 0, -1 +gcdext 0 0 + = 0, 0, 0 +lcm 0 0 = 0 +lcm 10 12 = 60 +lcm -10 12 = 60 +lcm 10 -12 = 60 +lcm -10 -12 = 60 +lcm 0 12 = 0 +lcm 0 -12 = 0 +lcm 10 0 = 0 +lcm -10 0 = 0 +lcm 2^120 2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm 2^120 -2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm -2^120 2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm -2^120 -2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm 2^120 0 = 0 +lcm -2^120 0 = 0 +is_odd 0 + = false +is_odd 1 + = true +is_odd 2 + = false +is_odd 3 + = true +is_odd 2^120 + = false +is_odd 2^120+1 + = true +is_odd 2^300 + = false +is_odd 2^300+1 + = true +sqrt 0 + = 0 +sqrt 1 + = 1 +sqrt 2 + = 1 +sqrt 2^120 + = 1152921504606846976 +sqrt 2^121 + = 1630477228166597776 +sqrt_rem 0 + = 0, 0 +sqrt_rem 1 + = 1, 0 +sqrt_rem 2 + = 1, 1 +sqrt_rem 2^120 + = 1152921504606846976, 0 +sqrt_rem 2^121 + = 1630477228166597776, 1772969445592542976 +popcount 0 + = 0 +popcount 1 + = 1 +popcount 2 + = 1 +popcount max_int32 + = 31 +popcount 2^120 + = 1 +popcount (2^120-1) + = 120 +hamdist 0 0 + = 0 +hamdist 0 1 + = 1 +hamdist 0 2^300 + = 1 +hamdist 2^120 2^120 + = 0 +hamdist 2^120 (2^120-1) + = 121 +hamdist 2^120 2^300 + = 2 +hamdist (2^120-1) (2^300-1) + = 180 +hash(2^120) + = 691199303 +hash(2^121) + = 382412560 +hash(2^300) + = 61759632 +2^120 = 2^300 + = false +2^120 = 2^120 + = true +2^120 = 2^120 + = true +2^120 > 2^300 + = false +2^120 < 2^300 + = true +2^120 = 1 + = false +2^120 > 1 + = true +2^120 < 1 + = false +-2^120 > 1 + = false +-2^120 < 1 + = true +demarshal 2^120, 2^300, 1 + = 1329227995784915872903807060280344576, 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, 1 +demarshal -2^120, -2^300, -1 + = -1329227995784915872903807060280344576, -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, -1 +format %i 0 = /0/ +format %i 1 = /1/ +format %i -1 = /-1/ +format %i 2^30 = /1073741824/ +format %i -2^30 = /-1073741824/ +format % i 1 = / 1/ +format %+i 1 = /+1/ +format %x 0 = /0/ +format %x 1 = /1/ +format %x -1 = /-1/ +format %x 2^30 = /40000000/ +format %x -2^30 = /-40000000/ +format %X 0 = /0/ +format %X 1 = /1/ +format %X -1 = /-1/ +format %X 2^30 = /40000000/ +format %X -2^30 = /-40000000/ +format %o 0 = /0/ +format %o 1 = /1/ +format %o -1 = /-1/ +format %o 2^30 = /10000000000/ +format %o -2^30 = /-10000000000/ +format %10i 0 = / 0/ +format %10i 1 = / 1/ +format %10i -1 = / -1/ +format %10i 2^30 = /1073741824/ +format %10i -2^30 = /-1073741824/ +format %-10i 0 = /0 / +format %-10i 1 = /1 / +format %-10i -1 = /-1 / +format %-10i 2^30 = /1073741824/ +format %-10i -2^30 = /-1073741824/ +format %+10i 0 = / +0/ +format %+10i 1 = / +1/ +format %+10i -1 = / -1/ +format %+10i 2^30 = /+1073741824/ +format %+10i -2^30 = /-1073741824/ +format % 10i 0 = / 0/ +format % 10i 1 = / 1/ +format % 10i -1 = / -1/ +format % 10i 2^30 = / 1073741824/ +format % 10i -2^30 = /-1073741824/ +format %010i 0 = /0000000000/ +format %010i 1 = /0000000001/ +format %010i -1 = /-000000001/ +format %010i 2^30 = /1073741824/ +format %010i -2^30 = /-1073741824/ +format %#x 0 = /0x0/ +format %#x 1 = /0x1/ +format %#x -1 = /-0x1/ +format %#x 2^30 = /0x40000000/ +format %#x -2^30 = /-0x40000000/ +format %#X 0 = /0X0/ +format %#X 1 = /0X1/ +format %#X -1 = /-0X1/ +format %#X 2^30 = /0X40000000/ +format %#X -2^30 = /-0X40000000/ +format %#o 0 = /0o0/ +format %#o 1 = /0o1/ +format %#o -1 = /-0o1/ +format %#o 2^30 = /0o10000000000/ +format %#o -2^30 = /-0o10000000000/ +format %#10x 0 = / 0x0/ +format %#10x 1 = / 0x1/ +format %#10x -1 = / -0x1/ +format %#10x 2^30 = /0x40000000/ +format %#10x -2^30 = /-0x40000000/ +format %#10X 0 = / 0X0/ +format %#10X 1 = / 0X1/ +format %#10X -1 = / -0X1/ +format %#10X 2^30 = /0X40000000/ +format %#10X -2^30 = /-0X40000000/ +format %#10o 0 = / 0o0/ +format %#10o 1 = / 0o1/ +format %#10o -1 = / -0o1/ +format %#10o 2^30 = /0o10000000000/ +format %#10o -2^30 = /-0o10000000000/ +format %#-10x 0 = /0x0 / +format %#-10x 1 = /0x1 / +format %#-10x -1 = /-0x1 / +format %#-10x 2^30 = /0x40000000/ +format %#-10x -2^30 = /-0x40000000/ +format %#-10X 0 = /0X0 / +format %#-10X 1 = /0X1 / +format %#-10X -1 = /-0X1 / +format %#-10X 2^30 = /0X40000000/ +format %#-10X -2^30 = /-0X40000000/ +format %#-10o 0 = /0o0 / +format %#-10o 1 = /0o1 / +format %#-10o -1 = /-0o1 / +format %#-10o 2^30 = /0o10000000000/ +format %#-10o -2^30 = /-0o10000000000/ +extract 42 0 1 = 0 (passed) +extract 42 0 5 = 10 (passed) +extract 42 0 32 = 42 (passed) +extract 42 0 64 = 42 (passed) +extract 42 1 1 = 1 (passed) +extract 42 1 5 = 21 (passed) +extract 42 1 32 = 21 (passed) +extract 42 1 63 = 21 (passed) +extract 42 1 64 = 21 (passed) +extract 42 1 127 = 21 (passed) +extract 42 1 128 = 21 (passed) +extract 42 69 12 = 0 (passed) +extract -42 0 1 = 0 (passed) +extract -42 0 5 = 22 (passed) +extract -42 0 32 = 4294967254 (passed) +extract -42 0 64 = 18446744073709551574 (passed) +extract -42 1 1 = 1 (passed) +extract -42 1 5 = 11 (passed) +extract -42 1 32 = 4294967275 (passed) +extract -42 1 63 = 9223372036854775787 (passed) +extract -42 1 64 = 18446744073709551595 (passed) +extract -42 1 127 = 170141183460469231731687303715884105707 (passed) +extract -42 1 128 = 340282366920938463463374607431768211435 (passed) +extract -42 69 12 = 4095 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 0 1 = 1 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 0 64 = 15536040655639606317 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 128 1 = 1 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 128 5 = 19 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 131 32 = 2516587394 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 175 63 = 7690089207107781587 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 277 123 = 9888429935207999867003931753264634841 (passed) +signed_extract 42 0 1 = 0 (passed) +signed_extract 42 0 5 = 10 (passed) +signed_extract 42 0 32 = 42 (passed) +signed_extract 42 0 64 = 42 (passed) +signed_extract 42 1 1 = -1 (passed) +signed_extract 42 1 5 = -11 (passed) +signed_extract 42 1 32 = 21 (passed) +signed_extract 42 1 63 = 21 (passed) +signed_extract 42 1 64 = 21 (passed) +signed_extract 42 1 127 = 21 (passed) +signed_extract 42 1 128 = 21 (passed) +signed_extract 42 69 12 = 0 (passed) +signed_extract -42 0 1 = 0 (passed) +signed_extract -42 0 5 = -10 (passed) +signed_extract -42 0 32 = -42 (passed) +signed_extract -42 0 64 = -42 (passed) +signed_extract -42 1 1 = -1 (passed) +signed_extract -42 1 5 = 11 (passed) +signed_extract -42 1 32 = -21 (passed) +signed_extract -42 1 63 = -21 (passed) +signed_extract -42 1 64 = -21 (passed) +signed_extract -42 1 127 = -21 (passed) +signed_extract -42 1 128 = -21 (passed) +signed_extract -42 69 12 = -1 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 0 1 = -1 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 0 64 = -2910703418069945299 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 128 1 = -1 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 128 5 = -13 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 131 32 = -1778379902 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 175 63 = -1533282829746994221 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 277 123 = -745394031071327116226524728978121767 (passed) +to_bits 0 + = +marshal round trip 0 + = OK +to_bits 2 + = 02 00 00 00 +marshal round trip 2 + = OK +to_bits -2 + = 02 00 00 00 +marshal round trip -2 + = OK +to_bits 1073741824 + = 00 00 00 40 +marshal round trip 1073741824 + = OK +to_bits -1073741824 + = 00 00 00 40 +marshal round trip -1073741824 + = OK +to_bits 4611686018427387904 + = 00 00 00 00 00 00 00 40 +marshal round trip 4611686018427387904 + = OK +to_bits -4611686018427387904 + = 00 00 00 00 00 00 00 40 +marshal round trip -4611686018427387904 + = OK +to_bits 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 +marshal round trip 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 + = OK +to_bits 1329227995784915872903807060280344576 + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 +marshal round trip 1329227995784915872903807060280344576 + = OK +to_bits 2658455991569831745807614120560689152 + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 +marshal round trip 2658455991569831745807614120560689152 + = OK +to_bits 1073741823 + = ff ff ff 3f +marshal round trip 1073741823 + = OK +to_bits -1073741824 + = 00 00 00 40 +marshal round trip -1073741824 + = OK +to_bits 2147483647 + = ff ff ff 7f +marshal round trip 2147483647 + = OK +to_bits -2147483648 + = 00 00 00 80 +marshal round trip -2147483648 + = OK +to_bits 9223372036854775807 + = ff ff ff ff ff ff ff 7f +marshal round trip 9223372036854775807 + = OK +to_bits -9223372036854775808 + = 00 00 00 00 00 00 00 80 +marshal round trip -9223372036854775808 + = OK +to_bits 2147483647 + = ff ff ff 7f +marshal round trip 2147483647 + = OK +to_bits -2147483648 + = 00 00 00 80 +marshal round trip -2147483648 + = OK +testbit 0 (passed) +testbit 1 (passed) +testbit -42 (passed) +testbit 31415926535897932384626433832795028841971693993751058209749445923078164062862089986 (passed) +testbit -2277361236363886404304896 (passed) +numbits / trailing_zeros 0 (passed) +numbits / trailing_zeros 1 (passed) +numbits / trailing_zeros -42 (passed) +numbits / trailing_zeros 1511006158790834639735881728 (passed) +numbits / trailing_zeros -2277361236363886404304896 (passed) +- 0 = 0 +- 1 = -1 +- -1 = 1 +- +inf = -inf +- -inf = +inf +- undef = undef +1/ 0 = +inf +1/ 1 = 1 +1/ -1 = -1 +1/ +inf = 0 +1/ -inf = 0 +1/ undef = undef +abs 0 = 0 +abs 1 = 1 +abs -1 = 1 +abs +inf = +inf +abs -inf = +inf +abs undef = undef +0 + 0 = 0 +0 + 1 = 1 +0 + -1 = -1 +0 + +inf = +inf +0 + -inf = -inf +0 + undef = undef +1 + 0 = 1 +1 + 1 = 2 +1 + -1 = 0 +1 + +inf = +inf +1 + -inf = -inf +1 + undef = undef +-1 + 0 = -1 +-1 + 1 = 0 +-1 + -1 = -2 +-1 + +inf = +inf +-1 + -inf = -inf +-1 + undef = undef ++inf + 0 = +inf ++inf + 1 = +inf ++inf + -1 = +inf ++inf + +inf = +inf ++inf + -inf = undef ++inf + undef = undef +-inf + 0 = -inf +-inf + 1 = -inf +-inf + -1 = -inf +-inf + +inf = undef +-inf + -inf = -inf +-inf + undef = undef +undef + 0 = undef +undef + 1 = undef +undef + -1 = undef +undef + +inf = undef +undef + -inf = undef +undef + undef = undef +0 - 0 = 0 +0 - 1 = -1 +0 - -1 = 1 +0 - +inf = -inf +0 - -inf = +inf +0 - undef = undef +1 - 0 = 1 +1 - 1 = 0 +1 - -1 = 2 +1 - +inf = -inf +1 - -inf = +inf +1 - undef = undef +-1 - 0 = -1 +-1 - 1 = -2 +-1 - -1 = 0 +-1 - +inf = -inf +-1 - -inf = +inf +-1 - undef = undef ++inf - 0 = +inf ++inf - 1 = +inf ++inf - -1 = +inf ++inf - +inf = undef ++inf - -inf = +inf ++inf - undef = undef +-inf - 0 = -inf +-inf - 1 = -inf +-inf - -1 = -inf +-inf - +inf = -inf +-inf - -inf = undef +-inf - undef = undef +undef - 0 = undef +undef - 1 = undef +undef - -1 = undef +undef - +inf = undef +undef - -inf = undef +undef - undef = undef +0 * 0 = 0 +0 * 1 = 0 +0 * -1 = 0 +0 * +inf = undef +0 * -inf = undef +0 * undef = undef +1 * 0 = 0 +1 * 1 = 1 +1 * -1 = -1 +1 * +inf = +inf +1 * -inf = -inf +1 * undef = undef +-1 * 0 = 0 +-1 * 1 = -1 +-1 * -1 = 1 +-1 * +inf = -inf +-1 * -inf = +inf +-1 * undef = undef ++inf * 0 = undef ++inf * 1 = +inf ++inf * -1 = -inf ++inf * +inf = +inf ++inf * -inf = -inf ++inf * undef = undef +-inf * 0 = undef +-inf * 1 = -inf +-inf * -1 = +inf +-inf * +inf = -inf +-inf * -inf = +inf +-inf * undef = undef +undef * 0 = undef +undef * 1 = undef +undef * -1 = undef +undef * +inf = undef +undef * -inf = undef +undef * undef = undef +0 / 0 = undef +0 / 1 = 0 +0 / -1 = 0 +0 / +inf = 0 +0 / -inf = 0 +0 / undef = undef +1 / 0 = +inf +1 / 1 = 1 +1 / -1 = -1 +1 / +inf = 0 +1 / -inf = 0 +1 / undef = undef +-1 / 0 = -inf +-1 / 1 = -1 +-1 / -1 = 1 +-1 / +inf = 0 +-1 / -inf = 0 +-1 / undef = undef ++inf / 0 = +inf ++inf / 1 = +inf ++inf / -1 = -inf ++inf / +inf = undef ++inf / -inf = undef ++inf / undef = undef +-inf / 0 = -inf +-inf / 1 = -inf +-inf / -1 = +inf +-inf / +inf = undef +-inf / -inf = undef +-inf / undef = undef +undef / 0 = undef +undef / 1 = undef +undef / -1 = undef +undef / +inf = undef +undef / -inf = undef +undef / undef = undef +0 * 1/ 0 = undef +0 * 1/ 1 = 0 +0 * 1/ -1 = 0 +0 * 1/ +inf = 0 +0 * 1/ -inf = 0 +0 * 1/ undef = undef +1 * 1/ 0 = +inf +1 * 1/ 1 = 1 +1 * 1/ -1 = -1 +1 * 1/ +inf = 0 +1 * 1/ -inf = 0 +1 * 1/ undef = undef +-1 * 1/ 0 = -inf +-1 * 1/ 1 = -1 +-1 * 1/ -1 = 1 +-1 * 1/ +inf = 0 +-1 * 1/ -inf = 0 +-1 * 1/ undef = undef ++inf * 1/ 0 = +inf ++inf * 1/ 1 = +inf ++inf * 1/ -1 = -inf ++inf * 1/ +inf = undef ++inf * 1/ -inf = undef ++inf * 1/ undef = undef +-inf * 1/ 0 = -inf +-inf * 1/ 1 = -inf +-inf * 1/ -1 = +inf +-inf * 1/ +inf = undef +-inf * 1/ -inf = undef +-inf * 1/ undef = undef +undef * 1/ 0 = undef +undef * 1/ 1 = undef +undef * 1/ -1 = undef +undef * 1/ +inf = undef +undef * 1/ -inf = undef +undef * 1/ undef = undef +mul_2exp (1) 0 = 0 +mul_2exp (1) 1 = 2 +mul_2exp (1) -1 = -2 +mul_2exp (1) +inf = +inf +mul_2exp (1) -inf = -inf +mul_2exp (1) undef = undef +mul_2exp (2) 0 = 0 +mul_2exp (2) 1 = 4 +mul_2exp (2) -1 = -4 +mul_2exp (2) +inf = +inf +mul_2exp (2) -inf = -inf +mul_2exp (2) undef = undef +div_2exp (1) 0 = 0 +div_2exp (1) 1 = 1/2 +div_2exp (1) -1 = -1/2 +div_2exp (1) +inf = +inf +div_2exp (1) -inf = -inf +div_2exp (1) undef = undef +div_2exp (2) 0 = 0 +div_2exp (2) 1 = 1/4 +div_2exp (2) -1 = -1/4 +div_2exp (2) +inf = +inf +div_2exp (2) -inf = -inf +div_2exp (2) undef = undef +identity checking 0 0 +identity checking 0 1 +identity checking 0 -1 +identity checking 0 +inf +identity checking 0 -inf +identity checking 0 undef +identity checking 1 0 +identity checking 1 1 +identity checking 1 -1 +identity checking 1 +inf +identity checking 1 -inf +identity checking 1 undef +identity checking -1 0 +identity checking -1 1 +identity checking -1 -1 +identity checking -1 +inf +identity checking -1 -inf +identity checking -1 undef +identity checking +inf 0 +identity checking +inf 1 +identity checking +inf -1 +identity checking +inf +inf +identity checking +inf -inf +identity checking +inf undef +identity checking -inf 0 +identity checking -inf 1 +identity checking -inf -1 +identity checking -inf +inf +identity checking -inf -inf +identity checking -inf undef +identity checking undef 0 +identity checking undef 1 +identity checking undef -1 +identity checking undef +inf +identity checking undef -inf +identity checking undef undef diff --git a/tests/zq.output-MPIR-64-64 b/tests/zq.output-MPIR-64-64 new file mode 100644 index 0000000..5c09e7e --- /dev/null +++ b/tests/zq.output-MPIR-64-64 @@ -0,0 +1,1373 @@ +0 + = 0 +1 + = 1 +-1 + = -1 +42 + = 42 +1+1 + = 2 +1-1 + = 0 +- 1 + = -1 +0-1 + = -1 +max_int + = 4611686018427387903 +min_int + = -4611686018427387904 +-max_int + = -4611686018427387903 +-min_int + = 4611686018427387904 +2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^120 + = 1329227995784915872903807060280344576 +2^300+2^120 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300-2^120 + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +2^300+(-(2^120)) + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +2^120-2^300 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +2^120+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-(2^120)+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +-(2^120)-2^300 + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300-2^300 + = 0 +2^121 + = 2658455991569831745807614120560689152 +2^121+2^120 + = 3987683987354747618711421180841033728 +2^121-2^120 + = 1329227995784915872903807060280344576 +2^121+(-(2^120)) + = 1329227995784915872903807060280344576 +2^120-2^121 + = -1329227995784915872903807060280344576 +2^120+(-(2^121)) + = -1329227995784915872903807060280344576 +-(2^120)+(-(2^121)) + = -3987683987354747618711421180841033728 +-(2^120)-2^121 + = -3987683987354747618711421180841033728 +2^121+0 + = 2658455991569831745807614120560689152 +2^121-0 + = 2658455991569831745807614120560689152 +0+2^121 + = 2658455991569831745807614120560689152 +0-2^121 + = -2658455991569831745807614120560689152 +2^300+1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +2^300-1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +1+2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +1-2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +2^300+(-1) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +2^300-(-1) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +(-1)+2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +(-1)-2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)+1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +-(2^300)-1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +1+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +1-(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)+(-1) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)-(-1) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +(-1)+(-(2^300)) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +(-1)-(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +max_int+1 + = 4611686018427387904 +min_int-1 + = -4611686018427387905 +-max_int-1 + = -4611686018427387904 +-min_int-1 + = 4611686018427387903 +5! = 120 +12! = 479001600 +15! = 1307674368000 +20! = 2432902008176640000 +25! = 15511210043330985984000000 +50! = 30414093201713378043612608166064768844377641568960512000000000000 +2^300*2^120 + = 2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^120*2^300 + = 2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^300*(-(2^120)) + = -2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^120*(-(2^300)) + = -2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +-(2^120)*(-(2^300)) + = 2707685248164858261307045101702230179137145581421695874189921465443966120903931272499975005961073806735733604454495675614232576 +2^121*2^120 + = 3533694129556768659166595001485837031654967793751237916243212402585239552 +2^120*2^121 + = 3533694129556768659166595001485837031654967793751237916243212402585239552 +2^121*0 + = 0 +0*2^121 + = 0 +2^300*1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1*2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^300*(-1) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +(-1)*2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-(2^300)*1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1*(-(2^300)) + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-(2^300)*(-1) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +(-1)*(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1*(2^30) + = 1073741824 +1*(2^62) + = 4611686018427387904 +(2^30)*(2^30) + = 1152921504606846976 +(2^62)*(2^62) + = 21267647932558653966460912964485513216 +0+1 + = 1 +1+1 + = 2 +-1+1 + = 0 +2+1 + = 3 +-2+1 + = -1 +(2^300)+1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +-(2^300)+1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +0-1 + = -1 +1-1 + = 0 +-1-1 + = -2 +2-1 + = 1 +-2-1 + = -3 +(2^300)-1 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +-(2^300)-1 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +max_int+1 + = 4611686018427387904 +min_int-1 + = -4611686018427387905 +-max_int-1 + = -4611686018427387904 +-min_int-1 + = 4611686018427387903 +abs(0) + = 0 +abs(1) + = 1 +abs(-1) + = 1 +abs(min_int) + = 4611686018427387904 +abs(2^300) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +abs(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +max_natint + = 9223372036854775807 +max_int32 + = 2147483647 +max_int64 + = 9223372036854775807 +to_int 1 + = 1 +to_int max_int + = 4611686018427387903 +to_int max_natint + = ovf +to_int max_int32 + = 2147483647 +to_int max_int64 + = ovf +to_int32 1 + = 1 +to_int32 max_int + = ovf +to_int32 max_natint + = ovf +to_int32 max_int32 + = 2147483647 +to_int32 max_int64 + = ovf +to_int64 1 + = 1 +to_int64 max_int + = 4611686018427387903 +to_int64 max_natint + = 9223372036854775807 +to_int64 max_int32 + = 2147483647 +to_int64 max_int64 + = 9223372036854775807 +to_natint 1 + = 1 +to_natint max_int + = 4611686018427387903 +to_natint max_natint + = 9223372036854775807 +to_natint max_int32 + = 2147483647 +to_natint max_int64 + = 9223372036854775807 +to_int -min_int + = ovf +to_int -min_natint + = ovf +to_int -min_int32 + = 2147483648 +to_int -min_int64 + = ovf +to_int32 -min_int + = ovf +to_int32 -min_natint + = ovf +to_int32 -min_int32 + = ovf +to_int32 -min_int64 + = ovf +to_int64 -min_int + = 4611686018427387904 +to_int64 -min_natint + = ovf +to_int64 -min_int32 + = 2147483648 +to_int64 -min_int64 + = ovf +to_natint -min_int + = 4611686018427387904 +to_natint -min_natint + = ovf +to_natint -min_int32 + = 2147483648 +to_natint -min_int64 + = ovf +of_float 1. + = 1 +of_float -1. + = -1 +of_float pi + = 3 +of_float 2^30 + = 1073741824 +of_float 2^31 + = 2147483648 +of_float 2^32 + = 4294967296 +of_float 2^33 + = 8589934592 +of_float -2^30 + = -1073741824 +of_float -2^31 + = -2147483648 +of_float -2^32 + = -4294967296 +of_float -2^33 + = -8589934592 +of_float 2^61 + = 2305843009213693952 +of_float 2^62 + = 4611686018427387904 +of_float 2^63 + = 9223372036854775808 +of_float 2^64 + = 18446744073709551616 +of_float 2^65 + = 36893488147419103232 +of_float -2^61 + = -2305843009213693952 +of_float -2^62 + = -4611686018427387904 +of_float -2^63 + = -9223372036854775808 +of_float -2^64 + = -18446744073709551616 +of_float -2^65 + = -36893488147419103232 +of_float 2^120 + = 1329227995784915872903807060280344576 +of_float 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +of_float -2^120 + = -1329227995784915872903807060280344576 +of_float -2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +of_float 0.5 + = 0 +of_float -0.5 + = 0 +of_float 200.5 + = 200 +of_float -200.5 + = -200 +to_float 0 + = OK +to_float 1 + = OK +to_float -1 + = OK +to_float 2^120 + = OK +to_float -2^120 + = OK +to_float (2^120-1) + = OK +to_float (-2^120+1) + = OK +to_float 2^63 + = OK +to_float -2^63 + = OK +to_float (2^63-1) + = OK +to_float (-2^63-1) + = OK +to_float (-2^63+1) + = OK +to_float 2^300 + = OK +to_float -2^300 + = OK +to_float (2^300-1) + = OK +to_float (-2^300+1) + = OK +of_string 12 + = 12 +of_string 0x12 + = 18 +of_string 0b10 + = 2 +of_string 0o12 + = 10 +of_string -12 + = -12 +of_string -0x12 + = -18 +of_string -0b10 + = -2 +of_string -0o12 + = -10 +of_string 000123456789012345678901234567890 + = 123456789012345678901234567890 +2^120 / 2^300 (trunc) + = 0 +max_int / 2 (trunc) + = 2305843009213693951 +(2^300+1) / 2^120 (trunc) + = 1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / 2^120 (trunc) + = -1532495540865888858358347027150309183618739122183602176 +(2^300+1) / (-(2^120)) (trunc) + = -1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / (-(2^120)) (trunc) + = 1532495540865888858358347027150309183618739122183602176 +2^120 / 2^300 (ceil) + = 1 +max_int / 2 (ceil) + = 2305843009213693952 +(2^300+1) / 2^120 (ceil) + = 1532495540865888858358347027150309183618739122183602177 +(-(2^300+1)) / 2^120 (ceil) + = -1532495540865888858358347027150309183618739122183602176 +(2^300+1) / (-(2^120)) (ceil) + = -1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / (-(2^120)) (ceil) + = 1532495540865888858358347027150309183618739122183602177 +2^120 / 2^300 (floor) + = 0 +max_int / 2 (floor) + = 2305843009213693951 +(2^300+1) / 2^120 (floor) + = 1532495540865888858358347027150309183618739122183602176 +(-(2^300+1)) / 2^120 (floor) + = -1532495540865888858358347027150309183618739122183602177 +(2^300+1) / (-(2^120)) (floor) + = -1532495540865888858358347027150309183618739122183602177 +(-(2^300+1)) / (-(2^120)) (floor) + = 1532495540865888858358347027150309183618739122183602176 +2^120 % 2^300 + = 1329227995784915872903807060280344576 +max_int % 2 + = 1 +(2^300+1) % 2^120 + = 1 +(-(2^300+1)) % 2^120 + = -1 +(2^300+1) % (-(2^120)) + = 1 +(-(2^300+1)) % (-(2^120)) + = -1 +2^120 /,% 2^300 + = 0, 1329227995784915872903807060280344576 +max_int /,% 2 + = 2305843009213693951, 1 +(2^300+1) /,% 2^120 + = 1532495540865888858358347027150309183618739122183602176, 1 +(-(2^300+1)) /,% 2^120 + = -1532495540865888858358347027150309183618739122183602176, -1 +(2^300+1) /,% (-(2^120)) + = -1532495540865888858358347027150309183618739122183602176, 1 +(-(2^300+1)) /,% (-(2^120)) + = 1532495540865888858358347027150309183618739122183602176, -1 +1 & 2 + = 0 +1 & 2^300 + = 0 +2^120 & 2^300 + = 0 +2^300 & 2^120 + = 0 +2^300 & 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^300 & 0 + = 0 +-2^120 & 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 + 2^120 & -2^300 + = 0 +-2^120 & -2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^300 & 2^120 + = 0 + 2^300 & -2^120 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^300 & -2^120 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +1 | 2 + = 3 +1 | 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +2^120 | 2^300 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 | 2^120 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 | 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^300 | 0 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^120 | 2^300 + = -1329227995784915872903807060280344576 + 2^120 | -2^300 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-2^120 | -2^300 + = -1329227995784915872903807060280344576 +-2^300 | 2^120 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 + 2^300 | -2^120 + = -1329227995784915872903807060280344576 +-2^300 | -2^120 + = -1329227995784915872903807060280344576 +1 ^ 2 + = 3 +1 ^ 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +2^120 ^ 2^300 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 ^ 2^120 + = 2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +2^300 ^ 2^300 + = 0 +2^300 ^ 0 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +-2^120 ^ 2^300 + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 + 2^120 ^ -2^300 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-2^120 ^ -2^300 + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +-2^300 ^ 2^120 + = -2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 + 2^300 ^ -2^120 + = -2037035976334486086268445688409378161051468393665936251965368445139297172667143766463741952 +-2^300 ^ -2^120 + = 2037035976334486086268445688409378161051468393665936249306912453569465426859529645903052800 +~0 + = -1 +~1 + = -2 +~2 + = -3 +~2^300 + = -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397377 +~(-1) + = 0 +~(-2) + = 1 +~(-(2^300)) + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397375 +0 >> 1 + = 0 +0 >> 100 + = 0 +2 >> 1 + = 1 +2 >> 2 + = 0 +2 >> 100 + = 0 +2^300 >> 1 + = 1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +2^300 >> 2 + = 509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +2^300 >> 100 + = 1606938044258990275541962092341162602522202993782792835301376 +2^300 >> 200 + = 1267650600228229401496703205376 +2^300 >> 300 + = 1 +2^300 >> 400 + = 0 +-1 >> 1 + = -1 +-2 >> 1 + = -1 +-2 >> 2 + = -1 +-2 >> 100 + = -1 +-2^300 >> 1 + = -1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +-2^300 >> 2 + = -509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +-2^300 >> 100 + = -1606938044258990275541962092341162602522202993782792835301376 +-2^300 >> 200 + = -1267650600228229401496703205376 +-2^300 >> 300 + = -1 +-2^300 >> 400 + = -1 +0 >>0 1 + = 0 +0 >>0 100 + = 0 +2 >>0 1 + = 1 +2 >>0 2 + = 0 +2 >>0 100 + = 0 +2^300 >>0 1 + = 1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +2^300 >>0 2 + = 509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +2^300 >>0 100 + = 1606938044258990275541962092341162602522202993782792835301376 +2^300 >>0 200 + = 1267650600228229401496703205376 +2^300 >>0 300 + = 1 +2^300 >>0 400 + = 0 +-1 >>0 1 + = 0 +-2 >>0 1 + = -1 +-2 >>0 2 + = 0 +-2 >>0 100 + = 0 +-2^300 >>0 1 + = -1018517988167243043134222844204689080525734196832968125318070224677190649881668353091698688 +-2^300 >>0 2 + = -509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344 +-2^300 >>0 100 + = -1606938044258990275541962092341162602522202993782792835301376 +-2^300 >>0 200 + = -1267650600228229401496703205376 +-2^300 >>0 300 + = -1 +-2^300 >>0 400 + = 0 +0 << 1 + = 0 +0 << 100 + = 0 +2 << 1 + = 4 +2 << 32 + = 8589934592 +2 << 64 + = 36893488147419103232 +2 << 299 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +2^120 << 1 + = 2658455991569831745807614120560689152 +2^120 << 180 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +compare 1 2 + = -1 +compare 1 1 + = 0 +compare 2 1 + = 1 +compare 2^300 2^120 + = 1 +compare 2^120 2^120 + = 0 +compare 2^120 2^300 + = -1 +compare 2^121 2^120 + = 1 +compare 2^120 2^121 + = -1 +compare 2^300 -2^120 + = 1 +compare 2^120 -2^120 + = 1 +compare 2^120 -2^300 + = 1 +compare -2^300 2^120 + = -1 +compare -2^120 2^120 + = -1 +compare -2^120 2^300 + = -1 +compare -2^300 -2^120 + = -1 +compare -2^120 -2^120 + = 0 +compare -2^120 -2^300 + = 1 +equal 1 2 + = false +equal 1 1 + = true +equal 2 1 + = false +equal 2^300 2^120 + = false +equal 2^120 2^120 + = true +equal 2^120 2^300 + = false +equal 2^121 2^120 + = false +equal 2^120 2^121 + = false +equal 2^120 -2^120 + = false +equal -2^120 2^120 + = false +equal -2^120 -2^120 + = true +sign 0 + = 0 +sign 1 + = 1 +sign -1 + = -1 +sign 2^300 + = 1 +sign -2^300 + = -1 +gcd 0 0 + = 0 +gcd 0 -137 + = 137 +gcd 12 27 + = 3 +gcd 27 12 + = 3 +gcd 27 27 + = 27 +gcd -12 27 + = 3 +gcd 12 -27 + = 3 +gcd -12 -27 + = 3 +gcd 0 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +gcd 2^120 2^300 + = 1329227995784915872903807060280344576 +gcd 2^300 2^120 + = 1329227995784915872903807060280344576 +gcd 0 -2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +gcd 2^120 -2^300 + = 1329227995784915872903807060280344576 +gcd 2^300 -2^120 + = 1329227995784915872903807060280344576 +gcd -2^120 2^300 + = 1329227995784915872903807060280344576 +gcd -2^300 2^120 + = 1329227995784915872903807060280344576 +gcd -2^120 -2^300 + = 1329227995784915872903807060280344576 +gcd -2^300 -2^120 + = 1329227995784915872903807060280344576 +gcdext 12 27 + = 3, -2, 1 +gcdext 27 12 + = 3, 1, -2 +gcdext 27 27 + = 27, 0, 1 +gcdext -12 27 + = 3, 2, 1 +gcdext 12 -27 + = 3, -2, -1 +gcdext -12 -27 + = 3, 2, -1 +gcdext 2^120 2^300 + = 1329227995784915872903807060280344576, 1, 0 +gcdext 2^300 2^120 + = 1329227995784915872903807060280344576, 0, 1 +gcdext 12 0 + = 12, 1, 0 +gcdext 0 27 + = 27, 0, 1 +gcdext -12 0 + = 12, -1, 0 +gcdext 0 -27 + = 27, 0, -1 +gcdext 2^120 0 + = 1329227995784915872903807060280344576, 1, 0 +gcdext 0 2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, 0, 1 +gcdext -2^120 0 + = 1329227995784915872903807060280344576, -1, 0 +gcdext 0 -2^300 + = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, 0, -1 +gcdext 0 0 + = 0, 0, 0 +lcm 0 0 = 0 +lcm 10 12 = 60 +lcm -10 12 = 60 +lcm 10 -12 = 60 +lcm -10 -12 = 60 +lcm 0 12 = 0 +lcm 0 -12 = 0 +lcm 10 0 = 0 +lcm -10 0 = 0 +lcm 2^120 2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm 2^120 -2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm -2^120 2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm -2^120 -2^300 = 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 +lcm 2^120 0 = 0 +lcm -2^120 0 = 0 +is_odd 0 + = false +is_odd 1 + = true +is_odd 2 + = false +is_odd 3 + = true +is_odd 2^120 + = false +is_odd 2^120+1 + = true +is_odd 2^300 + = false +is_odd 2^300+1 + = true +sqrt 0 + = 0 +sqrt 1 + = 1 +sqrt 2 + = 1 +sqrt 2^120 + = 1152921504606846976 +sqrt 2^121 + = 1630477228166597776 +sqrt_rem 0 + = 0, 0 +sqrt_rem 1 + = 1, 0 +sqrt_rem 2 + = 1, 1 +sqrt_rem 2^120 + = 1152921504606846976, 0 +sqrt_rem 2^121 + = 1630477228166597776, 1772969445592542976 +popcount 0 + = 0 +popcount 1 + = 1 +popcount 2 + = 1 +popcount max_int32 + = 31 +popcount 2^120 + = 1 +popcount (2^120-1) + = 120 +hamdist 0 0 + = 0 +hamdist 0 1 + = 1 +hamdist 0 2^300 + = 1 +hamdist 2^120 2^120 + = 0 +hamdist 2^120 (2^120-1) + = 121 +hamdist 2^120 2^300 + = 2 +hamdist (2^120-1) (2^300-1) + = 180 +hash(2^120) + = 691199303 +hash(2^121) + = 382412560 +hash(2^300) + = 61759632 +2^120 = 2^300 + = false +2^120 = 2^120 + = true +2^120 = 2^120 + = true +2^120 > 2^300 + = false +2^120 < 2^300 + = true +2^120 = 1 + = false +2^120 > 1 + = true +2^120 < 1 + = false +-2^120 > 1 + = false +-2^120 < 1 + = true +demarshal 2^120, 2^300, 1 + = 1329227995784915872903807060280344576, 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, 1 +demarshal -2^120, -2^300, -1 + = -1329227995784915872903807060280344576, -2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376, -1 +format %i 0 = /0/ +format %i 1 = /1/ +format %i -1 = /-1/ +format %i 2^30 = /1073741824/ +format %i -2^30 = /-1073741824/ +format % i 1 = / 1/ +format %+i 1 = /+1/ +format %x 0 = /0/ +format %x 1 = /1/ +format %x -1 = /-1/ +format %x 2^30 = /40000000/ +format %x -2^30 = /-40000000/ +format %X 0 = /0/ +format %X 1 = /1/ +format %X -1 = /-1/ +format %X 2^30 = /40000000/ +format %X -2^30 = /-40000000/ +format %o 0 = /0/ +format %o 1 = /1/ +format %o -1 = /-1/ +format %o 2^30 = /10000000000/ +format %o -2^30 = /-10000000000/ +format %10i 0 = / 0/ +format %10i 1 = / 1/ +format %10i -1 = / -1/ +format %10i 2^30 = /1073741824/ +format %10i -2^30 = /-1073741824/ +format %-10i 0 = /0 / +format %-10i 1 = /1 / +format %-10i -1 = /-1 / +format %-10i 2^30 = /1073741824/ +format %-10i -2^30 = /-1073741824/ +format %+10i 0 = / +0/ +format %+10i 1 = / +1/ +format %+10i -1 = / -1/ +format %+10i 2^30 = /+1073741824/ +format %+10i -2^30 = /-1073741824/ +format % 10i 0 = / 0/ +format % 10i 1 = / 1/ +format % 10i -1 = / -1/ +format % 10i 2^30 = / 1073741824/ +format % 10i -2^30 = /-1073741824/ +format %010i 0 = /0000000000/ +format %010i 1 = /0000000001/ +format %010i -1 = /-000000001/ +format %010i 2^30 = /1073741824/ +format %010i -2^30 = /-1073741824/ +format %#x 0 = /0x0/ +format %#x 1 = /0x1/ +format %#x -1 = /-0x1/ +format %#x 2^30 = /0x40000000/ +format %#x -2^30 = /-0x40000000/ +format %#X 0 = /0X0/ +format %#X 1 = /0X1/ +format %#X -1 = /-0X1/ +format %#X 2^30 = /0X40000000/ +format %#X -2^30 = /-0X40000000/ +format %#o 0 = /0o0/ +format %#o 1 = /0o1/ +format %#o -1 = /-0o1/ +format %#o 2^30 = /0o10000000000/ +format %#o -2^30 = /-0o10000000000/ +format %#10x 0 = / 0x0/ +format %#10x 1 = / 0x1/ +format %#10x -1 = / -0x1/ +format %#10x 2^30 = /0x40000000/ +format %#10x -2^30 = /-0x40000000/ +format %#10X 0 = / 0X0/ +format %#10X 1 = / 0X1/ +format %#10X -1 = / -0X1/ +format %#10X 2^30 = /0X40000000/ +format %#10X -2^30 = /-0X40000000/ +format %#10o 0 = / 0o0/ +format %#10o 1 = / 0o1/ +format %#10o -1 = / -0o1/ +format %#10o 2^30 = /0o10000000000/ +format %#10o -2^30 = /-0o10000000000/ +format %#-10x 0 = /0x0 / +format %#-10x 1 = /0x1 / +format %#-10x -1 = /-0x1 / +format %#-10x 2^30 = /0x40000000/ +format %#-10x -2^30 = /-0x40000000/ +format %#-10X 0 = /0X0 / +format %#-10X 1 = /0X1 / +format %#-10X -1 = /-0X1 / +format %#-10X 2^30 = /0X40000000/ +format %#-10X -2^30 = /-0X40000000/ +format %#-10o 0 = /0o0 / +format %#-10o 1 = /0o1 / +format %#-10o -1 = /-0o1 / +format %#-10o 2^30 = /0o10000000000/ +format %#-10o -2^30 = /-0o10000000000/ +extract 42 0 1 = 0 (passed) +extract 42 0 5 = 10 (passed) +extract 42 0 32 = 42 (passed) +extract 42 0 64 = 42 (passed) +extract 42 1 1 = 1 (passed) +extract 42 1 5 = 21 (passed) +extract 42 1 32 = 21 (passed) +extract 42 1 63 = 21 (passed) +extract 42 1 64 = 21 (passed) +extract 42 1 127 = 21 (passed) +extract 42 1 128 = 21 (passed) +extract 42 69 12 = 0 (passed) +extract -42 0 1 = 0 (passed) +extract -42 0 5 = 22 (passed) +extract -42 0 32 = 4294967254 (passed) +extract -42 0 64 = 18446744073709551574 (passed) +extract -42 1 1 = 1 (passed) +extract -42 1 5 = 11 (passed) +extract -42 1 32 = 4294967275 (passed) +extract -42 1 63 = 9223372036854775787 (passed) +extract -42 1 64 = 18446744073709551595 (passed) +extract -42 1 127 = 170141183460469231731687303715884105707 (passed) +extract -42 1 128 = 340282366920938463463374607431768211435 (passed) +extract -42 69 12 = 4095 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 0 1 = 1 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 0 64 = 15536040655639606317 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 128 1 = 1 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 128 5 = 19 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 131 32 = 2516587394 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 175 63 = 7690089207107781587 (passed) +extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 277 123 = 9888429935207999867003931753264634841 (passed) +signed_extract 42 0 1 = 0 (passed) +signed_extract 42 0 5 = 10 (passed) +signed_extract 42 0 32 = 42 (passed) +signed_extract 42 0 64 = 42 (passed) +signed_extract 42 1 1 = -1 (passed) +signed_extract 42 1 5 = -11 (passed) +signed_extract 42 1 32 = 21 (passed) +signed_extract 42 1 63 = 21 (passed) +signed_extract 42 1 64 = 21 (passed) +signed_extract 42 1 127 = 21 (passed) +signed_extract 42 1 128 = 21 (passed) +signed_extract 42 69 12 = 0 (passed) +signed_extract -42 0 1 = 0 (passed) +signed_extract -42 0 5 = -10 (passed) +signed_extract -42 0 32 = -42 (passed) +signed_extract -42 0 64 = -42 (passed) +signed_extract -42 1 1 = -1 (passed) +signed_extract -42 1 5 = 11 (passed) +signed_extract -42 1 32 = -21 (passed) +signed_extract -42 1 63 = -21 (passed) +signed_extract -42 1 64 = -21 (passed) +signed_extract -42 1 127 = -21 (passed) +signed_extract -42 1 128 = -21 (passed) +signed_extract -42 69 12 = -1 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 0 1 = -1 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 0 64 = -2910703418069945299 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 128 1 = -1 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 128 5 = -13 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 131 32 = -1778379902 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 175 63 = -1533282829746994221 (passed) +signed_extract 3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701 277 123 = -745394031071327116226524728978121767 (passed) +to_bits 0 + = +marshal round trip 0 + = OK +to_bits 2 + = 02 00 00 00 00 00 00 00 +marshal round trip 2 + = OK +to_bits -2 + = 02 00 00 00 00 00 00 00 +marshal round trip -2 + = OK +to_bits 1073741824 + = 00 00 00 40 00 00 00 00 +marshal round trip 1073741824 + = OK +to_bits -1073741824 + = 00 00 00 40 00 00 00 00 +marshal round trip -1073741824 + = OK +to_bits 4611686018427387904 + = 00 00 00 00 00 00 00 40 +marshal round trip 4611686018427387904 + = OK +to_bits -4611686018427387904 + = 00 00 00 00 00 00 00 40 +marshal round trip -4611686018427387904 + = OK +to_bits 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 +marshal round trip 2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376 + = OK +to_bits 1329227995784915872903807060280344576 + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 +marshal round trip 1329227995784915872903807060280344576 + = OK +to_bits 2658455991569831745807614120560689152 + = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 +marshal round trip 2658455991569831745807614120560689152 + = OK +to_bits 4611686018427387903 + = ff ff ff ff ff ff ff 3f +marshal round trip 4611686018427387903 + = OK +to_bits -4611686018427387904 + = 00 00 00 00 00 00 00 40 +marshal round trip -4611686018427387904 + = OK +to_bits 2147483647 + = ff ff ff 7f 00 00 00 00 +marshal round trip 2147483647 + = OK +to_bits -2147483648 + = 00 00 00 80 00 00 00 00 +marshal round trip -2147483648 + = OK +to_bits 9223372036854775807 + = ff ff ff ff ff ff ff 7f +marshal round trip 9223372036854775807 + = OK +to_bits -9223372036854775808 + = 00 00 00 00 00 00 00 80 +marshal round trip -9223372036854775808 + = OK +to_bits 9223372036854775807 + = ff ff ff ff ff ff ff 7f +marshal round trip 9223372036854775807 + = OK +to_bits -9223372036854775808 + = 00 00 00 00 00 00 00 80 +marshal round trip -9223372036854775808 + = OK +testbit 0 (passed) +testbit 1 (passed) +testbit -42 (passed) +testbit 31415926535897932384626433832795028841971693993751058209749445923078164062862089986 (passed) +testbit -2277361236363886404304896 (passed) +numbits / trailing_zeros 0 (passed) +numbits / trailing_zeros 1 (passed) +numbits / trailing_zeros -42 (passed) +numbits / trailing_zeros 1511006158790834639735881728 (passed) +numbits / trailing_zeros -2277361236363886404304896 (passed) +- 0 = 0 +- 1 = -1 +- -1 = 1 +- +inf = -inf +- -inf = +inf +- undef = undef +1/ 0 = +inf +1/ 1 = 1 +1/ -1 = -1 +1/ +inf = 0 +1/ -inf = 0 +1/ undef = undef +abs 0 = 0 +abs 1 = 1 +abs -1 = 1 +abs +inf = +inf +abs -inf = +inf +abs undef = undef +0 + 0 = 0 +0 + 1 = 1 +0 + -1 = -1 +0 + +inf = +inf +0 + -inf = -inf +0 + undef = undef +1 + 0 = 1 +1 + 1 = 2 +1 + -1 = 0 +1 + +inf = +inf +1 + -inf = -inf +1 + undef = undef +-1 + 0 = -1 +-1 + 1 = 0 +-1 + -1 = -2 +-1 + +inf = +inf +-1 + -inf = -inf +-1 + undef = undef ++inf + 0 = +inf ++inf + 1 = +inf ++inf + -1 = +inf ++inf + +inf = +inf ++inf + -inf = undef ++inf + undef = undef +-inf + 0 = -inf +-inf + 1 = -inf +-inf + -1 = -inf +-inf + +inf = undef +-inf + -inf = -inf +-inf + undef = undef +undef + 0 = undef +undef + 1 = undef +undef + -1 = undef +undef + +inf = undef +undef + -inf = undef +undef + undef = undef +0 - 0 = 0 +0 - 1 = -1 +0 - -1 = 1 +0 - +inf = -inf +0 - -inf = +inf +0 - undef = undef +1 - 0 = 1 +1 - 1 = 0 +1 - -1 = 2 +1 - +inf = -inf +1 - -inf = +inf +1 - undef = undef +-1 - 0 = -1 +-1 - 1 = -2 +-1 - -1 = 0 +-1 - +inf = -inf +-1 - -inf = +inf +-1 - undef = undef ++inf - 0 = +inf ++inf - 1 = +inf ++inf - -1 = +inf ++inf - +inf = undef ++inf - -inf = +inf ++inf - undef = undef +-inf - 0 = -inf +-inf - 1 = -inf +-inf - -1 = -inf +-inf - +inf = -inf +-inf - -inf = undef +-inf - undef = undef +undef - 0 = undef +undef - 1 = undef +undef - -1 = undef +undef - +inf = undef +undef - -inf = undef +undef - undef = undef +0 * 0 = 0 +0 * 1 = 0 +0 * -1 = 0 +0 * +inf = undef +0 * -inf = undef +0 * undef = undef +1 * 0 = 0 +1 * 1 = 1 +1 * -1 = -1 +1 * +inf = +inf +1 * -inf = -inf +1 * undef = undef +-1 * 0 = 0 +-1 * 1 = -1 +-1 * -1 = 1 +-1 * +inf = -inf +-1 * -inf = +inf +-1 * undef = undef ++inf * 0 = undef ++inf * 1 = +inf ++inf * -1 = -inf ++inf * +inf = +inf ++inf * -inf = -inf ++inf * undef = undef +-inf * 0 = undef +-inf * 1 = -inf +-inf * -1 = +inf +-inf * +inf = -inf +-inf * -inf = +inf +-inf * undef = undef +undef * 0 = undef +undef * 1 = undef +undef * -1 = undef +undef * +inf = undef +undef * -inf = undef +undef * undef = undef +0 / 0 = undef +0 / 1 = 0 +0 / -1 = 0 +0 / +inf = 0 +0 / -inf = 0 +0 / undef = undef +1 / 0 = +inf +1 / 1 = 1 +1 / -1 = -1 +1 / +inf = 0 +1 / -inf = 0 +1 / undef = undef +-1 / 0 = -inf +-1 / 1 = -1 +-1 / -1 = 1 +-1 / +inf = 0 +-1 / -inf = 0 +-1 / undef = undef ++inf / 0 = +inf ++inf / 1 = +inf ++inf / -1 = -inf ++inf / +inf = undef ++inf / -inf = undef ++inf / undef = undef +-inf / 0 = -inf +-inf / 1 = -inf +-inf / -1 = +inf +-inf / +inf = undef +-inf / -inf = undef +-inf / undef = undef +undef / 0 = undef +undef / 1 = undef +undef / -1 = undef +undef / +inf = undef +undef / -inf = undef +undef / undef = undef +0 * 1/ 0 = undef +0 * 1/ 1 = 0 +0 * 1/ -1 = 0 +0 * 1/ +inf = 0 +0 * 1/ -inf = 0 +0 * 1/ undef = undef +1 * 1/ 0 = +inf +1 * 1/ 1 = 1 +1 * 1/ -1 = -1 +1 * 1/ +inf = 0 +1 * 1/ -inf = 0 +1 * 1/ undef = undef +-1 * 1/ 0 = -inf +-1 * 1/ 1 = -1 +-1 * 1/ -1 = 1 +-1 * 1/ +inf = 0 +-1 * 1/ -inf = 0 +-1 * 1/ undef = undef ++inf * 1/ 0 = +inf ++inf * 1/ 1 = +inf ++inf * 1/ -1 = -inf ++inf * 1/ +inf = undef ++inf * 1/ -inf = undef ++inf * 1/ undef = undef +-inf * 1/ 0 = -inf +-inf * 1/ 1 = -inf +-inf * 1/ -1 = +inf +-inf * 1/ +inf = undef +-inf * 1/ -inf = undef +-inf * 1/ undef = undef +undef * 1/ 0 = undef +undef * 1/ 1 = undef +undef * 1/ -1 = undef +undef * 1/ +inf = undef +undef * 1/ -inf = undef +undef * 1/ undef = undef +mul_2exp (1) 0 = 0 +mul_2exp (1) 1 = 2 +mul_2exp (1) -1 = -2 +mul_2exp (1) +inf = +inf +mul_2exp (1) -inf = -inf +mul_2exp (1) undef = undef +mul_2exp (2) 0 = 0 +mul_2exp (2) 1 = 4 +mul_2exp (2) -1 = -4 +mul_2exp (2) +inf = +inf +mul_2exp (2) -inf = -inf +mul_2exp (2) undef = undef +div_2exp (1) 0 = 0 +div_2exp (1) 1 = 1/2 +div_2exp (1) -1 = -1/2 +div_2exp (1) +inf = +inf +div_2exp (1) -inf = -inf +div_2exp (1) undef = undef +div_2exp (2) 0 = 0 +div_2exp (2) 1 = 1/4 +div_2exp (2) -1 = -1/4 +div_2exp (2) +inf = +inf +div_2exp (2) -inf = -inf +div_2exp (2) undef = undef +identity checking 0 0 +identity checking 0 1 +identity checking 0 -1 +identity checking 0 +inf +identity checking 0 -inf +identity checking 0 undef +identity checking 1 0 +identity checking 1 1 +identity checking 1 -1 +identity checking 1 +inf +identity checking 1 -inf +identity checking 1 undef +identity checking -1 0 +identity checking -1 1 +identity checking -1 -1 +identity checking -1 +inf +identity checking -1 -inf +identity checking -1 undef +identity checking +inf 0 +identity checking +inf 1 +identity checking +inf -1 +identity checking +inf +inf +identity checking +inf -inf +identity checking +inf undef +identity checking -inf 0 +identity checking -inf 1 +identity checking -inf -1 +identity checking -inf +inf +identity checking -inf -inf +identity checking -inf undef +identity checking undef 0 +identity checking undef 1 +identity checking undef -1 +identity checking undef +inf +identity checking undef -inf +identity checking undef undef diff --git a/z.ml b/z.ml index 58faadb..7b0fecf 100644 --- a/z.ml +++ b/z.ml @@ -552,4 +552,8 @@ module Compare = struct let (<>) a b = not (equal a b) end +external digit_bits: unit -> int = "ml_z_digit_bits" + let version = Zarith_version.version +let backend = Zarith_version.backend + diff --git a/z.mli b/z.mli index 1794942..27c9f2d 100644 --- a/z.mli +++ b/z.mli @@ -490,10 +490,14 @@ val hash: t -> int (** Hashes a number, producing a small integer. The result is consistent with equality: if [a] = [b], then [hash a] = [hash b]. - The result is the same as produced by OCaml's generic hash function, - {!Hashtbl.hash}. Together with type {!Z.t}, the function {!Z.hash} makes it possible to pass module {!Z} as argument to the functor {!Hashtbl.Make}. + + Currently, the value depends on the backend (GMP or LibTomMath). + For GMP, the result is the same as produced by OCaml's generic hash function, + {!Hashtbl.hash}. + For LibTomMath, the result depends on the bit-size of limbs/digits. + @before 1.14 a different hash algorithm was used. *) @@ -872,7 +876,20 @@ end val version: string (** Library version. @since 1.1 -*) + *) + +val backend: string +(** Backend implementing large integer operations. + Can be GMP, MPIR, LibTomMath. + @since 1.15 + *) + +external digit_bits: unit -> int = "ml_z_digit_bits" +(** Number of useful bits in each individual word (so-called 'limb' or 'digit'). + Can be 32 or 64 for GMP, and 28 or 60 for LibTomMath. + @since 1.15 + *) + (**/**)