它是如何管理的"rounding",因为除以(并且比多个)returns 相同的数量,在由于四舍五入而截断后没有任何损失?
How is it managed "rounding" since divide (and than multiple) returns the same amount without any loss after truncation due to rounding?
一个test很简单:
float a= 1.0f;
float b = 1.576f;
float c = a/b;
cout << c << endl;
cout << c * b << endl;
结果:
0.634518
1
但是 1/1.1576
类似于 0,63451776649746192893401015228426
(当然还有更多数字)。
当然,四舍五入有时会发生。但是一旦这个值被截断而不是乘回来,我无论如何都能得到原始值。
我是"lucky"还是每次都这样保证?
你很幸运。永远不要假设浮点运算的结果是特定值。比较时可以使用 < 和 >,但如果要检查是否相等,请使用小的 epsilon。
if (abs(a - b) < epsilon) cout << "a and b are equal" << endl;
即使比较,根据情况,您也可能想要使用 epsilon。
您可以使用 std::numeric_limits<float>::epsilon()
或定义您自己的。
N3337 3.9.1.8:
The value representation of
floating-point types is implementation-defined
你很(不)幸运。这是绝对不能保证的。
考虑一个浮点表示,尾数中的四个二进制数字只有 space,并且不会抑制前导数字(因为这只会使表示更复杂,而无需更改参数) .
1/10 = 0.000110011...b
在我们的表示中将是 1.100B-4
。现在乘以十 (1010b
),得到扩展精度 1111.B-4
。如果将指数归一化,最终结果为 1.111B-1
- not 与 1.000B0
.
相同
类似的论点适用于更高的精度。如果您使用的是 x86 平台,float 有 23 位精度(其中一个隐藏),然而内部浮点寄存器有 63 位精度——这意味着中间值是持有 much 更准确。这意味着您通常不会注意到这样的问题。
一个test很简单:
float a= 1.0f;
float b = 1.576f;
float c = a/b;
cout << c << endl;
cout << c * b << endl;
结果:
0.634518
1
但是 1/1.1576
类似于 0,63451776649746192893401015228426
(当然还有更多数字)。
当然,四舍五入有时会发生。但是一旦这个值被截断而不是乘回来,我无论如何都能得到原始值。
我是"lucky"还是每次都这样保证?
你很幸运。永远不要假设浮点运算的结果是特定值。比较时可以使用 < 和 >,但如果要检查是否相等,请使用小的 epsilon。
if (abs(a - b) < epsilon) cout << "a and b are equal" << endl;
即使比较,根据情况,您也可能想要使用 epsilon。
您可以使用 std::numeric_limits<float>::epsilon()
或定义您自己的。
N3337 3.9.1.8:
The value representation of floating-point types is implementation-defined
你很(不)幸运。这是绝对不能保证的。
考虑一个浮点表示,尾数中的四个二进制数字只有 space,并且不会抑制前导数字(因为这只会使表示更复杂,而无需更改参数) .
1/10 = 0.000110011...b
在我们的表示中将是 1.100B-4
。现在乘以十 (1010b
),得到扩展精度 1111.B-4
。如果将指数归一化,最终结果为 1.111B-1
- not 与 1.000B0
.
类似的论点适用于更高的精度。如果您使用的是 x86 平台,float 有 23 位精度(其中一个隐藏),然而内部浮点寄存器有 63 位精度——这意味着中间值是持有 much 更准确。这意味着您通常不会注意到这样的问题。