1 #ifndef MC_DEC128_H_INCLUDED 2 #define MC_DEC128_H_INCLUDED 6 #include <mlib/endian.h> 7 #include <mlib/int128.h> 8 #include <mlib/macros.h> 12 #ifndef MONGOCRYPT_INTELDFP 14 #define MONGOCRYPT_HAVE_DECIMAL128_SUPPORT 0 16 #else // With IntelDFP: 18 #define MONGOCRYPT_HAVE_DECIMAL128_SUPPORT 1 23 #include <bid_functions.h> 33 typedef enum mc_dec128_rounding_mode {
34 MC_DEC128_ROUND_NEAREST_EVEN = 0,
35 MC_DEC128_ROUND_DOWNWARD = 1,
36 MC_DEC128_ROUND_UPWARD = 2,
37 MC_DEC128_ROUND_TOWARD_ZERO = 3,
38 MC_DEC128_ROUND_NEAREST_AWAY = 4,
39 MC_DEC128_ROUND_DEFAULT = MC_DEC128_ROUND_NEAREST_EVEN,
40 } mc_dec128_rounding_mode;
42 typedef struct mc_dec128_flagset {
49 #if defined _M_IX86 && !defined __INTEL_COMPILER 50 #define _mcDec128Align(n) 52 #define _mcDec128Align(n) __declspec(align(n)) 56 #define _mcDec128Align(n) __attribute__((aligned(n))) 58 #define _mcDec128Align(n) 62 typedef union _mcDec128Align(16) {
64 #if !defined(__INTELLISENSE__) && defined(__GNUC__) && defined(__amd64) && !defined(__APPLE__) && !defined(__clang__) 67 float value_ __attribute__((mode(TD)));
77 #define MC_DEC128_C(N) mc_dec128 _mcDec128Const(((N) < 0 ? -(N) : (N)), ((N) < 0 ? 1 : 0)) 79 #define MC_DEC128_C(N) _mcDec128Const(((N) < 0 ? -(N) : (N)), ((N) < 0 ? 1 : 0)) 82 #define MC_DEC128(N) MLIB_INIT(mc_dec128) MC_DEC128_C(N) 84 #define _mcDec128Combination(Bits) ((uint64_t)(Bits) << (47)) 85 #define _mcDec128ZeroExpCombo _mcDec128Combination(1 << 7 | 1 << 13 | 1 << 14) 86 #define _mcDec128Const(N, Negate) _mcDec128ConstFromParts(N, (_mcDec128ZeroExpCombo | ((uint64_t)(Negate) << 63))) 87 #define _mcDec128ConstFromParts(CoeffLow, HighWord) \ 90 MLIB_IS_LITTLE_ENDIAN ? (uint64_t)(CoeffLow) : (uint64_t)(HighWord), \ 91 MLIB_IS_LITTLE_ENDIAN ? (uint64_t)(HighWord) : (uint64_t)(CoeffLow), \ 95 static const mc_dec128 MC_DEC128_ZERO = MC_DEC128_C(0);
96 static const mc_dec128 MC_DEC128_ONE = MC_DEC128_C(1);
97 static const mc_dec128 MC_DEC128_MINUSONE = MC_DEC128_C(-1);
100 #define MC_DEC128_LARGEST_NEGATIVE mc_dec128_from_string("-9999999999999999999999999999999999E6111") 101 #define MC_DEC128_SMALLEST_NEGATIVE mc_dec128_from_string("-1E-6176") 103 #define MC_DEC128_LARGEST_POSITIVE mc_dec128_from_string("9999999999999999999999999999999999E6111") 105 #define MC_DEC128_SMALLEST_POSITIVE mc_dec128_from_string("1E-6176") 107 #define MC_DEC128_NORMALIZED_ZERO MC_DEC128_C(0) 109 #define MC_DEC128_NEGATIVE_EXPONENT_ZERO mc_dec128_from_string("0E-6176") 111 #define _mcDec128InfCombo _mcDec128Combination(1 << 15 | 1 << 14 | 1 << 13 | 1 << 12) 112 #define _mcDec128QuietNaNCombo _mcDec128Combination(1 << 15 | 1 << 14 | 1 << 13 | 1 << 12 | 1 << 11) 115 #define MC_DEC128_POSITIVE_INFINITY _mcDec128ConstFromParts(0, _mcDec128InfCombo) 116 #define MC_DEC128_NEGATIVE_INFINITY _mcDec128ConstFromParts(0, _mcDec128InfCombo | 1ull << 63) 118 #define MC_DEC128_POSITIVE_NAN _mcDec128ConstFromParts(0, _mcDec128QuietNaNCombo) 120 #define MC_DEC128_NEGATIVE_NAN _mcDec128ConstFromParts(0, _mcDec128QuietNaNCombo | 1ull << 63) 124 static inline BID_UINT128 _mc_to_bid128(mc_dec128 d) {
126 memcpy(&r, &d,
sizeof d);
131 static inline mc_dec128 _bid128_to_mc(BID_UINT128 d) {
133 memcpy(&r, &d,
sizeof d);
145 static inline mc_dec128 mc_dec128_from_double_ex(
double d, mc_dec128_rounding_mode rnd, mc_dec128_flagset *flags) {
146 mc_dec128_flagset zero_flags = {0};
147 return _bid128_to_mc(binary64_to_bid128(d, rnd, flags ? &flags->bits : &zero_flags.bits));
154 static inline mc_dec128 mc_dec128_from_double(
double d) {
155 return mc_dec128_from_double_ex(d, MC_DEC128_ROUND_DEFAULT, NULL);
166 static inline mc_dec128 mc_dec128_from_string_ex(
const char *s, mc_dec128_rounding_mode rnd, mc_dec128_flagset *flags) {
167 mc_dec128_flagset zero_flags = {0};
168 return _bid128_to_mc(bid128_from_string((
char *)s, rnd, flags ? &flags->bits : &zero_flags.bits));
175 static inline mc_dec128 mc_dec128_from_string(
const char *s) {
176 return mc_dec128_from_string_ex(s, MC_DEC128_ROUND_DEFAULT, NULL);
183 typedef struct mc_dec128_string {
194 static inline mc_dec128_string mc_dec128_to_string_ex(mc_dec128 d, mc_dec128_flagset *flags) {
195 mc_dec128_flagset zero_flags = {0};
196 mc_dec128_string out = {{0}};
197 bid128_to_string(out.str, _mc_to_bid128(d), flags ? &flags->bits : &zero_flags.bits);
204 static inline mc_dec128_string mc_dec128_to_string(mc_dec128 d) {
205 return mc_dec128_to_string_ex(d, NULL);
209 #define DECL_IDF_COMPARE_1(Oper) \ 210 static inline bool mc_dec128_##Oper##_ex(mc_dec128 left, mc_dec128 right, mc_dec128_flagset *flags) { \ 211 mc_dec128_flagset zero_flags = {0}; \ 213 != bid128_quiet_##Oper(_mc_to_bid128(left), \ 214 _mc_to_bid128(right), \ 215 flags ? &flags->bits : &zero_flags.bits); \ 218 static inline bool mc_dec128_##Oper(mc_dec128 left, mc_dec128 right) { \ 219 return mc_dec128_##Oper##_ex(left, right, NULL); \ 222 #define DECL_IDF_COMPARE(Op) DECL_IDF_COMPARE_1(Op) 224 DECL_IDF_COMPARE(equal)
225 DECL_IDF_COMPARE(not_equal)
226 DECL_IDF_COMPARE(greater)
227 DECL_IDF_COMPARE(greater_equal)
228 DECL_IDF_COMPARE(less)
229 DECL_IDF_COMPARE(less_equal)
231 #undef DECL_IDF_COMPARE 232 #undef DECL_IDF_COMPARE_1 235 #define DECL_PREDICATE(Name, BIDName) \ 236 static inline bool mc_dec128_##Name(mc_dec128 d) { return 0 != bid128_##BIDName(_mc_to_bid128(d)); } 238 DECL_PREDICATE(is_zero, isZero)
239 DECL_PREDICATE(is_negative, isSigned)
240 DECL_PREDICATE(is_inf, isInf)
241 DECL_PREDICATE(is_finite, isFinite)
242 DECL_PREDICATE(is_nan, isNaN)
244 #undef DECL_PREDICATE 247 #define DECL_IDF_BINOP_WRAPPER(Oper) \ 248 static inline mc_dec128 mc_dec128_##Oper##_ex(mc_dec128 left, \ 250 mc_dec128_rounding_mode mode, \ 251 mc_dec128_flagset *flags) { \ 252 mc_dec128_flagset zero_flags = {0}; \ 253 return _bid128_to_mc( \ 254 bid128_##Oper(_mc_to_bid128(left), _mc_to_bid128(right), mode, flags ? &flags->bits : &zero_flags.bits)); \ 257 static inline mc_dec128 mc_dec128_##Oper(mc_dec128 left, mc_dec128 right) { \ 258 return mc_dec128_##Oper##_ex(left, right, MC_DEC128_ROUND_DEFAULT, NULL); \ 261 DECL_IDF_BINOP_WRAPPER(add)
262 DECL_IDF_BINOP_WRAPPER(mul)
263 DECL_IDF_BINOP_WRAPPER(div)
264 DECL_IDF_BINOP_WRAPPER(sub)
265 DECL_IDF_BINOP_WRAPPER(pow)
267 #undef DECL_IDF_BINOP_WRAPPER 270 #define DECL_IDF_UNOP_WRAPPER(Oper) \ 271 static inline mc_dec128 mc_dec128_##Oper##_ex(mc_dec128 operand, mc_dec128_flagset *flags) { \ 272 mc_dec128_flagset zero_flags = {0}; \ 273 return _bid128_to_mc( \ 274 bid128_##Oper(_mc_to_bid128(operand), MC_DEC128_ROUND_DEFAULT, flags ? &flags->bits : &zero_flags.bits)); \ 277 static inline mc_dec128 mc_dec128_##Oper(mc_dec128 operand) { return mc_dec128_##Oper##_ex(operand, NULL); } 279 DECL_IDF_UNOP_WRAPPER(log2)
280 DECL_IDF_UNOP_WRAPPER(log10)
281 #undef DECL_IDF_UNOP_WRAPPER 283 static inline mc_dec128
284 mc_dec128_round_integral_ex(mc_dec128 value, mc_dec128_rounding_mode direction, mc_dec128_flagset *flags) {
285 BID_UINT128 bid = _mc_to_bid128(value);
286 mc_dec128_flagset zero_flags = {0};
287 _IDEC_flags *fl = flags ? &flags->bits : &zero_flags.bits;
289 case MC_DEC128_ROUND_TOWARD_ZERO:
return _bid128_to_mc(bid128_round_integral_zero(bid, fl));
290 case MC_DEC128_ROUND_NEAREST_AWAY:
return _bid128_to_mc(bid128_round_integral_nearest_away(bid, fl));
291 case MC_DEC128_ROUND_NEAREST_EVEN:
return _bid128_to_mc(bid128_round_integral_nearest_even(bid, fl));
292 case MC_DEC128_ROUND_DOWNWARD:
return _bid128_to_mc(bid128_round_integral_negative(bid, fl));
293 case MC_DEC128_ROUND_UPWARD:
return _bid128_to_mc(bid128_round_integral_positive(bid, fl));
298 static inline mc_dec128 mc_dec128_negate(mc_dec128 operand) {
299 return _bid128_to_mc(bid128_negate(_mc_to_bid128(operand)));
302 static inline mc_dec128 mc_dec128_abs(mc_dec128 operand) {
303 return _bid128_to_mc(bid128_abs(_mc_to_bid128(operand)));
315 static inline mc_dec128
316 mc_dec128_scale_ex(mc_dec128 fac,
long int exp, mc_dec128_rounding_mode rounding, mc_dec128_flagset *flags) {
317 mc_dec128_flagset zero_flags = {0};
318 return _bid128_to_mc(bid128_scalbln(_mc_to_bid128(fac), exp, rounding, flags ? &flags->bits : &zero_flags.bits));
328 static inline mc_dec128 mc_dec128_scale(mc_dec128 fac,
long int exp) {
329 return mc_dec128_scale_ex(fac, exp, MC_DEC128_ROUND_DEFAULT, NULL);
333 typedef struct mc_dec128_modf_result {
338 } mc_dec128_modf_result;
349 static inline mc_dec128_modf_result mc_dec128_modf_ex(mc_dec128 d, mc_dec128_flagset *flags) {
350 mc_dec128_flagset zero_flags = {0};
351 mc_dec128_modf_result res;
353 res.frac = _bid128_to_mc(bid128_modf(_mc_to_bid128(d), &whole, flags ? &flags->bits : &zero_flags.bits));
354 res.whole = _bid128_to_mc(whole);
366 static inline mc_dec128_modf_result mc_dec128_modf(mc_dec128 d) {
367 return mc_dec128_modf_ex(d, NULL);
378 static inline mc_dec128 mc_dec128_fmod_ex(mc_dec128 numer, mc_dec128 denom, mc_dec128_flagset *flags) {
379 mc_dec128_flagset zero_flags = {0};
380 return _bid128_to_mc(
381 bid128_fmod(_mc_to_bid128(numer), _mc_to_bid128(denom), flags ? &flags->bits : &zero_flags.bits));
391 static inline mc_dec128 mc_dec128_fmod(mc_dec128 numer, mc_dec128 denom) {
392 return mc_dec128_fmod_ex(numer, denom, NULL);
402 static inline int64_t mc_dec128_to_int64_ex(mc_dec128 d, mc_dec128_flagset *flags) {
403 mc_dec128_flagset zero_flags = {0};
404 return bid128_to_int64_int(_mc_to_bid128(d), flags ? &flags->bits : &zero_flags.bits);
413 static inline int64_t mc_dec128_to_int64(mc_dec128 d) {
414 return mc_dec128_to_int64_ex(d, NULL);
420 MC_DEC128_COMBO_NONCANONICAL = 3 << 15,
422 MC_DEC128_COMBO_INFINITY = 0x1e << 12,
424 MC_DEC128_MAX_BIASED_EXPONENT = 6143 + 6144,
426 MC_DEC128_EXPONENT_BIAS = 6143 + 33,
428 MC_DEC_MIN_EXPONENT = -6143,
430 MC_DEC_MAX_EXPONENT = 6144,
434 static inline uint32_t mc_dec128_combination(mc_dec128 d) {
436 uint64_t hi = d._words[MLIB_IS_LITTLE_ENDIAN ? 1 : 0];
438 int signpos = 64 - 1;
440 int fieldpos = signpos - 17;
441 int fieldmask = (1 << 17) - 1;
442 return (uint32_t)((hi >> fieldpos) & (uint32_t)fieldmask);
448 static inline uint64_t mc_dec128_coeff_high(mc_dec128 d) {
449 uint64_t hi_field_mask = (1ull << 49) - 1;
450 uint32_t combo = mc_dec128_combination(d);
451 if (combo < MC_DEC128_COMBO_NONCANONICAL) {
452 uint64_t hi = d._words[MLIB_IS_LITTLE_ENDIAN ? 1 : 0];
453 return hi & hi_field_mask;
462 static inline uint64_t mc_dec128_coeff_low(mc_dec128 d) {
463 uint32_t combo = mc_dec128_combination(d);
464 if (combo < MC_DEC128_COMBO_NONCANONICAL) {
465 uint64_t lo = d._words[MLIB_IS_LITTLE_ENDIAN ? 0 : 1];
476 static inline mlib_int128 mc_dec128_coeff(mc_dec128 d) {
478 uint64_t hi = mc_dec128_coeff_high(d);
480 uint64_t lo = mc_dec128_coeff_low(d);
482 mlib_int128 hi_128 = mlib_int128_lshift(MLIB_INT128_CAST(hi), 64);
483 return mlib_int128_add(hi_128, MLIB_INT128_CAST(lo));
494 static inline uint32_t mc_dec128_get_biased_exp(mc_dec128 d) {
495 uint32_t combo = mc_dec128_combination(d);
496 if (combo < MC_DEC128_COMBO_NONCANONICAL) {
499 if (combo >= MC_DEC128_COMBO_INFINITY) {
500 return MC_DEC128_MAX_BIASED_EXPONENT + 1;
502 return (combo >> 1) & ((1 << 14) - 1);
507 static inline char *mc_dec128_to_new_decimal_string(mc_dec128 d) {
508 if (mc_dec128_is_zero(d)) {
510 char *s = (
char *)calloc(2, 1);
517 if (mc_dec128_is_negative(d)) {
519 d = mc_dec128_negate(d);
520 char *s = mc_dec128_to_new_decimal_string(d);
524 char *s1 = (
char *)calloc(strlen(s) + 2, 1);
533 if (mc_dec128_is_inf(d) || mc_dec128_is_nan(d)) {
534 const char *r = mc_dec128_is_inf(d) ?
"Infinity" :
"NaN";
535 char *c = (
char *)calloc(strlen(r) + 1, 1);
542 const char DIGITS[] =
"0123456789";
543 const mc_dec128 TEN = MC_DEC128_C(10);
546 mc_dec128_modf_result modf = mc_dec128_modf(d);
548 if (mc_dec128_is_zero(modf.frac)) {
551 mc_dec128 log10 = mc_dec128_modf(mc_dec128_log10(d)).whole;
552 int64_t ndigits = mc_dec128_to_int64(log10) + 1;
554 char *strbuf = (
char *)calloc((
size_t)(ndigits + 1), 1);
557 char *optr = strbuf + ndigits - 1;
558 while (!mc_dec128_is_zero(modf.whole)) {
559 mc_dec128 rem = mc_dec128_fmod(modf.whole, TEN);
560 int64_t remi = mc_dec128_to_int64(rem);
561 *optr-- = DIGITS[remi];
563 modf = mc_dec128_modf(mc_dec128_div(modf.whole, TEN));
567 }
else if (mc_dec128_is_zero(modf.whole)) {
569 while (!mc_dec128_is_zero(mc_dec128_modf(d).frac)) {
570 d = mc_dec128_mul(d, TEN);
573 char *part = mc_dec128_to_new_decimal_string(d);
577 char *buf = (
char *)calloc(strlen(part) + 3, 1);
581 strcpy(buf + 2, part);
587 char *whole = mc_dec128_to_new_decimal_string(modf.whole);
591 char *frac = mc_dec128_to_new_decimal_string(modf.frac);
596 char *ret = (
char *)calloc(strlen(whole) + strlen(frac) + 1, 1);
600 out += strlen(whole);
602 strcpy(out, frac + 1);
610 static inline mc_dec128 mc_dec128_from_bson_iter(
const bson_iter_t *it) {
612 if (!bson_iter_decimal128(it, &b)) {
613 mc_dec128 nan = MC_DEC128_POSITIVE_NAN;
617 memcpy(&ret, &b,
sizeof b);
621 static inline bson_decimal128_t mc_dec128_to_bson_decimal128(mc_dec128 v) {
622 bson_decimal128_t ret;
623 memcpy(&ret, &v,
sizeof ret);
631 #endif // MC_DEC128_H_INCLUDED