打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
c – fmod返回不一致的值

尝试使用一些perlin噪声函数时,遇到一个奇怪的错误.突然间,我在所有电话中间都获得了一个off值.将其追溯到fmod()中的不一致返回值.

i=512;cout << i << ","  << fmod(i/102.4,1.f) << "," << fmod(i/102.4,1.f) << endl;

我希望得到以下输出.

512,0,0

但我没有.我明白了

512,0,1

更奇怪的是,如果我多次调用cout线,则错误会在以后的运行中消失.

512,0,1512,0,0512,0,0

将值硬编码到函数中(将所有’y’替换为’512′)会得到正确的结果(始终返回0).

有没有人见过这样的结果?

解决方法:

最终编辑:这几乎肯定是GCC或glibc中的一个错误.简单地声明一个在代码中的其他地方调用fmod的函数(即使该函数没有被调用)也会使问题消失.

我建议将-fno-builtins传递给编译器来解决这个问题. Thas似乎为我解决了这个问题.

我可以在GCC 4.5.3中为cygwin重现这一点.

只有当i变量是非const时才会发生这种情况[编辑:可能是因为它鼓励编译器使用临时存储初始除法的结果).我测试的更简单的C程序:

#include <stdio.h>#include <math.h>int main(){    int i = 512;    printf("%f %f\n", fmod(i/102.4,1.f), fmod(i/102.4,1.f));    printf("%f %f\n", fmod(i/102.4,1.f), fmod(i/102.4,1.f));}

哪个输出:

0.000000 1.0000000.000000 0.000000

