【发布时间】:2015-09-02 01:28:46
【问题描述】:
当使用 IEEE 754 浮点表示(c++ 中的double 类型)时,非常接近(可表示)整数的数字将四舍五入到最接近的整数并精确表示。这是真的吗?
在四舍五入之前,一个数字必须与最接近的可表示整数有多接近?
这个距离是恒定的吗?
比如给定1可以精确表示,那么小于1的最大double是多少?
【问题讨论】:
标签: c++
当使用 IEEE 754 浮点表示(c++ 中的double 类型)时,非常接近(可表示)整数的数字将四舍五入到最接近的整数并精确表示。这是真的吗?
在四舍五入之前,一个数字必须与最接近的可表示整数有多接近?
这个距离是恒定的吗?
比如给定1可以精确表示,那么小于1的最大double是多少?
【问题讨论】:
标签: c++
当使用 IEEE 754 浮点表示时(
double输入 c ++),非常接近(可表示的)整数的数字是 四舍五入到最接近的整数并精确表示。
这取决于数字是否更接近整数而不是其他可表示的值。 0.99999999999999994 is not equal to 1, but 0.99999999999999995 is.
这个距离是恒定的吗?
不,幅度越大,它就越小——尤其是表示中的指数越大。较大的指数意味着尾数覆盖的区间较大,这反过来又意味着整体精度较低。
例如,小于 1 的最大双精度数是多少?
std::nexttoward(1.0, 0.0)。例如。 0.999999999999999889 on Coliru.
【讨论】:
你会发现关于 1.0 的相反方向的更明确的陈述 此处记录了 1.0 和下一个更大数字之间的差异:
std::numeric_limits<double>::epsilon()
浮点的工作方式,下一个较小的数字与 1.0 的距离应该是下一个较大数字的一半。
【讨论】:
低于 1 的第一个 IEEE 双精度可以明确地写为 0.99999999999999989,但正好是 0.999999999999999988897769753748434595763683319091796875。
距离不是恒定的,它取决于数字的指数(以及大小)。最终差距变得大于 1,这意味着偶数(与奇数相反 - 奇数是第一个被四舍五入的整数)整数将稍微四舍五入(或者最终,很多)。
【讨论】:
IEEE 浮点数递增的二进制表示可以看作是递增整数表示:
Hack 示例(英特尔):
#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";
}
输出:
0.9999999999999999 [3fefffffffffffff] < 1 [3ff0000000000000]
当整数表示达到其极限时,如果指数位发生变化,连续浮点数的差值会增加。
另请参阅:http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
【讨论】:
当使用 IEEE 754 浮点表示(c++ 中的 double 类型)时,非常接近精确整数的数字将四舍五入为最接近的整数并精确表示。这是真的吗?
这是错误的。
一个数字在四舍五入之前必须与最接近的 int 到底有多接近?
当您执行二进制到字符串的转换时,浮点数会使用当前舍入模式四舍五入到当前精度(对于printf 系列函数,默认精度为 6)。
【讨论】: