zoukankan      html  css  js  c++  java
  • 关于整形和浮点型的格式输出

    一个很好玩的现象:

    源代码:

    #include <stdio.h>
    
    int main()
    {
            int a = 10000;
            float b = 55.55;
            int c = 9988;
    
            printf("a : %f 
    ",a);
            printf("c : %f 
    ",c);
            printf("b : %d 
    ",(int)b);
            printf("a : %f 
    ",a);
            printf("c : %f 
    ",c);
            printf("b : %f 
    ",b);
            printf("a : %f 
    ",a);
            printf("c : %f 
    ",c);
            printf("b : %d 
    ",b);
    
            return 0;
    }

    输出:

    root@Ivy-debian-64:/home/zhangxu# ./a.out
    a : 0.000000
    c : 0.000000
    b : 55
    a : 0.000000
    c : 0.000000
    b : 55.549999
    a : 55.549999
    c : 55.549999
    b : -1645481984
    root@Ivy-debian-64:/home/zhangxu# ./a.out
    a : 0.000000
    c : 0.000000
    b : 55
    a : 0.000000
    c : 0.000000
    b : 55.549999
    a : 55.549999
    c : 55.549999
    b : 1511591936

    结果很奇怪,注意a、b以同样的格式输出时的不同结果。

     1     .file   "double_int.c"
     2         .section        .rodata
     3 .LC1:
     4         .string "a : %f 
    "
     5 .LC2:
     6         .string "c : %f 
    "
     7 .LC3:
     8         .string "b : %d 
    "
     9 .LC4:
    10         .string "b : %f 
    "
    11         .text
    12         .globl  main
    13         .type   main, @function
    14 main:
    15 .LFB0:
    16         .cfi_startproc
    17         pushq   %rbp
    18         .cfi_def_cfa_offset 16
    19         .cfi_offset 6, -16
    20         movq    %rsp, %rbp
    21         .cfi_def_cfa_register 6
    22         subq    $16, %rsp
    23         movl    $10000, -4(%rbp)
    24         movl    .LC0(%rip), %eax
    25         movl    %eax, -8(%rbp)
    26         movl    $9988, -12(%rbp)
    27         movl    -4(%rbp), %eax
    28         movl    %eax, %esi               //参数 %esi = 10000
    29         movl    $.LC1, %edi              //格式串 %edi
    30         movl    $0, %eax                 //0代表参数为整型 %eax (只是猜测,含义上不明确)
    31         call    printf                   //输出 0.000000 
    32 
    33         movl    -12(%rbp), %eax
    34         movl    %eax, %esi
    35         movl    $.LC2, %edi
    36         movl    $0, %eax
    37         call    printf                    //同上
    38 
    39         movss   -8(%rbp), %xmm0           //单精度浮点数移动指令
    40         cvttss2si       %xmm0, %eax       //单精度浮点数转换成整型,带截断,装入%eax  
    41         movl    %eax, %esi                //参数 %esi = 55
    42         movl    $.LC3, %edi           
    43         movl    $0, %eax
    44         call    printf
    45 
    46         movl    -4(%rbp), %eax
    47         movl    %eax, %esi
    48         movl    $.LC1, %edi
    49         movl    $0, %eax
    50         call    printf                    //xmm0中没有值,依然输出0.000000
    51 movl -12(%rbp), %eax 52 movl %eax, %esi 53 movl $.LC2, %edi 54 movl $0, %eax 55 call printf //同 line 50 56 57 movss -8(%rbp), %xmm0 58 cvtps2pd %xmm0, %xmm0 //单精度转换成双精度,装入xmm0 59 movl $.LC4, %edi //格式串 60 movl $1, %eax //1代表参数为浮点型 %eax 61 call printf //输出55.549999 62 63 movl -4(%rbp), %eax 64 movl %eax, %esi 65 movl $.LC1, %edi 66 movl $0, %eax 67 call printf //输出55.549999 68 69 movl -12(%rbp), %eax 70 movl %eax, %esi 71 movl $.LC2, %edi 72 movl $0, %eax 73 call printf //输出55.549999 74 75 movss -8(%rbp), %xmm0 76 cvtps2pd %xmm0, %xmm0
    #      movl $5555, %esi
    77 movl $.LC3, %edi 78 movl $1, %eax 79 call printf //输出任意值 80 81 movl $0, %eax 82 leave 83 .cfi_def_cfa 7, 8 84 ret 85 .cfi_endproc 86 .LFE0: 87 .size main, .-main 88 .section .rodata 89 .align 4 90 .LC0: 91 .long 1113469747 92 .ident "GCC: (Debian 4.7.2-5) 4.7.2" 93 .section .note.GNU-stack,"",@progbits

    可能的原因如下,

    如果格式串中有“%f”时,printf就会从xmm中读出相应的值,所以如果xmm中没有正确的值,就会输出0.000000。如果有,就会用此时xmm中的值,当成输入,这就是line 56、line 73输出55.549999(精度问题,如果是双精度浮点会输出55.550000)的原因。因为之前用“%f”输出b的时候,将xmm赋值了。

    如果格式串中有“%d”时,printf就从esi中读取相应的值,所以line 79会输出任意值,因为此时esi的值可能是任意的。如果在line 76和 line 77之间人为地给esi赋值为5555,就会输出b:5555。

    单精度和双精度的情况不同。

    参考:

    http://scc.qibebt.cas.cn/docs/optimization/VTune(TM)%20User's%20Guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/instruct32_hh/vc203.htm

    http://scc.qibebt.cas.cn/docs/optimization/VTune(TM)%20User's%20Guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/instruct32_hh/vc55.htm

    http://scc.qibebt.cas.cn/docs/optimization/VTune(TM)%20User's%20Guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/instruct32_hh/vc68.htm

    http://scc.qibebt.cas.cn/docs/optimization/VTune(TM)%20User's%20Guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/instruct32_hh/vc202.htm

     
  • 相关阅读:
    走线规范-标识
    python学习之网路操作
    python学习之函数
    RTT学习之软件包
    RT_THREAD之组件学习
    RT_THREAD之nano学习
    物联网相关的模块
    JavaScript学习笔记之二
    javascript完美实现图片拖动改变顺序
    响应式WEB设计的9项基本原则
  • 原文地址:https://www.cnblogs.com/godjesse/p/3329260.html
Copyright © 2011-2022 走看看