我的问题:
尝试找出以下C ++代码段的结果:
#include <iostream>
int main(int argc, char* argv[])
{
double a = 5.1;
int b = a * 100;
std::cout << b << std::endl;
double c = 6.1;
int d = c * 100;
std::cout << d << std::endl;
}
在Windows上,我使用VS2008 SP1编译并运行上面的代码并获取:
509
610
在Linux上,我使用g ++编译并运行相同的代码并获取:
509
609
代码有什么问题?
抱歉,我试图找出问题的标题,因此我可以搜索一下。但是,我不能说出这个问题,所以我直接在这里提出。
感谢任何建议。
答案 0 :(得分:5)
double
不是一种确切类型,您可以通过应用std::numeric_limits
typetrait看到:
#include <limits>
static_assert(std::numeric_limits<double>::is_exact == false);
因此涉及双打的计算只是近似的,并且你所观察到的内容没有任何错误。
您的代码没有问题。
答案 1 :(得分:2)
一般情况下,double(和float)是二进制的,你只能对2的幂的分数进行精确表示。因此,如果小数部分只由1/2,1 / 4等词组成, 1 / 8,1 / 16等等,浮点数或双精度都是准确的(当然,除非你遇到精度问题)。
现在,“0.1”是1/10,实际上是1/2 * 1/5。 5不是2的幂,因此“0.1”不能用二进制表示,它只能近似。
答案 2 :(得分:1)
double
到int
转换是通过截断完成的。在你的情况下,由于在舍入数字时精度损失(以及MSalters指出的少量坏运气,因为这只发生在一些“边缘”值附近)。
以下是编译器/操作系统之间行为差异的几个可能原因:
答案 3 :(得分:1)
作为的规则之一,Kernighan和Plauger所描述的编程风格元素。
10.0
次0.1
几乎不会1.0
意味着浮动不像数学实数那样。有一个标准(IEEE 754)如何实现浮点数,但它不是C标准的一部分,而只是在C#中。