【问题标题】:Correct strtod implementation?正确的 strtod 实现?
【发布时间】:2011-10-18 23:40:30
【问题描述】:

简单的问题:数字 1.15507e-173 的正确位表示形式是双精度吗? 完整的问题:如何确定这个数字的正确解析?

背景:我的问题来自this answer,它显示了来自三个不同解析器的两个不同位表示,即

0x1c06dace8bda0ee0

0x1c06dace8bda0edf

我想知道哪个解析器做对了。

更新the C99 specification 的第 6.4.4.2 节说对于 C 解析器,

"...the result is either the nearest representable value, or the larger
or smaller representable value immediately adjacent to the nearest
representable value, chosen in an implementation-defined manner."

这意味着解析的数字不需要是最近的,甚至不需要是两个相邻的可表示数字之一。 7.20.1.3 中的相同规范说 strtod() 的行为方式与内置解析器基本相同。感谢指出这一点的回答者。

另请参阅this answer 来回答类似的问题,以及this blog

【问题讨论】:

  • C 解析器说什么?我相信 GCC 4.6 在内部使用 MPFR,所以我希望结果尽可能准确。
  • 没有“正确”——我假设没有检查这两个答案都在 1.15507e-173 的数学精确值的一个 ULP 之内,因为它们之间只有 1 个 ULP。 C 标准没有说明实现必须产生哪一个。 IEEE 754 定义了舍入模式,但我不知道它是否说明了它们如何影响strtod
  • 为什么还是这个特定的数字?这与最近的一些错误有关吗?
  • @Steve,注释 305 似乎暗示编译指示 STDC FENC_ACCESS 影响 strtod。
  • @Kerrek,这个数字没有特别的意义;这只是我发现的一个差异。 C 解析器给出第一个值,我系统的 strtod() 也是如此。

标签: c floating-point strtod


【解决方案1】:
:= num1 = ImportString["\.1c\.06\.da\.ce\.8b\.da\.0e\.e0", "Real64", ByteOrdering->1] // First; := num2 = ImportString["\.1c\.06\.da\.ce\.8b\.da\.0e\.df", "Real64", ByteOrdering->1] // First; := SetPrecision[num1, Infinity]-numOr //N := numOr = SetPrecision[1.15507, Infinity] * 10^-173; -190 = -6.65645 10 := SetPrecision[num2, Infinity]-numOr //N -189 = -2.46118 10

鉴于两者都偏离同一侧,因此正确的表示是第一个。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 2010-10-15
  • 2018-02-10
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多