首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C语言进行整数铸造浮点数比较

问用C语言进行整数铸造浮点数比较
EN

Stack Overflow用户
提问于 2014-03-28 14:35:39
回答 1查看 337关注 0票数 5

我想得到一个准确/准确的答案,为什么下面的代码输出不同的结果:

代码语言:javascript
复制
#include "stdio.h"
int main(void)
{
    int a = 9;
    int b = 10;
    printf("%d\n", (double)a / (double)b == 0.9); /* prints 0 */
    printf("%d\n", (double)9 / (double)10 == 0.9); /* prints 1 */
    return 0;
}

我认为这可能是编译器依赖的,我的是gcc (GCC mingw Windows7) 4.8.1和be (Debian4.7.2-5) 4.7.2。

非常感谢!

更新!

我生成了带有和不使用-std=c99选项的程序集代码,这应该有助于理解这里正在发生的事情。

如果没有-std=c99 (这将给出结果0/1):

代码语言:javascript
复制
    .file    "a.c"
    .section .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string  "%d\n"
    .section .text.startup,"ax",@progbits
    .p2align 4,,15
    .globl   main
    .type    main, @function
main:
.LFB11:
    .cfi_startproc
    pushl %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl %esp, %ebp
    .cfi_def_cfa_register 5
    andl $-16, %esp
    subl $16, %esp
    movl $1, 4(%esp)
    movl $.LC0, (%esp)
    call printf
    movl $1, 4(%esp)
    movl $.LC0, (%esp)
    call printf
    xorl %eax, %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE11:
    .size    main, .-main
    .ident   "GCC: (Debian 4.7.2-5) 4.7.2"
    .section .note.GNU-stack,"",@progbits

使用-std=c99 (这给出了结果1/1):

代码语言:javascript
复制
    .file    "a.c"
    .section .rodata
.LC1:
    .string "%d\n"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushl %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    andl    $-16, %esp
    subl    $32, %esp
    movl    $9, 28(%esp)
    movl    $10, 24(%esp)
    fildl   28(%esp)
    fildl   24(%esp)
    fdivrp  %st, %st(1)
    movl    $1, %edx
    fldt    .LC0
    fucomp  %st(1)
    fnstsw  %ax
    sahf
    jp      .L5
    fldt    .LC0
    fucompp
    fnstsw  %ax
    sahf
    je      .L2
    jmp     .L3
.L5:
    fstp    %st(0)
.L3:
    movl    $0, %edx
.L2:
    movzbl  %dl, %eax
    movl    %eax, 4(%esp)
    movl    $.LC1, (%esp)
    call    printf
    movl    $1, 4(%esp)
    movl    $.LC1, (%esp)
    call    printf
    movl    $0, %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE0:
    .size main, .-main
    .section .rodata
    .align 16
.LC0:
    .long    1717986918
    .long    -429496730
    .long    16382
    .ident   "GCC: (Debian 4.7.2-5) 4.7.2"
    .section .note.GNU-stack,"",@progbits
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-28 15:05:56

在C中,允许以比代码指示的更高的精度运行浮点数学。

特别是编译时数学(第2行)可以作为long double运行。

C11dr§5.2.4.2.2 9“除赋值和转换(这消除了所有额外的范围和精度)外,带有浮动操作数的运算符产生的值以及受通常算术转换的值和浮动常数的值,都被计算成一种格式,其范围和精度可能大于该类型所要求的范围和精度。

见上面的Patricia Shanahan。

编辑

如果定义了FP评估模式,请检查

代码语言:javascript
复制
#include <float.h>
printf("%d\n", FLT_EVAL_METHOD);

C11dr§5.2.4.2.2 9(续)评估格式的使用以FLT_EVAL_METHOD的实现定义值为特征。

-1不确定;

0只根据类型的范围和精度评估所有操作和常数;

1计算浮子型的运算量和常数,双倍于双型的范围和精度,用长双型的范围和精度评价长双运算和常数;

2根据长双类型的范围和精度评估所有操作和常量。

FLT_EVAL_METHOD的所有其他负值都描述了实现定义的行为。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22715793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档