是否有可能找到不适合%.6g的浮子

时间:2019-09-20 18:15:24

标签: c floating-point precision

让我们假设我们总是具有相同的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 个答案:

答案 0 :(得分:2)

对于x = 0.0001220703052240423858165740966796875frestored_x不等于x。即使将%.6g更改为.8grestored_x也不等于x;它将是0.0001220703125。

(假设C实现将{-{1}}使用IEEE-754 binary32,并使用近似于最近的关系到偶数来校正舍入,而C标准则不需要。)

答案 1 :(得分:1)

6(FLT_DIG)是可以从十进制到float并返回到十进制而不会丢失的十进制数字的最大数目。区分接近但不相等的float不足;存在不相等的float值,这些值将与%.6g相同地打印。在最坏的情况下,您需要FLT_DECIMAL_DIG(9)位数字来安全地将float通过小数字符串往返,并且还需要更多的数字来精确地以十进制表示值 。 / p>