是stof,strtof确定性?

时间:2016-10-06 16:14:18

标签: c++ floating-point deterministic

我正在读取字符串中的浮点数。它们可以以各种形式编写,所以

float f1 = strtof("999999999999.16");
float f2 = stof("000999999999999.1600000");
assert(f1 == f2);

我可以确定断言将始终为真,无论前导和尾随零?分隔符将始终为点,stof不会处理逗号。

2 个答案:

答案 0 :(得分:3)

The C11 standard, in 7.22.1.3p9,这是关于C的strtof / strtod / strtold(这应该是C ++版本在其下使用的内容,至少从{{3判断) }}):

  

如果主题序列具有小数形式且最多为DECIMAL_DIG(在<float.h>中定义)有效数字,则结果应正确舍入。

鉴于您的两个代码行具有相同的有效位数,它们 的行为应该相同。但这仅仅是基于标准在这里提到“有效数字”这一事实的推测;在其他任何地方都没有提到它,标准没有更明确地说明前导(小数点前)或尾随(小数点后)零。

答案 1 :(得分:1)

C ++ 14(§21.5)标准规定:

  

float stof(const string& str, size_t* idx = 0);

     

double stod(const string& str, size_t* idx = 0);

     

long double stold(const string& str, size_t* idx = 0);

     

效果:前两个函数调用strtod(str.c_str(), ptr),第三个函数调用strtold( str.c_str(), ptr)。每个函数返回转换后的结果(如果有)。参数ptr指定一个指向函数内部对象的指针,该对象用于确定在*idx存储的内容。如果函数没有抛出异常并且idx != 0,则函数将*idx存储在str的第一个未转换元素的索引中。

因此,在许多情况下它们会相同,但中级double确实为double rounding打开了潜力。例如。如果str = "1.0000000596046448",则最接近的float(假设IEEE754算术)为1.0000001f,而最接近的double恰好位于1.0f1.0000001f之间,因此后续转换为float将向下舍入为1.0f

至少这是理论。但实际上,我无法重新创建:http://ideone.com/NMRy14