简体   繁体   中英

IEEE 754 floating point, what is the largest number < 1?

When using IEEE 754 floating point representation ( double type in c++), numbers that are very close to (representable) integers are rounded to their closest integer and represented exactly. Is that true?
Exactly how close does a number have to be to the nearest representable integer before it is rounded?
Is this distance constant?
For example, given that 1 can be represented exactly, what is the largest double less than 1?

When using IEEE 754 floating point representation ( double type in c++), numbers that are very close to (representable) integers are rounded to their closest integer and represented exactly.

This depends upon whether the number is closer to the integer than to other values representable. 0.99999999999999994 is not equal to 1 , but 0.99999999999999995 is.

Is this distance constant?

No, it becomes less with larger magnitudes - in particular with larger exponents in the representation. Larger exponents imply larger intervals to be covered by the mantissa, which in turn implies less precision overall.

For example, what is the largest double less than 1?

std::nexttoward(1.0, 0.0) . Eg 0.999999999999999889 on Coliru .

You will find much more definitive statements regarding the opposite direction from 1.0 The difference between 1.0 and the next larger number is documented here:

std::numeric_limits<double>::epsilon()

The way floating point works, the next smaller number should be exactly half as far away from 1.0 as the next larger number.

The first IEEE double below 1 can be written unambiguously as 0.99999999999999989, but is exactly 0.99999999999999988897769753748434595763683319091796875.

The distance is not constant, it depends on the exponent (and thus the magnitude) of the number. Eventually the gap becomes larger than 1, meaning even (not as opposed to odd - odd integers are the first to get rounded) integers will get rounded somewhat (or, eventually, a lot).

The binary representation of increasing IEEE floating point numbers can be seen as a increasing integer representation:

Sample Hack (Intel):

#include <cstdint>
#include <iostream>
#include <limits>

int main() {
    double one = 1;
    std::uint64_t one_representation = *reinterpret_cast<std::uint64_t*>(&one);
    std::uint64_t lesser_representation = one_representation - 1;
    std::cout.precision(std::numeric_limits<double>::digits10 + 1);
    std::cout << std::hex;
    std::cout << *reinterpret_cast<double*>(&lesser_representation)
              << " [" << lesser_representation
              << "] < " << *reinterpret_cast<double*>(&one_representation)
              << " [" << one_representation
              << "]\n";
}

Output:

0.9999999999999999 [3fefffffffffffff] < 1 [3ff0000000000000]

When advancing the integer representation to its limits, the difference of consecutive floating point numbers is increasing, if exponent bits change.

See also: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/

When using IEEE 754 floating point representation (double type in c++), numbers that are very close to exact integers are rounded to the closest integer and represented exactly. Is that true?

This is false.

Exactly how close does a number have to be to the nearest int before it is rounded?

When you do a binary to string conversion the floating point number gets rounded to the current precision (for printf family of functions the default precision is 6) using the current rounding mode.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM