Я читаю поплавки из строки. Они могут быть написаны в различной форме, поэтому
float f1 = strtof("999999999999.16");
float f2 = stof("000999999999999.1600000");
assert(f1 == f2);
Могу ли я быть уверен, что утверждение будет всегда верным, независимо от начальных и конечных нулей? Разделитель всегда будет точкой, stof
не обрабатывает запятую.
Стандарт С11, в 7.22.1.3р9, есть что сказать о С 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