|
|
1.1 root 1: ;; Copyright (C) 1986 Free Software Foundation, Inc.
2: ;; Author Bill Rosenblatt
3:
4: ;; This file is part of GNU Emacs.
5:
6: ;; GNU Emacs is distributed in the hope that it will be useful,
7: ;; but WITHOUT ANY WARRANTY. No author or distributor
8: ;; accepts responsibility to anyone for the consequences of using it
9: ;; or for whether it serves any particular purpose or works at all,
10: ;; unless he says so in writing. Refer to the GNU Emacs General Public
11: ;; License for full details.
12:
13: ;; Everyone is granted permission to copy, modify and redistribute
14: ;; GNU Emacs, but only under the conditions described in the
15: ;; GNU Emacs General Public License. A copy of this license is
16: ;; supposed to have been given to you along with GNU Emacs so you
17: ;; can know your rights and responsibilities. It should be in a
18: ;; file named COPYING. Among other things, the copyright notice
19: ;; and this notice must be preserved on all copies.
20:
21: ;; Floating point arithmetic package.
22: ;;
23: ;; Floating point numbers are represented by dot-pairs (mant . exp)
24: ;; where mant is the 24-bit signed integral mantissa and exp is the
25: ;; base 2 exponent.
26: ;;
27: ;; Emacs LISP supports a 24-bit signed integer data type, which has a
28: ;; range of -(2**23) to +(2**23)-1, or -8388608 to 8388607 decimal.
29: ;; This gives six significant decimal digit accuracy. Exponents can
30: ;; be anything in the range -(2**23) to +(2**23)-1.
31: ;;
32: ;; User interface:
33: ;; function f converts from integer to floating point
34: ;; function string-to-float converts from string to floating point
35: ;; function fint converts a floating point to integer (with truncation)
36: ;; function float-to-string converts from floating point to string
37: ;;
38: ;; Caveats:
39: ;; - Exponents outside of the range of +/-100 or so will cause certain
40: ;; functions (especially conversion routines) to take forever.
41: ;; - Very little checking is done for fixed point overflow/underflow.
42: ;; - No checking is done for over/underflow of the exponent
43: ;; (hardly necessary when exponent can be 2**23).
44: ;;
45: ;;
46: ;; Bill Rosenblatt
47: ;; June 20, 1986
48: ;;
49:
50: ;; fundamental implementation constants
51: (defconst exp-base 2
52: "Base of exponent in this floating point representation.")
53:
54: (defconst mantissa-bits 24
55: "Number of significant bits in this floating point representation.")
56:
57: (defconst decimal-digits 6
58: "Number of decimal digits expected to be accurate.")
59:
60: (defconst expt-digits 2
61: "Maximum permitted digits in a scientific notation exponent.")
62:
63: ;; other constants
64: (defconst maxbit (1- mantissa-bits)
65: "Number of highest bit")
66:
67: (defconst mantissa-maxval (1- (ash 1 maxbit))
68: "Maximum permissable value of mantissa")
69:
70: (defconst mantissa-minval (ash 1 maxbit)
71: "Minimum permissable value of mantissa")
72:
73: (defconst floating-point-regexp
74: "^[ \t]*\\(-?\\)\\([0-9]*\\)\
75: \\(\\.\\([0-9]*\\)\\|\\)\
76: \\(\\(\\([Ee]\\)\\(-?\\)\\([0-9][0-9]*\\)\\)\\|\\)[ \t]*$"
77: "Regular expression to match floating point numbers. Extract matches:
78: 1 - minus sign
79: 2 - integer part
80: 4 - fractional part
81: 8 - minus sign for power of ten
82: 9 - power of ten
83: ")
84:
85: (defconst high-bit-mask (ash 1 maxbit)
86: "Masks all bits except the high-order (sign) bit.")
87:
88: (defconst second-bit-mask (ash 1 (1- maxbit))
89: "Masks all bits except the highest-order magnitude bit")
90:
91: ;; various useful floating point constants
92: (setq _f0 '(0 . 1))
93:
94: (setq _f1/2 '(4194304 . -23))
95:
96: (setq _f1 '(4194304 . -22))
97:
98: (setq _f10 '(5242880 . -19))
99:
100: ;; support for decimal conversion routines
101: (setq powers-of-10 (make-vector (1+ decimal-digits) _f1))
102: (aset powers-of-10 1 _f10)
103: (aset powers-of-10 2 '(6553600 . -16))
104: (aset powers-of-10 3 '(8192000 . -13))
105: (aset powers-of-10 4 '(5120000 . -9))
106: (aset powers-of-10 5 '(6400000 . -6))
107: (aset powers-of-10 6 '(8000000 . -3))
108:
109: (setq all-decimal-digs-minval (aref powers-of-10 (1- decimal-digits))
110: highest-power-of-10 (aref powers-of-10 decimal-digits))
111:
112: (defun fashl (fnum) ; floating-point arithmetic shift left
113: (cons (ash (car fnum) 1) (1- (cdr fnum))))
114:
115: (defun fashr (fnum) ; floating point arithmetic shift right
116: (cons (ash (car fnum) -1) (1+ (cdr fnum))))
117:
118: (defun normalize (fnum)
119: (if (> (car fnum) 0) ; make sure next-to-highest bit is set
120: (while (zerop (logand (car fnum) second-bit-mask))
121: (setq fnum (fashl fnum)))
122: (if (< (car fnum) 0) ; make sure highest bit is set
123: (while (zerop (logand (car fnum) high-bit-mask))
124: (setq fnum (fashl fnum)))
125: (setq fnum _f0))) ; "standard 0"
126: fnum)
127:
128: (defun abs (n) ; integer absolute value
129: (if (natnump n) n (- n)))
130:
131: (defun fabs (fnum) ; re-normalize after taking abs value
132: (normalize (cons (abs (car fnum)) (cdr fnum))))
133:
134: (defun xor (a b) ; logical exclusive or
135: (and (or a b) (not (and a b))))
136:
137: (defun same-sign (a b) ; two f-p numbers have same sign?
138: (not (xor (natnump (car a)) (natnump (car b)))))
139:
140: (defun extract-match (str i) ; used after string-match
141: (condition-case ()
142: (substring str (match-beginning i) (match-end i))
143: (error "")))
144:
145: ;; support for the multiplication function
146: (setq halfword-bits (/ mantissa-bits 2) ; bits in a halfword
147: masklo (1- (ash 1 halfword-bits)) ; isolate the lower halfword
148: maskhi (lognot masklo) ; isolate the upper halfword
149: round-limit (ash 1 (/ halfword-bits 2)))
150:
151: (defun hihalf (n) ; return high halfword, shifted down
152: (ash (logand n maskhi) (- halfword-bits)))
153:
154: (defun lohalf (n) ; return low halfword
155: (logand n masklo))
156:
157: ;; Visible functions
158:
159: ;; Arithmetic functions
160: (defun f+ (a1 a2)
161: "Returns the sum of two floating point numbers."
162: (let ((f1 (fmax a1 a2))
163: (f2 (fmin a1 a2)))
164: (if (same-sign a1 a2)
165: (setq f1 (fashr f1) ; shift right to avoid overflow
166: f2 (fashr f2)))
167: (normalize
168: (cons (+ (car f1) (ash (car f2) (- (cdr f2) (cdr f1))))
169: (cdr f1)))))
170:
171: (defun f- (a1 &optional a2) ; unary or binary minus
172: "Returns the difference of two floating point numbers."
173: (if a2
174: (f+ a1 (f- a2))
175: (normalize (cons (- (car a1)) (cdr a1)))))
176:
177: (defun f* (a1 a2) ; multiply in halfword chunks
178: "Returns the product of two floating point numbers."
179: (let* ((i1 (car (fabs a1)))
180: (i2 (car (fabs a2)))
181: (sign (not (same-sign a1 a2)))
182: (prodlo (+ (hihalf (* (lohalf i1) (lohalf i2)))
183: (lohalf (* (hihalf i1) (lohalf i2)))
184: (lohalf (* (lohalf i1) (hihalf i2)))))
185: (prodhi (+ (* (hihalf i1) (hihalf i2))
186: (hihalf (* (hihalf i1) (lohalf i2)))
187: (hihalf (* (lohalf i1) (hihalf i2)))
188: (hihalf prodlo))))
189: (if (> (lohalf prodlo) round-limit)
190: (setq prodhi (1+ prodhi))) ; round off truncated bits
191: (normalize
192: (cons (if sign (- prodhi) prodhi)
193: (+ (cdr (fabs a1)) (cdr (fabs a2)) mantissa-bits)))))
194:
195: (defun f/ (a1 a2) ; SLOW subtract-and-shift algorithm
196: "Returns the quotient of two floating point numbers."
197: (if (zerop (car a2)) ; if divide by 0
198: (signal 'arith-error (list "attempt to divide by zero" a1 a2))
199: (let ((bits (1- maxbit))
200: (quotient 0)
201: (dividend (car (fabs a1)))
202: (divisor (car (fabs a2)))
203: (sign (not (same-sign a1 a2))))
204: (while (natnump bits)
205: (if (< (- dividend divisor) 0)
206: (setq quotient (ash quotient 1))
207: (setq quotient (1+ (ash quotient 1))
208: dividend (- dividend divisor)))
209: (setq dividend (ash dividend 1)
210: bits (1- bits)))
211: (normalize
212: (cons (if sign (- quotient) quotient)
213: (- (cdr (fabs a1)) (cdr (fabs a2)) (1- maxbit)))))))
214:
215: (defun f% (a1 a2)
216: "Returns the remainder of first floating point number divided by second."
217: (f- a1 (f* (ftrunc (f/ a1 a2)) a2)))
218:
219:
220: ;; Comparison functions
221: (defun f= (a1 a2)
222: "Returns t if two floating point numbers are equal, nil otherwise."
223: (equal a1 a2))
224:
225: (defun f> (a1 a2)
226: "Returns t if first floating point number is greater than second,
227: nil otherwise."
228: (cond ((and (natnump (car a1)) (< (car a2) 0))
229: t) ; a1 nonnegative, a2 negative
230: ((and (> (car a1) 0) (<= (car a2) 0))
231: t) ; a1 positive, a2 nonpositive
232: ((and (<= (car a1) 0) (natnump (car a2)))
233: nil) ; a1 nonpos, a2 nonneg
234: ((/= (cdr a1) (cdr a2)) ; same signs. exponents differ
235: (> (cdr a1) (cdr a2))) ; compare the mantissas.
236: (t
237: (> (car a1) (car a2))))) ; same exponents.
238:
239: (defun f>= (a1 a2)
240: "Returns t if first floating point number is greater than or equal to
241: second, nil otherwise."
242: (or (f> a1 a2) (f= a1 a2)))
243:
244: (defun f< (a1 a2)
245: "Returns t if first floating point number is less than second,
246: nil otherwise."
247: (not (f>= a1 a2)))
248:
249: (defun f<= (a1 a2)
250: "Returns t if first floating point number is less than or equal to
251: second, nil otherwise."
252: (not (f> a1 a2)))
253:
254: (defun f/= (a1 a2)
255: "Returns t if first floating point number is not equal to second,
256: nil otherwise."
257: (not (f= a1 a2)))
258:
259: (defun fmin (a1 a2)
260: "Returns the minimum of two floating point numbers."
261: (if (f< a1 a2) a1 a2))
262:
263: (defun fmax (a1 a2)
264: "Returns the maximum of two floating point numbers."
265: (if (f> a1 a2) a1 a2))
266:
267: (defun fzerop (fnum)
268: "Returns t if the floating point number is zero, nil otherwise."
269: (= (car fnum) 0))
270:
271: (defun floatp (fnum)
272: "Returns t if the arg is a floating point number, nil otherwise."
273: (and (consp fnum) (integerp (car fnum)) (integerp (cdr fnum))))
274:
275: ;; Conversion routines
276: (defun f (int)
277: "Convert the integer argument to floating point, like a C cast operator."
278: (normalize (cons int '0)))
279:
280: (defun int-to-hex-string (int)
281: "Convert the integer argument to a C-style hexadecimal string."
282: (let ((shiftval -20)
283: (str "0x")
284: (hex-chars "0123456789ABCDEF"))
285: (while (<= shiftval 0)
286: (setq str (concat str (char-to-string
287: (aref hex-chars
288: (logand (lsh int shiftval) 15))))
289: shiftval (+ shiftval 4)))
290: str))
291:
292: (defun ftrunc (fnum) ; truncate fractional part
293: "Truncate the fractional part of a floating point number."
294: (cond ((natnump (cdr fnum)) ; it's all integer, return number as is
295: fnum)
296: ((<= (cdr fnum) (- maxbit)) ; it's all fractional, return 0
297: '(0 . 1))
298: (t ; otherwise mask out fractional bits
299: (let ((mant (car fnum)) (exp (cdr fnum)))
300: (normalize
301: (cons (if (natnump mant) ; if negative, use absolute value
302: (ash (ash mant exp) (- exp))
303: (- (ash (ash (- mant) exp) (- exp))))
304: exp))))))
305:
306: (defun fint (fnum) ; truncate and convert to integer
307: "Convert the floating point number to integer, with truncation,
308: like a C cast operator."
309: (let* ((tf (ftrunc fnum)) (tint (car tf)) (texp (cdr tf)))
310: (cond ((>= texp mantissa-bits) ; too high, return "maxint"
311: mantissa-maxval)
312: ((<= texp (- mantissa-bits)) ; too low, return "minint"
313: mantissa-minval)
314: (t ; in range
315: (ash tint texp))))) ; shift so that exponent is 0
316:
317: (defun float-to-string (fnum &optional sci)
318: "Convert the floating point number to a decimal string.
319: Optional second argument non-nil means use scientific notation."
320: (let* ((value (fabs fnum)) (sign (< (car fnum) 0))
321: (power 0) (result 0) (str "")
322: (temp 0) (pow10 _f1))
323:
324: (if (f= fnum _f0)
325: "0"
326: (if (f>= value _f1) ; find largest power of 10 <= value
327: (progn ; value >= 1, power is positive
328: (while (f<= (setq temp (f* pow10 highest-power-of-10)) value)
329: (setq pow10 temp
330: power (+ power decimal-digits)))
331: (while (f<= (setq temp (f* pow10 _f10)) value)
332: (setq pow10 temp
333: power (1+ power))))
334: (progn ; value < 1, power is negative
335: (while (f> (setq temp (f/ pow10 highest-power-of-10)) value)
336: (setq pow10 temp
337: power (- power decimal-digits)))
338: (while (f> pow10 value)
339: (setq pow10 (f/ pow10 _f10)
340: power (1- power)))))
341: ; get value in range 100000 to 999999
342: (setq value (f* (f/ value pow10) all-decimal-digs-minval)
343: result (ftrunc value))
344: (if (f> (f- value result) _f1/2) ; round up if remainder > 0.5
345: (setq str (int-to-string (1+ (fint result))))
346: (setq str (int-to-string (fint result))))
347:
348: (if sci ; scientific notation
349: (setq str (concat (substring str 0 1) "." (substring str 1)
350: "E" (int-to-string power)))
351:
352: ; regular decimal string
353: (cond ((>= power (1- decimal-digits))
354: ; large power, append zeroes
355: (let ((zeroes (- power decimal-digits)))
356: (while (natnump zeroes)
357: (setq str (concat str "0")
358: zeroes (1- zeroes)))))
359:
360: ; negative power, prepend decimal
361: ((< power 0) ; point and zeroes
362: (let ((zeroes (- (- power) 2)))
363: (while (natnump zeroes)
364: (setq str (concat "0" str)
365: zeroes (1- zeroes)))
366: (setq str (concat "0." str))))
367:
368: (t ; in range, insert decimal point
369: (setq str (concat
370: (substring str 0 (1+ power))
371: "."
372: (substring str (1+ power)))))))
373:
374: (if sign ; if negative, prepend minus sign
375: (concat "-" str)
376: str))))
377:
378:
379: ;; string to float conversion.
380: ;; accepts scientific notation, but ignores anything after the first two
381: ;; digits of the exponent.
382: (defun string-to-float (str)
383: "Convert the string to a floating point number.
384: Accepts a decimal string in scientific notation,
385: with exponent preceded by either E or e.
386: Only the 6 most significant digits of the integer and fractional parts
387: are used; only the first two digits of the exponent are used.
388: Negative signs preceding both the decimal number and the exponent
389: are recognized."
390:
391: (if (string-match floating-point-regexp str 0)
392: (let (power)
393: (f*
394: ; calculate the mantissa
395: (let* ((int-subst (extract-match str 2))
396: (fract-subst (extract-match str 4))
397: (digit-string (concat int-subst fract-subst))
398: (mant-sign (equal (extract-match str 1) "-"))
399: (leading-0s 0) (round-up nil))
400:
401: ; get rid of leading 0's
402: (setq power (- (length int-subst) decimal-digits))
403: (while (and (< leading-0s (length digit-string))
404: (= (aref digit-string leading-0s) ?0))
405: (setq leading-0s (1+ leading-0s)))
406: (setq power (- power leading-0s)
407: digit-string (substring digit-string leading-0s))
408:
409: ; if more than 6 digits, round off
410: (if (> (length digit-string) decimal-digits)
411: (setq round-up (>= (aref digit-string decimal-digits) ?5)
412: digit-string (substring digit-string 0 decimal-digits))
413: (setq power (+ power (- decimal-digits (length digit-string)))))
414:
415: ; round up and add minus sign, if necessary
416: (f (* (+ (string-to-int digit-string)
417: (if round-up 1 0))
418: (if mant-sign -1 1))))
419:
420: ; calculate the exponent (power of ten)
421: (let* ((expt-subst (extract-match str 9))
422: (expt-sign (equal (extract-match str 8) "-"))
423: (expt 0) (chunks 0) (tens 0) (exponent _f1)
424: (func 'f*))
425:
426: (setq expt (+ (* (string-to-int
427: (substring expt-subst 0
428: (min expt-digits (length expt-subst))))
429: (if expt-sign -1 1))
430: power))
431: (if (< expt 0) ; if power of 10 negative
432: (setq expt (- expt) ; take abs val of exponent
433: func 'f/)) ; and set up to divide, not multiply
434:
435: (setq chunks (/ expt decimal-digits)
436: tens (% expt decimal-digits))
437: ; divide or multiply by "chunks" of 10**6
438: (while (> chunks 0)
439: (setq exponent (funcall func exponent highest-power-of-10)
440: chunks (1- chunks)))
441: ; divide or multiply by remaining power of ten
442: (funcall func exponent (aref powers-of-10 tens)))))
443:
444: _f0)) ; if invalid, return 0
445:
446:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.