Why does “dtoa.c” contain so much code?

你说的曾经没有我的故事 提交于 2019-11-27 19:26:25

dtoa.c contains two main functions: dtoa(), which converts a double to string, and strtod(), which converts a string to a double. It also contains a lot of support functions, most of which are for its own implementation of arbitrary-precision arithmetic. dtoa.c's claim to fame is getting these conversions right, and that can only be done, in general, with arbitrary-precision arithmetic. It also has code to round conversions correctly in four different rounding modes.

Your code only tries to implement the equivalent of dtoa(), and since it uses floating-point to do its conversions, will not always get them right. (Update: see my article http://www.exploringbinary.com/quick-and-dirty-floating-point-to-decimal-conversion/ for details.)

(I've written a lot about this on my blog, http://www.exploringbinary.com/ . Six of my last seven articles have been about strtod() conversions alone. Read through them to see how complicated it is to do correctly rounded conversions.)

Producing good results for conversions between decimal and binary floating point representations is a rather difficult problem.

The major source of difficulty is that many decimal fractions, even simple ones, cannot be accurately expressed using binary floating point -- for example, 0.5 can (obviously), but 0.1 cannot. And, going the other way (from binary to decimal), you generally don't want the absolutely accurate result (for example, the accurate decimal value of the closest number to 0.1 which can be represented in an IEEE-754-compliant double is actually 0.1000000000000000055511151231257827021181583404541015625) so you normally want some rounding.

So, conversion often involves approximation. Good conversion routines guarantee to produce the closest possible approximation within particular (word size or number of digits) constraints. This is where most of the complexity comes from.

Take a look at the paper cited in comment at the top of the dtoa.c implementation, Clinger's How to Read Floating Point Numbers Accurately, for a flavour of the problem; and perhaps David M. Gay (the author)'s paper, Correctly Rounded Binary-Decimal and Decimal-Binary Conversions.

(Also, more generally: What Every Computer Scientist Should Know About Floating Point Arithmetic.)

Based on a quick glance at it, a fair amount of the C version is dealing with multiple platforms and such as it looks like this file is meant to be generically usable across compilers (C & C++), bitnesses, floating point implementations, and platforms; with tons of #define configurability.

I think also that the code in dtoa.c might be more efficient (independent of language). For example, it seems to be doing some bit-fiddling, which in the hands of an expert often means speed. I assume it simply uses a less intuitive algorithm for speed reasons.

Short answer: because dtoa.c works.

This is exactly the difference between well-debugged product and a NIH prototype.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!