有没有办法确保浮点运算结果在linux和windows中都相同
我的程序在
linux和windows中运行,我必须确保浮点运算在不同的OS中得到相同的结果.
这是代码: for (int i = 0; i < 100000; ++i) { float d_value = 10.0f / float(i); float p_value = 0.01f * float(i) + 100.0f; } 我使用“g -m32 -c -static -g -O0 -ffloat-store”在linux中构建代码. 当我打印“d_value”和“p_value”时,“d_value”在linux和windows中都是相同的.但有时候“p_value”会有所不同. windows: 42d5d1eb linux: 42d5d1ec 为什么要发生这种情况 我的版本是 Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.4.5 (Debian 4.4.5-8) 我使用标志-ffloat-store,因为有人建议:Different math rounding behaviour between Linux,Mac OS X and Windows 解决方法
在Windows上使用/ fp:strict告诉编译器生成严格遵循IEEE 754的代码,并在Linux上生成gcc -msse2 -mfpmath = sse以获得相同的行为.
您所看到的差异的原因已经在StackOverflow上进行了讨论,但最好的调查是David Monniaux的article. 我用gcc -msse2 -mpfmath = sse编译时得到的汇编指令如下.说明cvtsi2ssq,divss,mulss,addss是正确的使用指令,它们会产生一个程序,其中p_value包含一个点42d5d1ec. .globl _main .align 4,0x90 _main: ## @main .cfi_startproc ## BB#0: pushq %rbp Ltmp2: .cfi_def_cfa_offset 16 Ltmp3: .cfi_offset %rbp,-16 movq %rsp,%rbp Ltmp4: .cfi_def_cfa_register %rbp subq $32,%rsp movl $0,-4(%rbp) movl $0,-8(%rbp) LBB0_1: ## =>This Inner Loop Header: Depth=1 cmpl $100000,-8(%rbp) ## imm = 0x186A0 jge LBB0_4 ## BB#2: ## in Loop: Header=BB0_1 Depth=1 movq _p_value@GOTPCREL(%rip),%rax movabsq $100,%rcx cvtsi2ssq %rcx,%xmm0 movss LCPI0_0(%rip),%xmm1 movabsq $10,%xmm2 cvtsi2ss -8(%rbp),%xmm3 divss %xmm3,%xmm2 movss %xmm2,-12(%rbp) cvtsi2ss -8(%rbp),%xmm2 mulss %xmm2,%xmm1 addss %xmm0,%xmm1 movss %xmm1,(%rax) movl (%rax),%edx movl %edx,-16(%rbp) leaq L_.str(%rip),%rdi movl -16(%rbp),%esi movb $0,%al callq _printf movl %eax,-20(%rbp) ## 4-byte Spill ## BB#3: ## in Loop: Header=BB0_1 Depth=1 movl -8(%rbp),%eax addl $1,%eax movl %eax,-8(%rbp) jmp LBB0_1 LBB0_4: movl -4(%rbp),%eax addq $32,%rsp popq %rbp ret (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |