annotate lisp/emacs-lisp/float.el @ 18092:8428d56cd207

(smtpmail-via-smtp): Recognize XVRB as a synonym for VERB and XONE as a synonym for ONEX. (smtpmail-read-response): Add "%s" to `message' calls to avoid problems with percent signs in strings. (smtpmail-read-response): Return all lines of the response text as a list of strings. Formerly only the first line was returned. This is insufficient when one wants to parse e.g. an EHLO response. Ignore responses starting with "0". This is necessary to support the VERB SMTP extension. (smtpmail-via-smtp): Try EHLO and find out which SMTP service extensions the receiving mailer supports. Issue the ONEX and XUSR commands if the corresponding extensions are supported. Issue VERB if supported and `smtpmail-debug-info' is non-nil. Add SIZE attribute to MAIL FROM: command if SIZE extension is supported. Add code that could set the BODY= attribute to MAIL FROM: if the receiving mailer supports 8BITMIME. This is currently disabled, since doing it right might involve adding MIME headers to, and in some cases reencoding, the message.
author Richard M. Stallman <rms@gnu.org>
date Sun, 01 Jun 1997 22:24:22 +0000
parents 83f275dcd93a
children ead435447ea4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
660
08eb386dd0f3 *** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 584
diff changeset
1 ;;; float.el --- floating point arithmetic package.
08eb386dd0f3 *** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 584
diff changeset
2
845
213978acbc1e entered into RCS
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 811
diff changeset
3 ;; Copyright (C) 1986 Free Software Foundation, Inc.
213978acbc1e entered into RCS
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 811
diff changeset
4
807
4f28bd14272c *** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 660
diff changeset
5 ;; Author: Bill Rosenblatt
4f28bd14272c *** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 660
diff changeset
6 ;; Maintainer: FSF
811
e694e0879463 *** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 807
diff changeset
7 ;; Keywords: extensions
807
4f28bd14272c *** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 660
diff changeset
8
59
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
9 ;; This file is part of GNU Emacs.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
10
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
12 ;; it under the terms of the GNU General Public License as published by
807
4f28bd14272c *** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 660
diff changeset
13 ;; the Free Software Foundation; either version 2, or (at your option)
59
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
14 ;; any later version.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
15
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
16 ;; GNU Emacs is distributed in the hope that it will be useful,
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
19 ;; GNU General Public License for more details.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
20
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
21 ;; You should have received a copy of the GNU General Public License
14169
83f275dcd93a Update FSF's address.
Erik Naggum <erik@naggum.no>
parents: 3591
diff changeset
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
83f275dcd93a Update FSF's address.
Erik Naggum <erik@naggum.no>
parents: 3591
diff changeset
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
83f275dcd93a Update FSF's address.
Erik Naggum <erik@naggum.no>
parents: 3591
diff changeset
24 ;; Boston, MA 02111-1307, USA.
59
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
25
807
4f28bd14272c *** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 660
diff changeset
26 ;;; Commentary:
4f28bd14272c *** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 660
diff changeset
27
59
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
28 ;; Floating point numbers are represented by dot-pairs (mant . exp)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
29 ;; where mant is the 24-bit signed integral mantissa and exp is the
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
30 ;; base 2 exponent.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
31 ;;
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
32 ;; Emacs LISP supports a 24-bit signed integer data type, which has a
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
33 ;; range of -(2**23) to +(2**23)-1, or -8388608 to 8388607 decimal.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
34 ;; This gives six significant decimal digit accuracy. Exponents can
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
35 ;; be anything in the range -(2**23) to +(2**23)-1.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
36 ;;
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
37 ;; User interface:
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
38 ;; function f converts from integer to floating point
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
39 ;; function string-to-float converts from string to floating point
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
40 ;; function fint converts a floating point to integer (with truncation)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
41 ;; function float-to-string converts from floating point to string
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
42 ;;
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
43 ;; Caveats:
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
44 ;; - Exponents outside of the range of +/-100 or so will cause certain
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
45 ;; functions (especially conversion routines) to take forever.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
46 ;; - Very little checking is done for fixed point overflow/underflow.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
47 ;; - No checking is done for over/underflow of the exponent
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
48 ;; (hardly necessary when exponent can be 2**23).
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
49 ;;
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
50 ;;
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
51 ;; Bill Rosenblatt
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
52 ;; June 20, 1986
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
53 ;;
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
54
807
4f28bd14272c *** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 660
diff changeset
55 ;;; Code:
4f28bd14272c *** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 660
diff changeset
56
59
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
57 ;; fundamental implementation constants
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
58 (defconst exp-base 2
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
59 "Base of exponent in this floating point representation.")
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
60
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
61 (defconst mantissa-bits 24
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
62 "Number of significant bits in this floating point representation.")
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
63
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
64 (defconst decimal-digits 6
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
65 "Number of decimal digits expected to be accurate.")
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
66
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
67 (defconst expt-digits 2
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
68 "Maximum permitted digits in a scientific notation exponent.")
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
69
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
70 ;; other constants
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
71 (defconst maxbit (1- mantissa-bits)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
72 "Number of highest bit")
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
73
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
74 (defconst mantissa-maxval (1- (ash 1 maxbit))
3591
507f64624555 Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents: 845
diff changeset
75 "Maximum permissible value of mantissa")
59
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
76
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
77 (defconst mantissa-minval (ash 1 maxbit)
3591
507f64624555 Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents: 845
diff changeset
78 "Minimum permissible value of mantissa")
59
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
79
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
80 (defconst floating-point-regexp
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
81 "^[ \t]*\\(-?\\)\\([0-9]*\\)\
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
82 \\(\\.\\([0-9]*\\)\\|\\)\
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
83 \\(\\(\\([Ee]\\)\\(-?\\)\\([0-9][0-9]*\\)\\)\\|\\)[ \t]*$"
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
84 "Regular expression to match floating point numbers. Extract matches:
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
85 1 - minus sign
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
86 2 - integer part
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
87 4 - fractional part
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
88 8 - minus sign for power of ten
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
89 9 - power of ten
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
90 ")
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
91
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
92 (defconst high-bit-mask (ash 1 maxbit)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
93 "Masks all bits except the high-order (sign) bit.")
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
94
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
95 (defconst second-bit-mask (ash 1 (1- maxbit))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
96 "Masks all bits except the highest-order magnitude bit")
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
97
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
98 ;; various useful floating point constants
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
99 (setq _f0 '(0 . 1))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
100
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
101 (setq _f1/2 '(4194304 . -23))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
102
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
103 (setq _f1 '(4194304 . -22))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
104
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
105 (setq _f10 '(5242880 . -19))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
106
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
107 ;; support for decimal conversion routines
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
108 (setq powers-of-10 (make-vector (1+ decimal-digits) _f1))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
109 (aset powers-of-10 1 _f10)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
110 (aset powers-of-10 2 '(6553600 . -16))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
111 (aset powers-of-10 3 '(8192000 . -13))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
112 (aset powers-of-10 4 '(5120000 . -9))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
113 (aset powers-of-10 5 '(6400000 . -6))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
114 (aset powers-of-10 6 '(8000000 . -3))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
115
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
116 (setq all-decimal-digs-minval (aref powers-of-10 (1- decimal-digits))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
117 highest-power-of-10 (aref powers-of-10 decimal-digits))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
118
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
119 (defun fashl (fnum) ; floating-point arithmetic shift left
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
120 (cons (ash (car fnum) 1) (1- (cdr fnum))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
121
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
122 (defun fashr (fnum) ; floating point arithmetic shift right
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
123 (cons (ash (car fnum) -1) (1+ (cdr fnum))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
124
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
125 (defun normalize (fnum)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
126 (if (> (car fnum) 0) ; make sure next-to-highest bit is set
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
127 (while (zerop (logand (car fnum) second-bit-mask))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
128 (setq fnum (fashl fnum)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
129 (if (< (car fnum) 0) ; make sure highest bit is set
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
130 (while (zerop (logand (car fnum) high-bit-mask))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
131 (setq fnum (fashl fnum)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
132 (setq fnum _f0))) ; "standard 0"
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
133 fnum)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
134
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
135 (defun abs (n) ; integer absolute value
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
136 (if (>= n 0) n (- n)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
137
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
138 (defun fabs (fnum) ; re-normalize after taking abs value
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
139 (normalize (cons (abs (car fnum)) (cdr fnum))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
140
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
141 (defun xor (a b) ; logical exclusive or
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
142 (and (or a b) (not (and a b))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
143
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
144 (defun same-sign (a b) ; two f-p numbers have same sign?
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
145 (not (xor (natnump (car a)) (natnump (car b)))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
146
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
147 (defun extract-match (str i) ; used after string-match
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
148 (condition-case ()
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
149 (substring str (match-beginning i) (match-end i))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
150 (error "")))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
151
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
152 ;; support for the multiplication function
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
153 (setq halfword-bits (/ mantissa-bits 2) ; bits in a halfword
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
154 masklo (1- (ash 1 halfword-bits)) ; isolate the lower halfword
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
155 maskhi (lognot masklo) ; isolate the upper halfword
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
156 round-limit (ash 1 (/ halfword-bits 2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
157
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
158 (defun hihalf (n) ; return high halfword, shifted down
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
159 (ash (logand n maskhi) (- halfword-bits)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
160
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
161 (defun lohalf (n) ; return low halfword
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
162 (logand n masklo))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
163
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
164 ;; Visible functions
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
165
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
166 ;; Arithmetic functions
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
167 (defun f+ (a1 a2)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
168 "Returns the sum of two floating point numbers."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
169 (let ((f1 (fmax a1 a2))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
170 (f2 (fmin a1 a2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
171 (if (same-sign a1 a2)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
172 (setq f1 (fashr f1) ; shift right to avoid overflow
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
173 f2 (fashr f2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
174 (normalize
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
175 (cons (+ (car f1) (ash (car f2) (- (cdr f2) (cdr f1))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
176 (cdr f1)))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
177
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
178 (defun f- (a1 &optional a2) ; unary or binary minus
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
179 "Returns the difference of two floating point numbers."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
180 (if a2
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
181 (f+ a1 (f- a2))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
182 (normalize (cons (- (car a1)) (cdr a1)))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
183
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
184 (defun f* (a1 a2) ; multiply in halfword chunks
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
185 "Returns the product of two floating point numbers."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
186 (let* ((i1 (car (fabs a1)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
187 (i2 (car (fabs a2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
188 (sign (not (same-sign a1 a2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
189 (prodlo (+ (hihalf (* (lohalf i1) (lohalf i2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
190 (lohalf (* (hihalf i1) (lohalf i2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
191 (lohalf (* (lohalf i1) (hihalf i2)))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
192 (prodhi (+ (* (hihalf i1) (hihalf i2))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
193 (hihalf (* (hihalf i1) (lohalf i2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
194 (hihalf (* (lohalf i1) (hihalf i2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
195 (hihalf prodlo))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
196 (if (> (lohalf prodlo) round-limit)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
197 (setq prodhi (1+ prodhi))) ; round off truncated bits
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
198 (normalize
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
199 (cons (if sign (- prodhi) prodhi)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
200 (+ (cdr (fabs a1)) (cdr (fabs a2)) mantissa-bits)))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
201
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
202 (defun f/ (a1 a2) ; SLOW subtract-and-shift algorithm
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
203 "Returns the quotient of two floating point numbers."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
204 (if (zerop (car a2)) ; if divide by 0
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
205 (signal 'arith-error (list "attempt to divide by zero" a1 a2))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
206 (let ((bits (1- maxbit))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
207 (quotient 0)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
208 (dividend (car (fabs a1)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
209 (divisor (car (fabs a2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
210 (sign (not (same-sign a1 a2))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
211 (while (natnump bits)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
212 (if (< (- dividend divisor) 0)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
213 (setq quotient (ash quotient 1))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
214 (setq quotient (1+ (ash quotient 1))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
215 dividend (- dividend divisor)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
216 (setq dividend (ash dividend 1)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
217 bits (1- bits)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
218 (normalize
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
219 (cons (if sign (- quotient) quotient)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
220 (- (cdr (fabs a1)) (cdr (fabs a2)) (1- maxbit)))))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
221
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
222 (defun f% (a1 a2)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
223 "Returns the remainder of first floating point number divided by second."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
224 (f- a1 (f* (ftrunc (f/ a1 a2)) a2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
225
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
226
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
227 ;; Comparison functions
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
228 (defun f= (a1 a2)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
229 "Returns t if two floating point numbers are equal, nil otherwise."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
230 (equal a1 a2))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
231
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
232 (defun f> (a1 a2)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
233 "Returns t if first floating point number is greater than second,
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
234 nil otherwise."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
235 (cond ((and (natnump (car a1)) (< (car a2) 0))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
236 t) ; a1 nonnegative, a2 negative
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
237 ((and (> (car a1) 0) (<= (car a2) 0))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
238 t) ; a1 positive, a2 nonpositive
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
239 ((and (<= (car a1) 0) (natnump (car a2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
240 nil) ; a1 nonpos, a2 nonneg
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
241 ((/= (cdr a1) (cdr a2)) ; same signs. exponents differ
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
242 (> (cdr a1) (cdr a2))) ; compare the mantissas.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
243 (t
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
244 (> (car a1) (car a2))))) ; same exponents.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
245
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
246 (defun f>= (a1 a2)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
247 "Returns t if first floating point number is greater than or equal to
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
248 second, nil otherwise."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
249 (or (f> a1 a2) (f= a1 a2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
250
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
251 (defun f< (a1 a2)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
252 "Returns t if first floating point number is less than second,
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
253 nil otherwise."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
254 (not (f>= a1 a2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
255
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
256 (defun f<= (a1 a2)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
257 "Returns t if first floating point number is less than or equal to
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
258 second, nil otherwise."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
259 (not (f> a1 a2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
260
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
261 (defun f/= (a1 a2)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
262 "Returns t if first floating point number is not equal to second,
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
263 nil otherwise."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
264 (not (f= a1 a2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
265
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
266 (defun fmin (a1 a2)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
267 "Returns the minimum of two floating point numbers."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
268 (if (f< a1 a2) a1 a2))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
269
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
270 (defun fmax (a1 a2)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
271 "Returns the maximum of two floating point numbers."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
272 (if (f> a1 a2) a1 a2))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
273
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
274 (defun fzerop (fnum)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
275 "Returns t if the floating point number is zero, nil otherwise."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
276 (= (car fnum) 0))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
277
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
278 (defun floatp (fnum)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
279 "Returns t if the arg is a floating point number, nil otherwise."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
280 (and (consp fnum) (integerp (car fnum)) (integerp (cdr fnum))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
281
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
282 ;; Conversion routines
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
283 (defun f (int)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
284 "Convert the integer argument to floating point, like a C cast operator."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
285 (normalize (cons int '0)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
286
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
287 (defun int-to-hex-string (int)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
288 "Convert the integer argument to a C-style hexadecimal string."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
289 (let ((shiftval -20)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
290 (str "0x")
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
291 (hex-chars "0123456789ABCDEF"))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
292 (while (<= shiftval 0)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
293 (setq str (concat str (char-to-string
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
294 (aref hex-chars
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
295 (logand (lsh int shiftval) 15))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
296 shiftval (+ shiftval 4)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
297 str))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
298
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
299 (defun ftrunc (fnum) ; truncate fractional part
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
300 "Truncate the fractional part of a floating point number."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
301 (cond ((natnump (cdr fnum)) ; it's all integer, return number as is
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
302 fnum)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
303 ((<= (cdr fnum) (- maxbit)) ; it's all fractional, return 0
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
304 '(0 . 1))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
305 (t ; otherwise mask out fractional bits
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
306 (let ((mant (car fnum)) (exp (cdr fnum)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
307 (normalize
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
308 (cons (if (natnump mant) ; if negative, use absolute value
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
309 (ash (ash mant exp) (- exp))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
310 (- (ash (ash (- mant) exp) (- exp))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
311 exp))))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
312
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
313 (defun fint (fnum) ; truncate and convert to integer
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
314 "Convert the floating point number to integer, with truncation,
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
315 like a C cast operator."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
316 (let* ((tf (ftrunc fnum)) (tint (car tf)) (texp (cdr tf)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
317 (cond ((>= texp mantissa-bits) ; too high, return "maxint"
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
318 mantissa-maxval)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
319 ((<= texp (- mantissa-bits)) ; too low, return "minint"
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
320 mantissa-minval)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
321 (t ; in range
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
322 (ash tint texp))))) ; shift so that exponent is 0
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
323
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
324 (defun float-to-string (fnum &optional sci)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
325 "Convert the floating point number to a decimal string.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
326 Optional second argument non-nil means use scientific notation."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
327 (let* ((value (fabs fnum)) (sign (< (car fnum) 0))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
328 (power 0) (result 0) (str "")
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
329 (temp 0) (pow10 _f1))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
330
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
331 (if (f= fnum _f0)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
332 "0"
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
333 (if (f>= value _f1) ; find largest power of 10 <= value
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
334 (progn ; value >= 1, power is positive
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
335 (while (f<= (setq temp (f* pow10 highest-power-of-10)) value)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
336 (setq pow10 temp
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
337 power (+ power decimal-digits)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
338 (while (f<= (setq temp (f* pow10 _f10)) value)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
339 (setq pow10 temp
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
340 power (1+ power))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
341 (progn ; value < 1, power is negative
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
342 (while (f> (setq temp (f/ pow10 highest-power-of-10)) value)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
343 (setq pow10 temp
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
344 power (- power decimal-digits)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
345 (while (f> pow10 value)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
346 (setq pow10 (f/ pow10 _f10)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
347 power (1- power)))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
348 ; get value in range 100000 to 999999
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
349 (setq value (f* (f/ value pow10) all-decimal-digs-minval)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
350 result (ftrunc value))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
351 (let (int)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
352 (if (f> (f- value result) _f1/2) ; round up if remainder > 0.5
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
353 (setq int (1+ (fint result)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
354 (setq int (fint result)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
355 (setq str (int-to-string int))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
356 (if (>= int 1000000)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
357 (setq power (1+ power))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
358
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
359 (if sci ; scientific notation
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
360 (setq str (concat (substring str 0 1) "." (substring str 1)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
361 "E" (int-to-string power)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
362
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
363 ; regular decimal string
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
364 (cond ((>= power (1- decimal-digits))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
365 ; large power, append zeroes
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
366 (let ((zeroes (- power decimal-digits)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
367 (while (natnump zeroes)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
368 (setq str (concat str "0")
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
369 zeroes (1- zeroes)))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
370
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
371 ; negative power, prepend decimal
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
372 ((< power 0) ; point and zeroes
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
373 (let ((zeroes (- (- power) 2)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
374 (while (natnump zeroes)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
375 (setq str (concat "0" str)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
376 zeroes (1- zeroes)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
377 (setq str (concat "0." str))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
378
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
379 (t ; in range, insert decimal point
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
380 (setq str (concat
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
381 (substring str 0 (1+ power))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
382 "."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
383 (substring str (1+ power)))))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
384
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
385 (if sign ; if negative, prepend minus sign
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
386 (concat "-" str)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
387 str))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
388
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
389
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
390 ;; string to float conversion.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
391 ;; accepts scientific notation, but ignores anything after the first two
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
392 ;; digits of the exponent.
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
393 (defun string-to-float (str)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
394 "Convert the string to a floating point number.
202
ae5ace097df2 *** empty log message ***
Jim Blandy <jimb@redhat.com>
parents: 67
diff changeset
395 Accepts a decimal string in scientific notation, with exponent preceded
ae5ace097df2 *** empty log message ***
Jim Blandy <jimb@redhat.com>
parents: 67
diff changeset
396 by either E or e. Only the six most significant digits of the integer
ae5ace097df2 *** empty log message ***
Jim Blandy <jimb@redhat.com>
parents: 67
diff changeset
397 and fractional parts are used; only the first two digits of the exponent
ae5ace097df2 *** empty log message ***
Jim Blandy <jimb@redhat.com>
parents: 67
diff changeset
398 are used. Negative signs preceding both the decimal number and the exponent
59
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
399 are recognized."
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
400
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
401 (if (string-match floating-point-regexp str 0)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
402 (let (power)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
403 (f*
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
404 ; calculate the mantissa
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
405 (let* ((int-subst (extract-match str 2))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
406 (fract-subst (extract-match str 4))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
407 (digit-string (concat int-subst fract-subst))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
408 (mant-sign (equal (extract-match str 1) "-"))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
409 (leading-0s 0) (round-up nil))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
410
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
411 ; get rid of leading 0's
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
412 (setq power (- (length int-subst) decimal-digits))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
413 (while (and (< leading-0s (length digit-string))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
414 (= (aref digit-string leading-0s) ?0))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
415 (setq leading-0s (1+ leading-0s)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
416 (setq power (- power leading-0s)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
417 digit-string (substring digit-string leading-0s))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
418
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
419 ; if more than 6 digits, round off
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
420 (if (> (length digit-string) decimal-digits)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
421 (setq round-up (>= (aref digit-string decimal-digits) ?5)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
422 digit-string (substring digit-string 0 decimal-digits))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
423 (setq power (+ power (- decimal-digits (length digit-string)))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
424
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
425 ; round up and add minus sign, if necessary
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
426 (f (* (+ (string-to-int digit-string)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
427 (if round-up 1 0))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
428 (if mant-sign -1 1))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
429
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
430 ; calculate the exponent (power of ten)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
431 (let* ((expt-subst (extract-match str 9))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
432 (expt-sign (equal (extract-match str 8) "-"))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
433 (expt 0) (chunks 0) (tens 0) (exponent _f1)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
434 (func 'f*))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
435
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
436 (setq expt (+ (* (string-to-int
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
437 (substring expt-subst 0
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
438 (min expt-digits (length expt-subst))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
439 (if expt-sign -1 1))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
440 power))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
441 (if (< expt 0) ; if power of 10 negative
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
442 (setq expt (- expt) ; take abs val of exponent
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
443 func 'f/)) ; and set up to divide, not multiply
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
444
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
445 (setq chunks (/ expt decimal-digits)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
446 tens (% expt decimal-digits))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
447 ; divide or multiply by "chunks" of 10**6
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
448 (while (> chunks 0)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
449 (setq exponent (funcall func exponent highest-power-of-10)
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
450 chunks (1- chunks)))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
451 ; divide or multiply by remaining power of ten
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
452 (funcall func exponent (aref powers-of-10 tens)))))
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
453
a94f4994dc6d Initial revision
Richard M. Stallman <rms@gnu.org>
parents:
diff changeset
454 _f0)) ; if invalid, return 0
584
4cd7543be581 *** empty log message ***
Jim Blandy <jimb@redhat.com>
parents: 202
diff changeset
455
4cd7543be581 *** empty log message ***
Jim Blandy <jimb@redhat.com>
parents: 202
diff changeset
456 (provide 'float)
4cd7543be581 *** empty log message ***
Jim Blandy <jimb@redhat.com>
parents: 202
diff changeset
457
660
08eb386dd0f3 *** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents: 584
diff changeset
458 ;;; float.el ends here