我正在从一个字符串中读取浮点数。浮点数可以用各种形式表示,因此
float f1 = strtof("999999999999.16");
float f2 = stof("000999999999999.1600000");
assert(f1 == f2);
我能确保这个断言始终是正确的吗?无论前导零和末尾零如何,分隔符永远是一个点(“.”),因为stof
不能处理逗号(“,”)。
我正在从一个字符串中读取浮点数。浮点数可以用各种形式表示,因此
float f1 = strtof("999999999999.16");
float f2 = stof("000999999999999.1600000");
assert(f1 == f2);
我能确保这个断言始终是正确的吗?无论前导零和末尾零如何,分隔符永远是一个点(“.”),因为stof
不能处理逗号(“,”)。
C11标准中的7.22.1.3p9对于C语言的strtof
/strtod
/strtold
(至少从cppreference上看,这些函数应该是C++版本所使用的)有如下规定:
如果主体序列具有小数形式,并且最多有
DECIMAL_DIG
(在<float.h>
中定义)个有效数字,则结果应正确舍入。
考虑到你的两行代码都具有相同数量的有效数字,它们应该表现相同。但这仅仅是基于标准在此处提到“有效数字”的推测;在其他任何地方都没有提到,标准也没有关于前导零(小数点之前)或尾随零(小数点之后)的更明确说明。
strtof
吗? Cplusplus 提到 stof
使用的是 strtod
,但并未提及与 stof
相似的内容。 - 463035818_is_not_a_numberstof
在 C++17 之前调用 strtod
,在 C++17 中将调用 strtof
。 - NathanOliverC++14(§21.5)标准规定:
在很多情况下,它们将是相同的,但中间的“double”确实打开了双重舍入的潜力。例如,如果
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
,则函数会将str
的第一个未转换的元素的索引存储在*idx
中。
str = "1.0000000596046448"
,那么最接近的float
(假设IEEE754算术)是1.0000001f
,而最接近的double
正好在1.0f
和1.0000001f
之间,因此随后转换为float
将向下舍入为1.0f
。
stof
在内部调用strtod
,所以我不知道这是否会有所不同。在C++17中,它将在内部调用strtof
,因此那时应该是有保证的。 - NathanOliver