类型转换中的错误!在MSVC和GCC中都有

时间:2014-08-06 11:04:56

标签: c++ visual-c++ gcc

从(unsigned long long)更改为(double)时发生错误。错误很小,只在某些数字中发生,但它就在那里。 MSVC和GCC中的错误相同。

检查自己:

#include <stdio.h>

int main( void ) 
{
             long long a = 834146832894220100LL;
    unsigned long long b = 834146832894220100ULL;

    printf( "%.16f\n%.16f\n",
        (( double )a / 1e+18),
        (( double )b / 1e+18)
    );

    getchar( );
    return 0;
}

结果是:

0.8341468328942201
0.8341468328942202

这是来自MSVC的asm代码:

// long long a = 834146832894220100LL;
    mov         dword ptr [a],12D5744h
    mov         dword ptr [ebp-20h],0B937C20h
// unsigned long long b = 834146832894220100ULL;
    mov         dword ptr [b],12D5744h
    mov         dword ptr [ebp-30h],0B937C20h
// This is unsigned to double conversion:
    mov         eax,dword ptr [b] 
    mov         ecx,dword ptr [ebp-30h] 
    mov         dword ptr [ebp-100h],eax 
    mov         dword ptr [ebp-0FCh],ecx 
    mov         edx,dword ptr [ebp-0FCh] 
    mov         dword ptr [ebp-104h],edx 
    and         dword ptr [ebp-0FCh],7FFFFFFFh 
    fild        qword ptr [ebp-100h] 
    and         dword ptr [ebp-104h],80000000h 
    mov         dword ptr [ebp-108h],0 
    fild        qword ptr [ebp-108h] 
    fchs             
    faddp       st(1),st 
    fdiv        qword ptr [__real@43abc16d674ec800 (0C07870h)]
    mov         esi,esp 
    sub         esp,8 
    fstp        qword ptr [esp] 
// This is signed to double conversion:
    fild        qword ptr [a] 
    fdiv        qword ptr [__real@43abc16d674ec800 (0C07870h)] 
    sub         esp,8 
    fstp        qword ptr [esp]

您有什么看法?

1 个答案:

答案 0 :(得分:1)

我在i386上反汇编了gcc 4.9.1中生成的代码。它为每个产生了相同的确切代码。我猜你的编译器在内部进行不同的评估,具体取决于类型。您可以尝试不同的优化级别和/或更改已签名与未签名的顺序。 它也可能是printf代码中的一个错误,它与为转换为文本的第一个/其余部分设置舍入模式有所不同。