我试过查看asm输出,但我的x87-foo很弱.任何人都可以看到什么是错的吗?我会一直在寻找:

    .file   "test.cpp"    .section    .debug_abbrev,"dr"Ldebug_abbrev0:    .section    .debug_info,"dr"Ldebug_info0:    .section    .debug_line,"dr"Ldebug_line0:    .textLtext0:    .def    ___main;    .scl    2;  .type   32; .endef    .section .rdata,"dr"LC3:    .ascii "%f %f\12\0"    .text.globl _main    .def    _main;  .scl    2;  .type   32; .endef_main:LFB7:    .file 1 "test.cpp"    .loc 1 6 0    pushl   �pLCFI0:    movl    %esp, �pLCFI1:    andl    $-16, %espLCFI2:    subl    $64, %espLCFI3:    .loc 1 6 0    call    ___mainLBB2:    .loc 1 7 0    movl    $512, 60(%esp)    .loc 1 8 0    fildl   60(%esp)    fldl    LC0    fdivrp  %st, %st(1)    fld1    fld %st(1)L2:    fprem    fnstsw  %ax    sahf    jp  L2    fstp    %st(1)    fucomi  %st(0), %st    jp  L5    fucomi  %st(0), %st    je  L6    fstp    %st(0)    jmp L4L5:    fstp    %st(0)L4:    fld1    fstpl   8(%esp)    fstpl   (%esp)    call    _fmod    jmp L3L6:    fstp    %st(1)L3:    fstpl   40(%esp)    fildl   60(%esp)    fldl    LC0    fdivrp  %st, %st(1)    fld1    fstpl   8(%esp)    fstpl   (%esp)    call    _fmod    fldl    40(%esp)    fstpl   12(%esp)    fstpl   4(%esp)    movl    $LC3, (%esp)    call    _printf    .loc 1 9 0    fildl   60(%esp)    fldl    LC0    fdivrp  %st, %st(1)    fld1    fstpl   8(%esp)    fstpl   (%esp)    call    _fmod    fstpl   32(%esp)    fildl   60(%esp)    fldl    LC0    fdivrp  %st, %st(1)    fld1    fstpl   8(%esp)    fstpl   (%esp)    call    _fmod    fldl    32(%esp)    fstpl   12(%esp)    fstpl   4(%esp)    movl    $LC3, (%esp)    call    _printfLBE2:    movl    $0, �x    .loc 1 10 0    leaveLCFI4:    retLFE7:    .section .rdata,"dr"    .align 8LC0:    .long   -1717986918    .long   1079613849    .section    .debug_frame,"dr"Lframe0:    .long   LECIE0-LSCIE0LSCIE0:    .long   0xffffffff    .byte   0x1    .ascii "\0"    .uleb128 0x1    .sleb128 -4    .byte   0x8    .byte   0xc    .uleb128 0x4    .uleb128 0x4    .byte   0x88    .uleb128 0x1    .align 4LECIE0:LSFDE0:    .long   LEFDE0-LASFDE0LASFDE0:    .secrel32   Lframe0    .long   LFB7    .long   LFE7-LFB7    .byte   0x4    .long   LCFI0-LFB7    .byte   0xe    .uleb128 0x8    .byte   0x85    .uleb128 0x2    .byte   0x4    .long   LCFI1-LCFI0    .byte   0xd    .uleb128 0x5    .byte   0x4    .long   LCFI4-LCFI1    .byte   0xc5    .byte   0xc    .uleb128 0x4    .uleb128 0x4    .align 4LEFDE0:    .section    .eh_frame,"w"Lframe1:    .long   LECIE1-LSCIE1LSCIE1:    .long   0x0    .byte   0x1    .ascii "\0"    .uleb128 0x1    .sleb128 -4    .byte   0x8    .byte   0xc    .uleb128 0x4    .uleb128 0x4    .byte   0x88    .uleb128 0x1    .align 4LECIE1:LSFDE3:    .long   LEFDE3-LASFDE3LASFDE3:    .long   LASFDE3-Lframe1    .long   LFB7    .long   LFE7-LFB7    .byte   0x4    .long   LCFI0-LFB7    .byte   0xe    .uleb128 0x8    .byte   0x85    .uleb128 0x2    .byte   0x4    .long   LCFI1-LCFI0    .byte   0xd    .uleb128 0x5    .byte   0x4    .long   LCFI4-LCFI1    .byte   0xc5    .byte   0xc    .uleb128 0x4    .uleb128 0x4    .align 4LEFDE3:    .textLetext0:    .section    .debug_loc,"dr"Ldebug_loc0:LLST0:    .long   LFB7-Ltext0    .long   LCFI0-Ltext0    .word   0x2    .byte   0x74    .sleb128 4    .long   LCFI0-Ltext0    .long   LCFI1-Ltext0    .word   0x2    .byte   0x74    .sleb128 8    .long   LCFI1-Ltext0    .long   LCFI4-Ltext0    .word   0x2    .byte   0x75    .sleb128 8    .long   LCFI4-Ltext0    .long   LFE7-Ltext0    .word   0x2    .byte   0x74    .sleb128 4    .long   0x0    .long   0x0    .section    .debug_info,"dr"    .long   0x13a    .word   0x2    .secrel32   Ldebug_abbrev0    .byte   0x4    .uleb128 0x1    .ascii "GNU C   4.5.3\0"    .byte   0x4    .ascii "test.cpp\0"    .ascii "/home/martin\0"    .long   Ltext0    .long   Letext0    .secrel32   Ldebug_line0    .uleb128 0x2    .byte   0x4    .byte   0x7    .ascii "unsigned int\0"    .uleb128 0x2    .byte   0x1    .byte   0x6    .ascii "char\0"    .uleb128 0x2    .byte   0x1    .byte   0x6    .ascii "signed char\0"    .uleb128 0x2    .byte   0x1    .byte   0x8    .ascii "unsigned char\0"    .uleb128 0x2    .byte   0x2    .byte   0x5    .ascii "short int\0"    .uleb128 0x2    .byte   0x2    .byte   0x7    .ascii "short unsigned int\0"    .uleb128 0x2    .byte   0x4    .byte   0x5    .ascii "int\0"    .uleb128 0x2    .byte   0x8    .byte   0x5    .ascii "long long int\0"    .uleb128 0x2    .byte   0x8    .byte   0x7    .ascii "long long unsigned int\0"    .uleb128 0x2    .byte   0x4    .byte   0x5    .ascii "long int\0"    .uleb128 0x2    .byte   0x4    .byte   0x7    .ascii "long unsigned int\0"    .uleb128 0x2    .byte   0x8    .byte   0x4    .ascii "double\0"    .uleb128 0x2    .byte   0x4    .byte   0x4    .ascii "float\0"    .uleb128 0x2    .byte   0xc    .byte   0x4    .ascii "long double\0"    .uleb128 0x3    .byte   0x1    .ascii "main\0"    .byte   0x1    .byte   0x5    .long   0x98    .long   LFB7    .long   LFE7    .secrel32   LLST0    .uleb128 0x4    .long   LBB2    .long   LBE2    .uleb128 0x5    .ascii "i\0"    .byte   0x1    .byte   0x7    .long   0x98    .byte   0x2    .byte   0x74    .sleb128 60    .byte   0x0    .byte   0x0    .byte   0x0    .section    .debug_abbrev,"dr"    .uleb128 0x1    .uleb128 0x11    .byte   0x1    .uleb128 0x25    .uleb128 0x8    .uleb128 0x13    .uleb128 0xb    .uleb128 0x3    .uleb128 0x8    .uleb128 0x1b    .uleb128 0x8    .uleb128 0x11    .uleb128 0x1    .uleb128 0x12    .uleb128 0x1    .uleb128 0x10    .uleb128 0x6    .byte   0x0    .byte   0x0    .uleb128 0x2    .uleb128 0x24    .byte   0x0    .uleb128 0xb    .uleb128 0xb    .uleb128 0x3e    .uleb128 0xb    .uleb128 0x3    .uleb128 0x8    .byte   0x0    .byte   0x0    .uleb128 0x3    .uleb128 0x2e    .byte   0x1    .uleb128 0x3f    .uleb128 0xc    .uleb128 0x3    .uleb128 0x8    .uleb128 0x3a    .uleb128 0xb    .uleb128 0x3b    .uleb128 0xb    .uleb128 0x49    .uleb128 0x13    .uleb128 0x11    .uleb128 0x1    .uleb128 0x12    .uleb128 0x1    .uleb128 0x40    .uleb128 0x6    .byte   0x0    .byte   0x0    .uleb128 0x4    .uleb128 0xb    .byte   0x1    .uleb128 0x11    .uleb128 0x1    .uleb128 0x12    .uleb128 0x1    .byte   0x0    .byte   0x0    .uleb128 0x5    .uleb128 0x34    .byte   0x0    .uleb128 0x3    .uleb128 0x8    .uleb128 0x3a    .uleb128 0xb    .uleb128 0x3b    .uleb128 0xb    .uleb128 0x49    .uleb128 0x13    .uleb128 0x2    .uleb128 0xa    .byte   0x0    .byte   0x0    .byte   0x0    .section    .debug_pubnames,"dr"    .long   0x17    .word   0x2    .secrel32   Ldebug_info0    .long   0x13e    .long   0x10d    .ascii "main\0"    .long   0x0    .section    .debug_pubtypes,"dr"    .long   0xe    .word   0x2    .secrel32   Ldebug_info0    .long   0x13e    .long   0x0    .section    .debug_aranges,"dr"    .long   0x1c    .word   0x2    .secrel32   Ldebug_info0    .byte   0x4    .byte   0x0    .word   0x0    .word   0x0    .long   Ltext0    .long   Letext0-Ltext0    .long   0x0    .long   0x0    .def    _fmod;  .scl    2;  .type   32; .endef    .def    _printf;    .scl    2;  .type   32; .endef

[编辑:注意,它总是第一次调用fmod返回奇怪的结果(从来没有一个). fmod调用正在从右到左进行评估.

[编辑2:定义一个函数,加倍my_fmod(double a,double b){return fmod(a,b);通过调用传递调用会使问题消失. ]

来源:https://www.icode9.com/content-4-355951.html
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
汇编指令速查
茉莉酸检测
Ted's Blog
C/C++程序到内存分配个人总结
鸡蛋药物残留研究进展
关于LedControl库发个例子
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服