2013-10-29 33 views
1

在用作模板放慢参数的一类的成员函数,我有包含以下代码的函数:奇怪静态铸造行为用作模板参数

double x = /*Something operation returning double*/; 
x /= CubeWidth; /*CubeWidth is a class member*/ 
cout << "Element after centering and normalization = " << x << endl; 
cout << "and after adding 1 and truncating = " << x+1 << endl; 
cout << "then static cast = " << (int) x+1 << endl; 

这样做的输出功能

Element after centering and normalization = 1 
and after adding 1 and truncating = 2 
then static cast = 1 

很明显,最后一行应该给出一个答案2.

如果我实例完全相同的类不使用它作为模板参数,我不要得到这个打印输出,而是我有正确的。

有谁能告诉我为什么会发生这种情况?

+2

好问题为什么。我知道如何解决这个问题,但是 - 把你的表达式放在括号里。例如'((int)x + 1)'。我也会等待好的解释。编辑:如果这个解决方案不起作用,那么我*必须是Daniel Frey写的。 – Grzegorz

+2

@j_random_hacker Nope,'+'的优先级高于'<<'的优先级,请参见[here](http://en.cppreference.com/w/cpp/language/operator_precedence)。 –

+0

@j_random_hacker:'1 << 2 + 1'确实是'1 << 3',例如'8',而不是'3'。 “... <<(cond)”的优先顺序是有意义的吗? x:y << ...在这种情况下代替'y',表达式将使用'y << ...'。 – Grzegorz

回答

3

最有可能的x(双)不完全是1,它是0.9999999...。通过打印x==1.0x<1.0来查看确切的值,并查看确实如此。或添加更多位数的输出:

cout << "and after adding 1 and truncating = " << setprecision(15) << x+1 << endl; 

整数逗号后会扔掉所有的数字取整,因此1.999999...变得1

+0

我认为你是对的,但效果已经开始随机出现。我只是再次运行测试,没有任何改变,除了我不再连接到无线网络!这可能是相关的吗?我知道我在抓秸秆...... – Plamen

+2

@Plamen宇宙射线,“相对Mondfeuchtigkeit”,...... - 但最终它更可能是'x'的计算,你没有显示。无论如何,只要让你的代码更安全,增加更多的数字或允许一个小的三角洲,例如'(INT)(X + 1.000001)'。也许[这个页面](http://floating-point-gui.de)会有帮助。 –