比较从字符串转换的浮点值与文字

Jab*_*cky 24 c c++ floating-point language-lawyer

这并不是着名的浮动点数学的重复,即使它看起来像乍一看.

我正在double从一个文本文件中读取一个文件fscanf(file, "%lf", &value);,并将其与==操作符进行比较,并与双文字进行比较.如果字符串是相同的文字,将使用对比==true在所有情况下?

文字文件内容:

7.7
Run Code Online (Sandbox Code Playgroud)

代码段:

double value;
fscanf(file, "%lf", &value);     // reading "7.7" from file into value

if (value == 7.7)
   printf("strictly equal\n");
Run Code Online (Sandbox Code Playgroud)

预期和实际产出是

strictly equal
Run Code Online (Sandbox Code Playgroud)

但是这假设编译器将双文字7.7转换为与fscanf函数完全相同的双精度,但编译器可能会也可能不会使用相同的库将字符串转换为double.

或者另外要求:从字符串到double的转换是否会导致唯一的二进制表示形式,或者可能存在轻微的实现依赖性差异?

现场演示

Ric*_*ges 18

从c ++标准:

[lex.fcon]

...如果缩放值在其类型的可表示值范围内,则结果是可表示的缩放值,否则最接近缩放值的较大或较小可表示值,以实现定义的方式选择 ...

强调我的.

因此,如果值可以通过double严格表示,则只能依赖于相等性.

  • @RichardHodges什么是_ [lex.fcon] _? (2认同)
  • 这当然听起来是最安全的假设.我的经验是,很容易被这样的事情所灼伤.首先,我不确定我有多信任`fscanf`完成的转换,以匹配编译器在编译时完成的转换.另一个原因是值有时最终会出现在寄存器中,其精度高于预期.但如果表示精确到双,那么它似乎应该是安全的. (2认同)

YSC*_*YSC 17

关于C++,从cppreference可以读到:

[lex.fcon] (§6.4.4.2)

评估浮点常量的结果是最接近的可表示值或紧邻最近的可表示值的较大或较小的可表示值,以实现定义的方式选择(换句话说,转换期间的默认舍入方向是实现定义的) .

由于未指定浮动文字的表示,我猜你无法总结它与scanf结果的比较.


关于C11(标准ISO/IEC 9899:2011):

[lex.fcon] (§6.4.4.2)

推荐做法

7浮动常量的转换时转换应与库函数的字符串执行时转换strtod相匹配,例如,给定适合两种转换的匹配输入,相同的结果格式和默认的执行时间舍入.

很明显,对于C11来说,这并不能保证匹配.

  • @MichaelWalz>你标记了C和C++.我想知道他们是否同意那个.在[C99](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf)中,规范性附录F第7.2小节内容如下:"在翻译期间,IEC 60559的默认模式是效果: - 舍入方向模式四舍五入到最接近的[...]".因此,只要您不更改代码的浮点环境,您的示例代码就可以保证在C99中工作. (2认同)