【问题标题】:Writing my own float parser编写我自己的浮点解析器
【发布时间】:2013-03-21 17:42:36
【问题描述】:

我正在尝试用 C 编写一个解析器,它的部分工作是将一系列字符转换为双精度字符。到目前为止,我一直在使用 strtod,但我发现它非常危险,它不会处理数字位于缓冲区末尾的情况,这不是空终止的。

我想我会自己写。如果我有一个 a.b 形式的数字的字符串表示,我会不会认为我可以计算 (double)a + ((double)b​​ / (double)10^n),其中 n 是b中的数字?

例如,23.4563:

a = 23 b = 4563

最终答案:23 + (4563/10000)

或者对于 IEEE 格式的浮点数会产生不准确的结果?

【问题讨论】:

  • 一方面,如果b 是整数类型,b / 10^n 将在被转换为float 之前进行四舍五入。你想把演员 inside 括号。此外,您需要确保ab 中没有整数溢出。
  • 对不起,是的,你是对的 - 我的错字。我会编辑它。
  • 更多思考:负数,指数格式1.2E10。负指数,...我真的建议你只是复制到一个空终止的缓冲区,让 strtod 做繁重的工作。
  • 计算a + b/10000.f 不会总是产生正确的舍入结果。 (出于这些目的,“正确舍入的结果”是最接近数学值的结果。)例如“1.0097”。 1 + 97/10000.f 产生 1.0097000598907470703125,但更接近和正确的 float 是 1.00969994068145751953125。出现不正确的结果是因为除法中有一个舍入,加法中有另一个舍入。除法中的舍入丢失了显示在加法中需要其他值的信息。
  • 您的问题是说您的工作是转换为 double,但在其他地方指的是转换为 float。你应该明确你想要生产什么类型。

标签: c floating-point


【解决方案1】:

很难准确地阅读浮点数,因为有各种各样的问题需要仔细解决,而且很多人都做不到。然而,这是一个已解决的问题。要开始,请参阅How to read floating point numbers accurately, June 1990, by William D. Clinger

我同意 Roddy 的观点,您最好将数据复制到缓冲区并使用现有的库函数。 (但是,您应该检查您的 C 实现是否提供了浮点数的正确舍入转换。C 标准不需要它,并且某些实现不提供它。)

【讨论】:

【解决方案2】:

你可能对this answer of mine to a somewhat related question感兴趣。

该答案中的解析器将十进制浮点数(表示为字符串)转换为 IEEE-754 浮点数和适当舍入的双精度数。

据我记得,代码中唯一的问题是它可能无法处理指数部分太大(不适合整数)并且应该返回错误或 @ 987654323@.

否则,它应该让您很好地了解该做什么(如果您对自己在做什么有任何想法:)。

【讨论】:

  • 不错的代码。不过要说一句:您说“指数部分太大(不适合整数)并且应该返回错误或 INF 的情况。”这很有趣,因为我也将自己的小数写入浮点函数(比你的短,因为我能够依赖现有的 bigint 实现),我犯了和你一样的错误,即假设指数太大而无法放入 int 意味着浮点数是无限的。 blog.frama-c.com/index.php?post/2012/11/19/…
【解决方案3】:

如前所述,这很困难,您需要额外的精度等等......

但是,如果您有限制输入,并且想知道您是否仍然可以使用半朴素算法和标准 IEEE 754 操作正确地将这些限制十进制转换为二进制,您可能会对我的回答感兴趣

How to manually parse a floating point number from a string

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多