Можно ли найти поплавок, который не подходит к% .6g - PullRequest
0 голосов
/ 20 сентября 2019

Предположим, что у нас всегда один и тот же языковой стандарт C.

Можно ли найти такое число с плавающей точкой value, которое в коде ниже restored_x != value

float x = value;
char s[32];
sprintf(s, "%.6g", x);//do not use snprintf for simplicity
float restored_x = 0.;
sscanf(s, "%g", &restored_x);

Другими словами, янайдите код, который использует %.6g для сериализации, и, как я знаю, десятичное представление двоичного числа с плавающей запятой не точно 6 цифр после "точки", оно может быть 7 или более.Но я не могу найти такое число (значение! = Restore_x), если оно существует?

Я не принимаю во внимание NaN и + -Inf и т. Д. В особом случае, потому что есть утверждения, которые проверяют ввод вфункция, которая использует %.6g для сериализации.

Ответы [ 2 ]

2 голосов
/ 20 сентября 2019

Для x = 0.0001220703052240423858165740966796875f, restored_x не равно x.Даже если %.6g изменяется на .8g, restored_x не будет равен x;это будет 0,0001220703125.

(Это предполагает, что реализация C использует двоичный код IEEE-754 для float и правильное округление с округлением до ближайшего равенства, даже того, что не требуется стандартом C.)

1 голос
/ 20 сентября 2019

6 (FLT_DIG) - это максимальное количество десятичных цифр, которое может быть округлено от десятичного до float и обратно до десятичного без потери. не достаточно для различения float значений, которые близки, но не равны;существуют неравные float значения, которые будут печататься одинаково с %.6g.Вам нужно FLT_DECIMAL_DIG (9) цифр для безопасного обхода float через десятичную строку в худшем случае и гораздо больше, чтобы представить значение точно в десятичном виде.

...