2017-01-09 4 views
3

、私は次のテストコードを持っている:VS2013:strtofがERANGEに設定されていませんか? Visual Studioの2013年に

#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
int main (int argc, const char* argv[]) 
{ 
    static const char* floatStr = "3.40282346638528859811704183485E+39"; 
    static const char* doubleStr = "1.79769313486231570814527423732E+309"; 

    char* end; 
    float floatVal = 42.0f; 
    double doubleVal = 42.0; 

    errno = 0; 
    floatVal = strtof(floatStr, &end); 
    printf("Conversion of '%s':\nfloatVal=%f\nerrno='%s'\n", 
     floatStr, 
     floatVal, 
     strerror(errno)); 

    errno = 0; 
    doubleVal = strtod(doubleStr, &end); 
    printf("Conversion of '%s':\ndoubleVal=%f\nerrno='%s'\n", 
     doubleStr, 
     doubleVal, 
     strerror(errno)); 

    return 0; 
} 

意図は非常に大きい(オーバーフロー)入力にstrtof()とは、strtod()関数を使用するときに観察された挙動を示すことです。

私が見つけたのは、strtof()関数はfloat値を+ INFに設定し、ERANGEのerrnoは設定しないことです。 strtod()関数は、しかし、+ INFにdouble値を設定し、ERANGE errnoにを設定します。

Conversion of '3.40282346638528859811704183485E+39': 
floatVal=1.#INF00 
errno='No error' 
Conversion of '1.79769313486231570814527423732E+309': 
doubleVal=1.#INF00 
errno='Result too large' 

が期待されるこの動作で、またはそれは実装固有のニュアンスでしょうか?

サイドノート:strtof()がstrtod()を呼び出していて、doubleからfloatへのキャストが+ INF結果を生成した後に適切にerrnoを設定していないようです。

+1

MSVC 2015は、どちらの場合も* errno = 'Result too large' *を返します。修正されたバグでなければなりません。 –

+1

'strtof'関数が' strtod'を '' 1.01161128282547 "'のような文字列で 'strtof'で構文解析することで実装されているかどうかを調べることができます。この小数の表現が 'double'として解析され、最も近い' float'に丸められた場合、文字列が 'float'("二重丸め ")として直接解析された場合とは異なる結果を生成します。このように実装された 'strtof'関数は、オーバーフローが正しく処理されたとしても、この理由で品質が悪いものです。質の高い 'strtof'は浮動小数点' 1.01161134f'を生成します。貧弱な 'strtof'は' 1.01161122f'を生成します。 –

+0

@WeatherVane私はVS2015で試行し、答えをマークします – Squirrel

答えて

3

WeatherVaneが指摘しているように、これはVS2015では発生せず、VS2013の実装にはバグがあるようです。

関連する問題