3 ms·
That's not how floating-point works. The IEEE 754 standard is quite clear that each floating-point datum represents exactly one real number (or infinity or NaN)
by stephencanon 7y ago
That's not how floating-point works. The IEEE 754 standard is quite clear that each floating-point datum represents exactly one real number (or infinity or NaN). Floating-point numbers are not intervals.
Analogously, `float x = 2.25; int a = x;` assigns the value two to a, but this does not imply that the integer two also represents 2.25. Two is just two.
- aidenn0 7y agoIMO that's a very wrongheaded way to think about floating-point values. As far as IEEE 754 goes, my only praise for it is that it's significantly better than no floating-point standard (which we had before). Integers are inherently different because calculations with integers are naturally discrete, while floating-point calculations are a discrete approximation of the reals, which are not discrete. There are two general purposes for floating-point numbers: scientific computing, where you start with an imprecise value and the precision multiplicatively accumulates (the original use). And as a hardware optimization for calculation of non-integer values (a common use-case today). In neither case does it make sense to treat a floating-point value as a precise number, which matches common advice to not compare floating-point values by equality.
- szc 7y agoI came here to comment that I think the problem is poorly posed and algorithm chosen to implement it is "backwards". But I also see that StehpenCannon has spoken :-); there is going to be very little chance he is wrong when it comes to arguing about floating point! He also notes the following, but not quite so explicitly... The problem is poorly posed because the question is, which mantissas, exponents and sign bits fit into a long. The algorithm is backwards because simple comparisons in integer space cannot compute this; but I think the algorithm should be, int fits_long(double value) { unsigned int trailingZeros = countOfTrailingZeros(mantissaOf(value)); bool fits = (bitsInAMantissa + 2 - trailingZeros + exponentOf(value) < bitsInALong); return fits; } [Notes: if double is always > 0 and going to an unsigned long, the 2 above would be 1. The 2 represents the sign bit in the double. Given that sizeof(double) == sizeof(long) all bits in the two representations are accounted for, so there is no information loss. checking: mantissa = 0 (with a hidden msb of 1) means, trailingZeros = bitsInAMantissa -> fits will be true when the exponent value can be 0..62. So this represents each of the +/- 2^exponent values mantissa = 1 x bitsInAMantissa means, trailingZeros = 0 -> fits will be true when the exponent value can be 0..(bitsInALong-BitsInAMantissa-2). So, +/- (all ones) * 2^exponent value. The representation for going from double to long is not "smooth". ] countOfTrailingZeros() is a favorite of bit twiddlers. "Hackers Delight" or "bithacks" https://graphics.stanford.edu/~seander/bithacks.html https://graphics.stanford.edu/~seander/bithacks.html [edited to improve readability]