diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2019-11-10 15:06:49 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2019-11-13 13:10:08 -0800 |
commit | ff10e9517d98aa606e007d3aa4d5aef1c423ab77 (patch) | |
tree | 99d676a2ef88a024fdfd3fdafcdb7abb508e0f55 /src/floatfns.c | |
parent | 65fb04801c59ac204790e0a5c0599c9b11151f32 (diff) | |
download | emacs-ff10e9517d98aa606e007d3aa4d5aef1c423ab77.tar.gz |
Refactor double integer scaling
This doesn’t alter behavior, and simplifies a future commit.
* src/floatfns.c (double_integer_scale): New function,
with body adapted from the old timefns.c.
* src/timefns.c (decode_float_time): Use it.
Diffstat (limited to 'src/floatfns.c')
-rw-r--r-- | src/floatfns.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/floatfns.c b/src/floatfns.c index 3199d572138..7e77dbd16dc 100644 --- a/src/floatfns.c +++ b/src/floatfns.c @@ -348,6 +348,29 @@ integer_value (Lisp_Object a) return true; } +/* Return the integer exponent E such that D * FLT_RADIX**E (i.e., + scalbn (D, E)) is an integer that has precision equal to D and is + representable as a double. + + Return DBL_MANT_DIG - DBL_MIN_EXP (the maximum possible valid + scale) if D is zero or tiny. Return a value greater than + DBL_MANT_DIG - DBL_MIN_EXP if there is conversion trouble; on all + current platforms this can happen only if D is infinite or a NaN. */ + +int +double_integer_scale (double d) +{ + int exponent = ilogb (d); + return (DBL_MIN_EXP - 1 <= exponent && exponent < INT_MAX + ? DBL_MANT_DIG - 1 - exponent + : (DBL_MANT_DIG - DBL_MIN_EXP + + (exponent == INT_MAX + || (exponent == FP_ILOGBNAN + && (FP_ILOGBNAN != FP_ILOGB0 || isnan (d))) + || (!IEEE_FLOATING_POINT && exponent == INT_MIN + && (FP_ILOGB0 != INT_MIN || d != 0))))); +} + /* the rounding functions */ static Lisp_Object |