2013-03-21 77 views
4

我想在C中编写一个解析器,它的一部分工作是将一系列字符转换为double。到目前为止,我一直在使用strtod,但我发现它非常危险,它不会处理数字位于缓冲区末尾的情况,该缓冲区不是以null结尾。编写我自己的float解析器

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

例如,23.4563:

一个= 23 B = 4563

最终答案:23 +(10000分之4563)

还是会产生相对于IEEE格式不准确的结果的花车?

+2

其一,如果'B'是一个整数类型,'b/10^N'会被转换为之前得到四舍五入'float'。你想把剧本放在圆括号里面。另外,你需要确保'a'或'b'中没有整数溢出。 – Shahbaz 2013-03-21 17:44:48

+0

对不起,是的,你是对的 - 我的错字。我会编辑它。 – Cthutu 2013-03-21 17:55:50

+0

更多思考:负数,指数格式'1.2E10'。负指数,...我真的*建议你只复制到一个空终止缓冲区,让strtod完成繁重的工作。 – Roddy 2013-03-21 17:58:14

回答

3

很难准确地读出浮点数字,因为存在各种必须认真解决的问题,许多人都没有这样做。但是,这是一个解决的问题。要开始,请参阅this paper

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

+1

+1这不是一个简单的问题。 – 2013-03-21 19:35:14

1

您可能感兴趣this answer of mine to a somewhat related question

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

据我所知,代码中唯一的问题是它可能无法处理指数部分太大(不适合整数)的情况,并且应该等于返回一个错误或INF

否则,它应该给你一个好主意该怎么做(如果你有任何想法,你所做的一切:)。

+0

不错的代码。但有一句话:你说“指数部分太大(不适合整数)的情况,应该等于返回一个错误或INF。”这很有趣,因为我也写了自己的小数点到浮点数,因为我可以依赖现有的bigint实现),所以我也犯了同样的错误,也就是说,假设一个指数太大而不适合int的情况意味着float是无限的。 http://blog.frama-c.com/index.php?post/2012/11/19/Funny-floating-point-bugs-in-Frama-C-Oxygen-s-front-end – 2013-03-21 22:21:17

+0

@PascalCuoq :) :) :) – 2013-03-21 22:52:42

1

前面已经说过,这是困难的,你需要额外的精度,等等

但是,如果你限制输入,并想知道你是否能正确地还是这些受限制的十进制转换为二进制半幼稚算法和标准IEEE 754 OPS,你可能有兴趣在我的回答

How to manually parse a floating point number from a string