![]() |
1
36
可能是这样的: http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18
|
![]() |
2
10
正如其他人所指出的,VS数学库正在X87 FPU上进行计算,并生成80位结果,即使类型是双精度的。 因此:
许多数学库和编译器通过在SSE寄存器(如果可用)中以64位浮点进行计算,或者在比较之前强制存储和舍入值,或者在实际计算cos()时存储和重新加载最终结果来保护您免受此影响。您所使用的编译器/库组合并不是那么简单。 |
![]() |
3
5
在释放模式下生成的cos(x)==cos(x)过程: 00DB101A call _CIcos (0DB1870h) 00DB101F fld st(0) 00DB1021 fucompp 该值计算一次,然后克隆,然后与自身进行比较-结果将正常 调试模式相同: 00A51405 sub esp,8 00A51408 fld qword ptr [x] 00A5140B fstp qword ptr [esp] 00A5140E call @ILT+270(_cos) (0A51113h) 00A51413 fld qword ptr [x] 00A51416 fstp qword ptr [esp] 00A51419 fstp qword ptr [ebp-0D8h] 00A5141F call @ILT+270(_cos) (0A51113h) 00A51424 add esp,8 00A51427 fld qword ptr [ebp-0D8h] 00A5142D fucompp
现在,奇怪的事情发生了。
|
![]() |
4
5
你应该
浮点寄存器的大小可能与内存值不同(在当前的Intel机器中,fpu寄存器是80位对64位的两倍)。如果编译器正在生成计算第一个余弦的代码,然后将该值存储到内存中,计算第二个余弦并将内存中的值与寄存器中的值进行比较,则这些值可能会有所不同(由于从80位到64位的舍入问题)。 浮点值有点棘手。谷歌的浮点比较。 |
![]() |
5
1
编译器可能生成了将64位双精度值与 80位内部浮点寄存器。测试浮点值是否相等 容易出现这些错误——你几乎总是最好做一个“模糊”比较,比如(fabs(val1-val2)<epsilon),而不是(val1=val2)。 |
![]() |
6
0
增加和测试一个浮点值作为循环控制变量通常是一个非常糟糕的主意。如果必须,创建一个单独的int lcv以便循环打开。 在这种情况下,更容易:
|
![]() |
7
-1
如何解决问题?修改
如果
阻止:
if ( (float)cos(x) == (float)cos(x) ) |
|
Rik Bloemers · for循环不接受任何浮点变量 3 年前 |
![]() |
zell · 为什么存储7个浮点数需要34字节? 3 年前 |
![]() |
Atharva Sunil Sathe · 如何删除任意数的小数点? 3 年前 |
![]() |
user1658887 · 为什么**2!=a*a一些彩车? 7 年前 |