铸造改变价值奇怪 为什么在C++代码的这个(可怕)片段中, A1=72 < /代码>而不是 73 ?< /P> #include <iostream> #include <string> using namespace std; int main (int argc, char* argv[]) { double a = 136.73; unsigned int a1 = (100*(a-(int)a)); cout << (a-(int)a) << endl; // 0.73 cout << 100*(a-(int)a) << endl; // 73 cout << a1 << endl; // 72 ! } #包括 #包括 使用名称空间std; int main(int argc,char*argv[]) { 双a=136.73; 无符号整数a1=(100*(a-(整数)a)); cout

铸造改变价值奇怪 为什么在C++代码的这个(可怕)片段中, A1=72 < /代码>而不是 73 ?< /P> #include <iostream> #include <string> using namespace std; int main (int argc, char* argv[]) { double a = 136.73; unsigned int a1 = (100*(a-(int)a)); cout << (a-(int)a) << endl; // 0.73 cout << 100*(a-(int)a) << endl; // 73 cout << a1 << endl; // 72 ! } #包括 #包括 使用名称空间std; int main(int argc,char*argv[]) { 双a=136.73; 无符号整数a1=(100*(a-(整数)a)); cout,c++,casting,C++,Casting,0.73无法精确表示,因此它被四舍五入到一个接近它的数字,在本例中,该数字低于0.73。当乘以100时,得到72。[某物],随后被修剪为72 如果提高输出精度,您将看到(a-(int)a)打印0.72999999898 因此,该值的最大值(将其转换为int)实际上是72 (更新的代码板。)这是一个常见的精度问题。文字136.73实际上代表数字 136.729999999999989768184605054557323455810546875 而a-(int)a的结果不是0.73(即使这是显示的

0.73
无法精确表示,因此它被四舍五入到一个接近它的数字,在本例中,该数字低于
0.73
。当乘以100时,得到
72。[某物]
,随后被修剪为
72


如果提高输出精度,您将看到
(a-(int)a)
打印
0.72999999898

因此,该值的最大值(将其转换为
int
)实际上是
72


(更新的代码板。)

这是一个常见的精度问题。文字
136.73
实际上代表数字

136.729999999999989768184605054557323455810546875
a-(int)a
的结果不是
0.73
(即使这是显示的结果),而是

0.729999999999989768184605054557323455810546875
当你把它乘以
100
,你得到

72.9999999999989768184605054557323455810546875

由于从double转换为int会切断小数点后的所有内容,因此您会得到
72

,如果您阅读以下文章,可能会变得很清楚:


其他人已经证明,
(a-(int)a)的结果
不完全是0.73,但有点低。这篇文章解释了为什么会这样。它并不容易阅读,但确实是每个从事FP工作的人都应该阅读并努力理解的东西,我认为。

答案应该与精度有关。以前曾多次这样问过。你知道IEEE7的二进制表示吗54浮点数和逼近十进制数时的固有限制?9之后的小数来自何处?@Klaus:了解一下双精度的内部存储方式,它应该变得显而易见。