不同的行为或开方时64位或32位编译 [英] different behaviour or sqrt when compiled with 64 or 32 bits
问题描述
我使用的sqrt()函数的数学库,当我建立了64位使用-m64我得到正确的结果,但是当我建立32位我有非常不一致的行为。
I'm using sqrt() function from math library, when I build for 64 bit using -m64 I'm getting correct result but when I build for 32 bit I have very inconsistent behaviour.
例如在64位
double dx = 0x1.fffffffffffffp+1023;
sqrt(dx); // => 0x1.fffffffffffffp+511
sqrt(0x1.fffffffffffffp+1023);// => 0x1.fffffffffffffp+511
(我认为这是正确舍入结果,MPFR验证)
(which I believe is the correctly rounded result, verified with mpfr)
但在32位相同的输入值,它的行为是不同的。
But on 32 bit same input value it behaves differently.
double dx = 0x1.fffffffffffffp+1023;
sqrt(dx); // => 0x1.0p+512
sqrt(0x1.fffffffffffffp+1023); // => 0x1.fffffffffffffp+511
当一个变量我得到错误的结果通过了相同的值。
我检查前和每次通话后舍入模式和所有被设置为四舍五入到最接近。
原因何在?
我使用的是64位机器上GCC 4.6,和选项 -mfpmath = SSE
和 -march =奔腾
的在x86 NAD 64例。
When the same value passed in a variable I'm getting wrong result.
I checked rounding mode before and after each call and all are set to round to nearest.
What the reason?
I'm using gcc 4.6 on a 64bit machine, and options are -mfpmath=sse
and -march=pentium
for both x86 nad x64 cases.
推荐答案
您还没有说哪个编译或构建筑,你正在使用,但假设对 GCC
86
/ X86-64
则差异可能向下,默认情况下GCC使用32位387浮点指令的事实86,而它使用的x86-64的SSE指令。
You haven't said which compiler or architecure you're using, but assuming gcc
on x86
/ x86-64
then the difference is likely down to the fact that by default gcc uses 387 floating point instructions on 32 bit x86, whereas it uses SSE instructions on x86-64.
387浮点寄存器为80位宽,而双击
为64位宽。这意味着,中间结果可以用387指示,这可导致在一个稍微不同的答案四舍五入后具有较高的precision。 (SSE2指令操作的装64位的双打)。
The 387 floating point registers are 80 bits wide, whereas double
is 64 bits wide. This means that intermediate results can have higher precision using the 387 instructions, which can result in a slightly different answer after rounding. (The SSE2 instructions operate on packed 64 bit doubles).
有改变编译器进行操作,这取决于你想要什么样的方式几种方式:
There's a few ways to change the way the compiler operates, depending on what you want:
- 如果您使用的x86的
-ffloat店
选项生成,当你在双
变量; - 如果您使用的x86版本,以及
-msse2
的-mfpmath = SSE
选项或-march =
开关,编译器将使用SSE指令浮点就像在x86-64的。在code将只能在支持SSE2,CPU上运行,但(奔腾M /奔腾4及更高版本)。 - 如果您使用
-mfpmath = 387
选项X86-64上构建,编译器将使用387指令浮点就像在x86。这是不推荐的,虽然 - X86-64的ABI规定浮点值在SSE寄存器传递,所以编译器必须做387和上证使用该选项注册的洗牌大量
- If you use the
-ffloat-store
option on x86 builds, the compiler will discard extra precision whenever you store a value in adouble
variable; - If you use the
-mfpmath=sse
options on x86 builds, along with-msse2
or an-march=
switch that specifies an SSE2-supporting architecture, the compiler will use SSE instructions for floating point just as on x86-64. The code will only run on CPUs that support SSE2, though (Pentium-M / Pentium 4 and later). - If you use the
-mfpmath=387
option on x86-64 builds, the compiler will use 387 instructions for floating point just as on x86. This isn't recommended, though - the x86-64 ABI specifies that floating point values are passed in SSE registers, so the compiler has to do a lot of shuffling between 387 and SSE registers with this option.
这篇关于不同的行为或开方时64位或32位编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!