10

编译器:来自 Nuwen 发行版的 64 位 MinGW G++ 4.9.1,在 Windows 8.1 下。

代码:

#ifdef INCLUDE_IOSTREAM
#   include <iostream>
#endif
#include <stdio.h>      // ::snprintf
#include <stdlib.h>     // EXIT_SUCCESS, EXIT_FAILURE
#include <stdexcept>    // std::exception

#ifdef snprintf
#   error snprintf defined as macro
#endif

#ifdef _MSC_VER
    auto const snprintf = _snprintf;
#endif

void test( double const value, int const precision)
{
    char buffer[34];
    snprintf( buffer, sizeof( buffer ), "%.*a", precision, value );
    printf( "Hex of %.3f with %2d digits: %s\n", value, precision, buffer );
}

auto main() -> int
{
    using namespace std;
    try
    {
        for( int precision = 6; precision <= 8; ++precision )
        {
            test( 5.0, precision );
        }
        test( 0.0, 14 );
        return EXIT_SUCCESS;
    }
    catch( exception const& x )
    {
        fprintf( stderr, "!%s\n", x.what() );
    }
    return EXIT_FAILURE;
}

适用于 Visual C++(但 Visual C++ 似乎缺少相反的转换):

H:\dev\test\so\0187> cl /nologo- /? 2>&1 | 查找 /i "ler ver"
Microsoft (R) C/C++ 优化编译器版本 18.00.30723 for x86

H:\dev\test\so\0187> cl barx.cpp -D INCLUDE_IOSTREAM /Feb
巴克斯.cpp

H:\dev\test\so\0187> b
6 位十六进制 5.000:0x1.400000p+2
具有 7 位数字的十六进制 5.000:0x1.4000000p+2
十六进制 5.000 8 位:0x1.40000000p+2
14 位十六进制 0.000:0x0.00000000000000p+0

H:\dev\test\so\0187>_

<iostream>包括在内时也适用于 g++ :

H:\dev\test\so\0187> g++ --version | 找到“++”
g++ (GCC) 4.9.1

H:\dev\test\so\0187> g++ -std=c++11 barx.cpp

H:\dev\test\so\0187>一个
6 位 5.000 的十六进制数:0x1.400000p+2
5.000 的十六进制,7 位数字:0x1.4000000p+2
8 位 5.000 的十六进制数:0x1.40000000p+2
14 位 0.000 的十六进制数:0x0.00000000000000p+0

H:\dev\test\so\0187>_

包含以下内容时会出现奇怪的结果<iostream>

H:\dev\test\so\0187> g++ -std=c++11 -D INCLUDE_IOSTREAM barx.cpp

H:\dev\test\so\0187>一个
6 位 5.000 的十六进制数:0xa.000000p-1
5.000 的十六进制,7 位数字:0xa.0000000p-1
5.000 的十六进制,8 位数字:0x0.00000000p-33            ← 奇怪。
^C                                                       ← 挂起,Ctrl+C
H:\dev\test\so\0187>_

我要求修复或解决方法。

4

1 回答 1

4

Microsoft 的实现有许多printf错误,默认情况下会影响 MinGW(#377#407等)。

在所有情况下,建议似乎都是在预处理器中定义__USE_MINGW_ANSI_STDIO1使用 MinGW 自己的 ANSI 兼容实现。

据推测,Visual Studio 有自己的内部解决方法来解决底层系统代码中的缺陷。

于 2014-12-06T21:12:01.477 回答