README revision 1.1
11.1Skleink$NetBSD: README,v 1.1 2006/01/25 15:18:40 kleink Exp $ 21.1Skleink 31.1SkleinkThis directory contains source for a library of binary -> decimal 41.1Skleinkand decimal -> binary conversion routines, for single-, double-, 51.1Skleinkand extended-precision IEEE binary floating-point arithmetic, and 61.1Skleinkother IEEE-like binary floating-point, including "double double", 71.1Skleinkas in 81.1Skleink 91.1Skleink T. J. Dekker, "A Floating-Point Technique for Extending the 101.1Skleink Available Precision", Numer. Math. 18 (1971), pp. 224-242 111.1Skleink 121.1Skleinkand 131.1Skleink 141.1Skleink "Inside Macintosh: PowerPC Numerics", Addison-Wesley, 1994 151.1Skleink 161.1SkleinkThe conversion routines use double-precision floating-point arithmetic 171.1Skleinkand, where necessary, high precision integer arithmetic. The routines 181.1Skleinkare generalizations of the strtod and dtoa routines described in 191.1Skleink 201.1Skleink David M. Gay, "Correctly Rounded Binary-Decimal and 211.1Skleink Decimal-Binary Conversions", Numerical Analysis Manuscript 221.1Skleink No. 90-10, Bell Labs, Murray Hill, 1990; 231.1Skleink http://cm.bell-labs.com/cm/cs/what/ampl/REFS/rounding.ps.gz 241.1Skleink 251.1Skleink(based in part on papers by Clinger and Steele & White: see the 261.1Skleinkreferences in the above paper). 271.1Skleink 281.1SkleinkThe present conversion routines should be able to use any of IEEE binary, 291.1SkleinkVAX, or IBM-mainframe double-precision arithmetic internally, but I (dmg) 301.1Skleinkhave so far only had a chance to test them with IEEE double precision 311.1Skleinkarithmetic. 321.1Skleink 331.1SkleinkThe core conversion routines are strtodg for decimal -> binary conversions 341.1Skleinkand gdtoa for binary -> decimal conversions. These routines operate 351.1Skleinkon arrays of unsigned 32-bit integers of type ULong, a signed 32-bit 361.1Skleinkexponent of type Long, and arithmetic characteristics described in 371.1Skleinkstruct FPI; FPI, Long, and ULong are defined in gdtoa.h. File arith.h 381.1Skleinkis supposed to provide #defines that cause gdtoa.h to define its 391.1Skleinktypes correctly. File arithchk.c is source for a program that 401.1Skleinkgenerates a suitable arith.h on all systems where I've been able to 411.1Skleinktest it. 421.1Skleink 431.1SkleinkThe core conversion routines are meant to be called by helper routines 441.1Skleinkthat know details of the particular binary arithmetic of interest and 451.1Skleinkconvert. The present directory provides helper routines for 5 variants 461.1Skleinkof IEEE binary floating-point arithmetic, each indicated by one or 471.1Skleinktwo letters: 481.1Skleink 491.1Skleink f IEEE single precision 501.1Skleink d IEEE double precision 511.1Skleink x IEEE extended precision, as on Intel 80x87 521.1Skleink and software emulations of Motorola 68xxx chips 531.1Skleink that do not pad the way the 68xxx does, but 541.1Skleink only store 80 bits 551.1Skleink xL IEEE extended precision, as on Motorola 68xxx chips 561.1Skleink Q quad precision, as on Sun Sparc chips 571.1Skleink dd double double, pairs of IEEE double numbers 581.1Skleink whose sum is the desired value 591.1Skleink 601.1SkleinkFor decimal -> binary conversions, there are three families of 611.1Skleinkhelper routines: one for round-nearest: 621.1Skleink 631.1Skleink strtof 641.1Skleink strtod 651.1Skleink strtodd 661.1Skleink strtopd 671.1Skleink strtopf 681.1Skleink strtopx 691.1Skleink strtopxL 701.1Skleink strtopQ 711.1Skleink 721.1Skleinkone with rounding direction specified: 731.1Skleink 741.1Skleink strtorf 751.1Skleink strtord 761.1Skleink strtordd 771.1Skleink strtorx 781.1Skleink strtorxL 791.1Skleink strtorQ 801.1Skleink 811.1Skleinkand one for computing an interval (at most one bit wide) that contains 821.1Skleinkthe decimal number: 831.1Skleink 841.1Skleink strtoIf 851.1Skleink strtoId 861.1Skleink strtoIdd 871.1Skleink strtoIx 881.1Skleink strtoIxL 891.1Skleink strtoIQ 901.1Skleink 911.1SkleinkThe latter call strtoIg, which makes one call on strtodg and adjusts 921.1Skleinkthe result to provide the desired interval. On systems where native 931.1Skleinkarithmetic can easily make one-ulp adjustments on values in the 941.1Skleinkdesired floating-point format, it might be more efficient to use the 951.1Skleinknative arithmetic. Routine strtodI is a variant of strtoId that 961.1Skleinkillustrates one way to do this for IEEE binary double-precision 971.1Skleinkarithmetic -- but whether this is more efficient remains to be seen. 981.1Skleink 991.1SkleinkFunctions strtod and strtof have "natural" return types, float and 1001.1Skleinkdouble -- strtod is specified by the C standard, and strtof appears 1011.1Skleinkin the stdlib.h of some systems, such as (at least some) Linux systems. 1021.1SkleinkThe other functions write their results to their final argument(s): 1031.1Skleinkto the final two argument for the strtoI... (interval) functions, 1041.1Skleinkand to the final argument for the others (strtop... and strtor...). 1051.1SkleinkWhere possible, these arguments have "natural" return types (double* 1061.1Skleinkor float*), to permit at least some type checking. In reality, they 1071.1Skleinkare viewed as arrays of ULong (or, for the "x" functions, UShort) 1081.1Skleinkvalues. On systems where long double is the appropriate type, one can 1091.1Skleinkpass long double* final argument(s) to these routines. The int value 1101.1Skleinkthat these routines return is the return value from the call they make 1111.1Skleinkon strtodg; see the enum of possible return values in gdtoa.h. 1121.1Skleink 1131.1SkleinkSource files g_ddfmt.c, misc.c, smisc.c, strtod.c, strtodg.c, and ulp.c 1141.1Skleinkshould use true IEEE double arithmetic (not, e.g., double extended), 1151.1Skleinkat least for storing (and viewing the bits of) the variables declared 1161.1Skleink"double" within them. 1171.1Skleink 1181.1SkleinkOne detail indicated in struct FPI is whether the target binary 1191.1Skleinkarithmetic departs from the IEEE standard by flushing denormalized 1201.1Skleinknumbers to 0. On systems that do this, the helper routines for 1211.1Skleinkconversion to double-double format (when compiled with 1221.1SkleinkSudden_Underflow #defined) penalize the bottom of the exponent 1231.1Skleinkrange so that they return a nonzero result only when the least 1241.1Skleinksignificant bit of the less significant member of the pair of 1251.1Skleinkdouble values returned can be expressed as a normalized double 1261.1Skleinkvalue. An alternative would be to drop to 53-bit precision near 1271.1Skleinkthe bottom of the exponent range. To get correct rounding, this 1281.1Skleinkwould (in general) require two calls on strtodg (one specifying 1291.1Skleink126-bit arithmetic, then, if necessary, one specifying 53-bit 1301.1Skleinkarithmetic). 1311.1Skleink 1321.1SkleinkBy default, the core routine strtodg and strtod set errno to ERANGE 1331.1Skleinkif the result overflows to +Infinity or underflows to 0. Compile 1341.1Skleinkthese routines with NO_ERRNO #defined to inhibit errno assignments. 1351.1Skleink 1361.1SkleinkRoutine strtod is based on netlib's "dtoa.c from fp", and 1371.1Skleink(f = strtod(s,se)) is more efficient for some conversions than, say, 1381.1Skleinkstrtord(s,se,1,&f). Parts of strtod require true IEEE double 1391.1Skleinkarithmetic with the default rounding mode (round-to-nearest) and, on 1401.1Skleinksystems with IEEE extended-precision registers, double-precision 1411.1Skleink(53-bit) rounding precision. If the machine uses (the equivalent of) 1421.1SkleinkIntel 80x87 arithmetic, the call 1431.1Skleink _control87(PC_53, MCW_PC); 1441.1Skleinkdoes this with many compilers. Whether this or another call is 1451.1Skleinkappropriate depends on the compiler; for this to work, it may be 1461.1Skleinknecessary to #include "float.h" or another system-dependent header 1471.1Skleinkfile. 1481.1Skleink 1491.1SkleinkSource file strtodnrp.c gives a strtod that does not require 53-bit 1501.1Skleinkrounding precision on systems (such as Intel IA32 systems) that may 1511.1Skleinksuffer double rounding due to use of extended-precision registers. 1521.1SkleinkFor some conversions this variant of strtod is less efficient than the 1531.1Skleinkone in strtod.c when the latter is run with 53-bit rounding precision. 1541.1Skleink 1551.1SkleinkThe values that the strto* routines return for NaNs are determined by 1561.1Skleinkgd_qnan.h, which the makefile generates by running the program whose 1571.1Skleinksource is qnan.c. Note that the rules for distinguishing signaling 1581.1Skleinkfrom quiet NaNs are system-dependent. For cross-compilation, you need 1591.1Skleinkto determine arith.h and gd_qnan.h suitably, e.g., using the 1601.1Skleinkarithmetic of the target machine. 1611.1Skleink 1621.1SkleinkC99's hexadecimal floating-point constants are recognized by the 1631.1Skleinkstrto* routines (but this feature has not yet been heavily tested). 1641.1SkleinkCompiling with NO_HEX_FP #defined disables this feature. 1651.1Skleink 1661.1SkleinkWhen compiled with -DINFNAN_CHECK, the strto* routines recognize C99's 1671.1SkleinkNaN and Infinity syntax. Moreover, unless No_Hex_NaN is #defined, the 1681.1Skleinkstrto* routines also recognize C99's NaN(...) syntax: they accept 1691.1Skleink(case insensitively) strings of the form NaN(x), where x is a string 1701.1Skleinkof hexadecimal digits and spaces; if there is only one string of 1711.1Skleinkhexadecimal digits, it is taken for the fraction bits of the resulting 1721.1SkleinkNaN; if there are two or more strings of hexadecimal digits, each 1731.1Skleinkstring is assigned to the next available sequence of 32-bit words of 1741.1Skleinkfractions bits (starting with the most significant), right-aligned in 1751.1Skleinkeach sequence. 1761.1Skleink 1771.1SkleinkFor binary -> decimal conversions, I've provided just one family 1781.1Skleinkof helper routines: 1791.1Skleink 1801.1Skleink g_ffmt 1811.1Skleink g_dfmt 1821.1Skleink g_ddfmt 1831.1Skleink g_xfmt 1841.1Skleink g_xLfmt 1851.1Skleink g_Qfmt 1861.1Skleink 1871.1Skleinkwhich do a "%g" style conversion either to a specified number of decimal 1881.1Skleinkplaces (if their ndig argument is positive), or to the shortest 1891.1Skleinkdecimal string that rounds to the given binary floating-point value 1901.1Skleink(if ndig <= 0). They write into a buffer supplied as an argument 1911.1Skleinkand return either a pointer to the end of the string (a null character) 1921.1Skleinkin the buffer, if the buffer was long enough, or 0. Other forms of 1931.1Skleinkconversion are easily done with the help of gdtoa(), such as %e or %f 1941.1Skleinkstyle and conversions with direction of rounding specified (so that, if 1951.1Skleinkdesired, the decimal value is either >= or <= the binary value). 1961.1Skleink 1971.1SkleinkFor an example of more general conversions based on dtoa(), see 1981.1Skleinknetlib's "printf.c from ampl/solvers". 1991.1Skleink 2001.1SkleinkFor double-double -> decimal, g_ddfmt() assumes IEEE-like arithmetic 2011.1Skleinkof precision max(126, #bits(input)) bits, where #bits(input) is the 2021.1Skleinknumber of mantissa bits needed to represent the sum of the two double 2031.1Skleinkvalues in the input. 2041.1Skleink 2051.1SkleinkThe makefile creates a library, gdtoa.a. To use the helper 2061.1Skleinkroutines, a program only needs to include gdtoa.h. All the 2071.1Skleinksource files for gdtoa.a include a more extensive gdtoaimp.h; 2081.1Skleinkamong other things, gdtoaimp.h has #defines that make "internal" 2091.1Skleinknames end in _D2A. To make a "system" library, one could modify 2101.1Skleinkthese #defines to make the names start with __. 2111.1Skleink 2121.1SkleinkVarious comments about possible #defines appear in gdtoaimp.h, 2131.1Skleinkbut for most purposes, arith.h should set suitable #defines. 2141.1Skleink 2151.1SkleinkSystems with preemptive scheduling of multiple threads require some 2161.1Skleinkmanual intervention. On such systems, it's necessary to compile 2171.1Skleinkdmisc.c, dtoa.c gdota.c, and misc.c with MULTIPLE_THREADS #defined, 2181.1Skleinkand to provide (or suitably #define) two locks, acquired by 2191.1SkleinkACQUIRE_DTOA_LOCK(n) and freed by FREE_DTOA_LOCK(n) for n = 0 or 1. 2201.1Skleink(The second lock, accessed in pow5mult, ensures lazy evaluation of 2211.1Skleinkonly one copy of high powers of 5; omitting this lock would introduce 2221.1Skleinka small probability of wasting memory, but would otherwise be harmless.) 2231.1SkleinkRoutines that call dtoa or gdtoa directly must also invoke freedtoa(s) 2241.1Skleinkto free the value s returned by dtoa or gdtoa. It's OK to do so whether 2251.1Skleinkor not MULTIPLE_THREADS is #defined, and the helper g_*fmt routines 2261.1Skleinklisted above all do this indirectly (in gfmt_D2A(), which they all call). 2271.1Skleink 2281.1SkleinkBy default, there is a private pool of memory of length 2000 bytes 2291.1Skleinkfor intermediate quantities, and MALLOC (see gdtoaimp.h) is called only 2301.1Skleinkif the private pool does not suffice. 2000 is large enough that MALLOC 2311.1Skleinkis called only under very unusual circumstances (decimal -> binary 2321.1Skleinkconversion of very long strings) for conversions to and from double 2331.1Skleinkprecision. For systems with preemptively scheduled multiple threads 2341.1Skleinkor for conversions to extended or quad, it may be appropriate to 2351.1Skleink#define PRIVATE_MEM nnnn, where nnnn is a suitable value > 2000. 2361.1SkleinkFor extended and quad precisions, -DPRIVATE_MEM=20000 is probably 2371.1Skleinkplenty even for many digits at the ends of the exponent range. 2381.1SkleinkUse of the private pool avoids some overhead. 2391.1Skleink 2401.1SkleinkDirectory test provides some test routines. See its README. 2411.1SkleinkI've also tested this stuff (except double double conversions) 2421.1Skleinkwith Vern Paxson's testbase program: see 2431.1Skleink 2441.1Skleink V. Paxson and W. Kahan, "A Program for Testing IEEE Binary-Decimal 2451.1Skleink Conversion", manuscript, May 1991, 2461.1Skleink ftp://ftp.ee.lbl.gov/testbase-report.ps.Z . 2471.1Skleink 2481.1Skleink(The same ftp directory has source for testbase.) 2491.1Skleink 2501.1SkleinkSome system-dependent additions to CFLAGS in the makefile: 2511.1Skleink 2521.1Skleink HU-UX: -Aa -Ae 2531.1Skleink OSF (DEC Unix): -ieee_with_no_inexact 2541.1Skleink SunOS 4.1x: -DKR_headers -DBad_float_h 2551.1Skleink 2561.1SkleinkIf you want to put this stuff into a shared library and your 2571.1Skleinkoperating system requires export lists for shared libraries, 2581.1Skleinkthe following would be an appropriate export list: 2591.1Skleink 2601.1Skleink dtoa 2611.1Skleink freedtoa 2621.1Skleink g_Qfmt 2631.1Skleink g_ddfmt 2641.1Skleink g_dfmt 2651.1Skleink g_ffmt 2661.1Skleink g_xLfmt 2671.1Skleink g_xfmt 2681.1Skleink gdtoa 2691.1Skleink strtoIQ 2701.1Skleink strtoId 2711.1Skleink strtoIdd 2721.1Skleink strtoIf 2731.1Skleink strtoIx 2741.1Skleink strtoIxL 2751.1Skleink strtod 2761.1Skleink strtodI 2771.1Skleink strtodg 2781.1Skleink strtof 2791.1Skleink strtopQ 2801.1Skleink strtopd 2811.1Skleink strtopdd 2821.1Skleink strtopf 2831.1Skleink strtopx 2841.1Skleink strtopxL 2851.1Skleink strtorQ 2861.1Skleink strtord 2871.1Skleink strtordd 2881.1Skleink strtorf 2891.1Skleink strtorx 2901.1Skleink strtorxL 2911.1Skleink 2921.1SkleinkWhen time permits, I (dmg) hope to write in more detail about the 2931.1Skleinkpresent conversion routines; for now, this README file must suffice. 2941.1SkleinkMeanwhile, if you wish to write helper functions for other kinds of 2951.1SkleinkIEEE-like arithmetic, some explanation of struct FPI and the bits 2961.1Skleinkarray may be helpful. Both gdtoa and strtodg operate on a bits array 2971.1Skleinkdescribed by FPI *fpi. The bits array is of type ULong, a 32-bit 2981.1Skleinkunsigned integer type. Floating-point numbers have fpi->nbits bits, 2991.1Skleinkwith the least significant 32 bits in bits[0], the next 32 bits in 3001.1Skleinkbits[1], etc. These numbers are regarded as integers multiplied by 3011.1Skleink2^e (i.e., 2 to the power of the exponent e), where e is the second 3021.1Skleinkargument (be) to gdtoa and is stored in *exp by strtodg. The minimum 3031.1Skleinkand maximum exponent values fpi->emin and fpi->emax for normalized 3041.1Skleinkfloating-point numbers reflect this arrangement. For example, the 3051.1SkleinkP754 standard for binary IEEE arithmetic specifies doubles as having 3061.1Skleink53 bits, with normalized values of the form 1.xxxxx... times 2^(b-1023), 3071.1Skleinkwith 52 bits (the x's) and the biased exponent b represented explicitly; 3081.1Skleinkb is an unsigned integer in the range 1 <= b <= 2046 for normalized 3091.1Skleinkfinite doubles, b = 0 for denormals, and b = 2047 for Infinities and NaNs. 3101.1SkleinkTo turn an IEEE double into the representation used by strtodg and gdtoa, 3111.1Skleinkwe multiply 1.xxxx... by 2^52 (to make it an integer) and reduce the 3121.1Skleinkexponent e = (b-1023) by 52: 3131.1Skleink 3141.1Skleink fpi->emin = 1 - 1023 - 52 3151.1Skleink fpi->emax = 1046 - 1023 - 52 3161.1Skleink 3171.1SkleinkIn various wrappers for IEEE double, we actually write -53 + 1 rather 3181.1Skleinkthan -52, to emphasize that there are 53 bits including one implicit bit. 3191.1SkleinkField fpi->rounding indicates the desired rounding direction, with 3201.1Skleinkpossible values 3211.1Skleink FPI_Round_zero = toward 0, 3221.1Skleink FPI_Round_near = unbiased rounding -- the IEEE default, 3231.1Skleink FPI_Round_up = toward +Infinity, and 3241.1Skleink FPI_Round_down = toward -Infinity 3251.1Skleinkgiven in gdtoa.h. 3261.1Skleink 3271.1SkleinkField fpi->sudden_underflow indicates whether strtodg should return 3281.1Skleinkdenormals or flush them to zero. Normal floating-point numbers have 3291.1Skleinkbit fpi->nbits in the bits array on. Denormals have it off, with 3301.1Skleinkexponent = fpi->emin. Strtodg provides distinct return values for normals 3311.1Skleinkand denormals; see gdtoa.h. 3321.1Skleink 3331.1SkleinkCompiling g__fmt.c, strtod.c, and strtodg.c with -DUSE_LOCALE causes 3341.1Skleinkthe decimal-point character to be taken from the current locale; otherwise 3351.1Skleinkit is '.'. 3361.1Skleink 3371.1SkleinkPlease send comments to David M. Gay (dmg at acm dot org, with " at " 3381.1Skleinkchanged at "@" and " dot " changed to "."). 339