让我们假设我们总是具有相同的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
进行序列化的函数中的输入。
答案 0 :(得分:2)
对于x = 0.0001220703052240423858165740966796875f
,restored_x
不等于x
。即使将%.6g
更改为.8g
,restored_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>