是静止的,是完全确定的
Is stof, strtof deterministic?
我正在从字符串中读取浮点数。它们可以写成各种形式,因此
float f1 = strtof("999999999999.16");
float f2 = stof("000999999999999.1600000");
assert(f1 == f2);
我可以确定断言总是为真,无论前导零和后置零如何?分隔符总是一个点,stof
不处理逗号。
C11标准,在7.22.1.3p9中,对C的strtof
/strtod
/strtold
(这应该是c++版本下面使用的,至少从cppreference判断)有这样的说法:
如果主题序列具有十进制形式并且最多
DECIMAL_DIG
位有效数字(在<float.h>
中定义),则结果应正确舍入。
假设你的两行代码有相同的有效位数,它们应该表现相同。但这仅仅是一种猜测,因为标准在这里根本就没有提到"有效数字";在其他任何地方都没有提到它,并且标准没有更明确地说明前导(小数点之前)或尾随(小数点之后)零。
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
确实打开了双舍入的可能性。例如,如果str = "1.0000000596046448"
,那么最接近的float
(假设IEEE754算法)是1.0000001f
,而最接近的double
正好在1.0f
和1.0000001f
之间,因此随后转换到float
将四舍五入到1.0f
。
至少理论上是这样的。但是,在实践中,我无法重新创建:http://ideone.com/NMRy14