| ... |
... |
@@ -4,12 +4,6 @@ |
|
4
|
4
|
|
|
5
|
5
|
(in-package "EXTENSIONS-TESTS")
|
|
6
|
6
|
|
|
7
|
|
-(define-test float-to-hex-string
|
|
8
|
|
- (assert-equal "0x1.8p+1" (ext:float-to-hex-string 3.0d0))
|
|
9
|
|
- (assert-equal "0x1.8p+1f" (ext:float-to-hex-string 3.0f0))
|
|
10
|
|
- (assert-equal "0x1.8p+1w" (ext:float-to-hex-string 3.0w0))
|
|
11
|
|
- (assert-equal "-0x1.8p+1" (ext:float-to-hex-string -3.0d0)))
|
|
12
|
|
-
|
|
13
|
7
|
;;; ---- write-hex-float / float-to-hex-string tests -------------------------
|
|
14
|
8
|
|
|
15
|
9
|
(define-test write-double-zero
|
| ... |
... |
@@ -91,150 +85,65 @@ |
|
91
|
85
|
(ext:float-to-hex-string (- 1.0w0 (scale-float 1.0w0 -54)))))
|
|
92
|
86
|
|
|
93
|
87
|
|
|
94
|
|
-
|
|
95
|
|
-(defun get-double-bits (val)
|
|
96
|
|
- (multiple-value-bind (hi lo) (kernel:double-float-bits val)
|
|
97
|
|
- (logior (ash (ldb (byte 32 0) hi) 32) (ldb (byte 32 0) lo))))
|
|
98
|
|
-
|
|
99
|
|
-(defun get-single-bits (val)
|
|
100
|
|
- (ldb (byte 32 0) (kernel:single-float-bits val)))
|
|
101
|
|
-
|
|
102
|
|
-(define-test test-hex-syntax
|
|
103
|
|
- (:tag :validation)
|
|
104
|
|
- (assert-error 'ext:hex-float-parse-error (ext:read-hex-float "inf"))
|
|
105
|
|
- (assert-error 'ext:hex-float-parse-error (ext:read-hex-float "0x.p+0"))
|
|
106
|
|
- (assert-error 'ext:hex-float-parse-error (ext:read-hex-float "0x1.0p")))
|
|
107
|
|
-
|
|
108
|
|
-(define-test test-cliff-boundaries
|
|
109
|
|
- (:tag :precision)
|
|
110
|
|
- ;; Double Precision (-1022 Cliff)
|
|
111
|
|
-
|
|
112
|
|
- (assert-equal #x0010000000000000
|
|
113
|
|
- (get-double-bits (ext:read-hex-float "0x1.0000000000000p-1022")))
|
|
114
|
|
- (assert-equal #x000fffffffffffff
|
|
115
|
|
- (get-double-bits (ext:read-hex-float "0x0.fffffffffffffp-1022")))
|
|
116
|
|
- (assert-equal #x001f0195cb356b8f
|
|
117
|
|
- (get-double-bits (ext:read-hex-float "0x1.f0195cb356b8fp-1022")))
|
|
118
|
|
-
|
|
119
|
|
- ;; Single Precision (-126 Cliff)
|
|
120
|
|
-
|
|
121
|
|
- (assert-equal #x00800000
|
|
122
|
|
- (get-single-bits (ext:read-hex-float "0x1.000000p-126f")))
|
|
123
|
|
- (assert-equal #x00400000
|
|
124
|
|
- (get-single-bits (ext:read-hex-float "0x0.800000p-126f")))
|
|
125
|
|
- (assert-equal #x7f7fffff
|
|
126
|
|
- (get-single-bits (ext:read-hex-float "0x1.fffffep+127f"))))
|
|
127
|
|
-
|
|
128
|
|
-(define-test test-negative-zero
|
|
129
|
|
- (:tag :edge-cases)
|
|
130
|
|
- (assert-equal #x8000000000000000
|
|
131
|
|
- (get-double-bits (ext:read-hex-float "-0x0.0p+0")))
|
|
132
|
|
- (assert-equal #x80000000
|
|
133
|
|
- (get-single-bits (ext:read-hex-float "-0x0.0p+0f")))
|
|
134
|
|
- (assert-true (typep (ext:read-hex-float "-0x0.0p+0f")
|
|
135
|
|
- 'single-float)))
|
|
136
|
|
-
|
|
137
|
|
-(define-test test-subnormal-boundaries
|
|
138
|
|
- (:tag :edge)
|
|
139
|
|
- ;; Test smallest single-float subnormal
|
|
140
|
|
- (let* ((val (kernel:make-single-float 1))
|
|
141
|
|
- (str (ext:float-to-hex-string val))
|
|
142
|
|
- (parsed (ext:read-hex-float str)))
|
|
143
|
|
- (assert-equal (get-single-bits val) (get-single-bits parsed)
|
|
144
|
|
- val str parsed))
|
|
145
|
|
- ;; Test smallest double-float subnormal
|
|
146
|
|
- (let* ((val (kernel:make-double-float 0 1))
|
|
147
|
|
- (str (ext:float-to-hex-string val))
|
|
148
|
|
- (parsed (ext:read-hex-float str)))
|
|
149
|
|
- (assert-equal (get-double-bits val) (get-double-bits parsed)
|
|
150
|
|
- val str parsed)))
|
|
151
|
|
-
|
|
152
|
|
-(define-test test-double-roundtrip
|
|
153
|
|
- (:tag :stress)
|
|
154
|
|
- (loop repeat 10000 do
|
|
155
|
|
- (let* ((hi-bits (random #x100000000))
|
|
156
|
|
- (hi (if (logbitp 31 hi-bits) (- hi-bits #x100000000) hi-bits))
|
|
157
|
|
- (lo (random #x100000000))
|
|
158
|
|
- (val (kernel:make-double-float hi lo)))
|
|
159
|
|
- (unless (or (ext:float-nan-p val) (ext:float-infinity-p val))
|
|
160
|
|
- (let* ((str (ext:float-to-hex-string val))
|
|
161
|
|
- (parsed (ext:read-hex-float str)))
|
|
162
|
|
- (assert-equal (get-double-bits val)
|
|
163
|
|
- (get-double-bits parsed)
|
|
164
|
|
- val str parsed))))))
|
|
165
|
|
-
|
|
166
|
|
-(define-test test-single-roundtrip
|
|
167
|
|
- (:tag :stress)
|
|
168
|
|
- (loop repeat 10000 do
|
|
169
|
|
- (let* ((bits-raw (random #x100000000))
|
|
170
|
|
- (bits (if (logbitp 31 bits-raw) (- bits-raw #x100000000) bits-raw))
|
|
171
|
|
- (val (kernel:make-single-float bits)))
|
|
172
|
|
- (unless (or (ext:float-nan-p val) (ext:float-infinity-p val))
|
|
173
|
|
- (let* ((str (concatenate 'string (ext:float-to-hex-string val) "f"))
|
|
174
|
|
- (parsed (ext:read-hex-float str)))
|
|
175
|
|
- (assert-equal (get-single-bits val)
|
|
176
|
|
- (get-single-bits parsed)
|
|
177
|
|
- val str parsed))))))
|
|
178
|
|
-
|
|
179
|
88
|
;;; ---- read-hex-float tests ------------------------------------------------
|
|
180
|
89
|
|
|
181
|
90
|
(define-test read-double-zero
|
|
182
|
|
- (assert-true (eql 0.0d0 (ext:read-hex-float "0x0p+0")))
|
|
183
|
|
- (assert-true (eql -0.0d0 (ext:read-hex-float "-0x0p+0"))))
|
|
|
91
|
+ (assert-eql 0.0d0 (ext:read-hex-float "0x0p+0"))
|
|
|
92
|
+ (assert-eql -0.0d0 (ext:read-hex-float "-0x0p+0")))
|
|
184
|
93
|
|
|
185
|
94
|
(define-test read-double-values
|
|
186
|
|
- (assert-true (eql 1.0d0 (ext:read-hex-float "0x1p+0")))
|
|
187
|
|
- (assert-true (eql -1.0d0 (ext:read-hex-float "-0x1p+0")))
|
|
188
|
|
- (assert-true (eql 2.0d0 (ext:read-hex-float "0x1p+1")))
|
|
189
|
|
- (assert-true (eql 0.5d0 (ext:read-hex-float "0x1p-1")))
|
|
190
|
|
- (assert-true (eql 3.0d0 (ext:read-hex-float "0x1.8p+1")))
|
|
191
|
|
- (assert-true (eql -3.0d0 (ext:read-hex-float "-0x1.8p+1")))
|
|
192
|
|
- (assert-true (eql pi (ext:read-hex-float "0x1.921fb54442d18p+1"))))
|
|
|
95
|
+ (assert-eql 1.0d0 (ext:read-hex-float "0x1p+0"))
|
|
|
96
|
+ (assert-eql -1.0d0 (ext:read-hex-float "-0x1p+0"))
|
|
|
97
|
+ (assert-eql 2.0d0 (ext:read-hex-float "0x1p+1"))
|
|
|
98
|
+ (assert-eql 0.5d0 (ext:read-hex-float "0x1p-1"))
|
|
|
99
|
+ (assert-eql 3.0d0 (ext:read-hex-float "0x1.8p+1"))
|
|
|
100
|
+ (assert-eql -3.0d0 (ext:read-hex-float "-0x1.8p+1"))
|
|
|
101
|
+ (assert-eql pi (ext:read-hex-float "0x1.921fb54442d18p+1")))
|
|
193
|
102
|
|
|
194
|
103
|
(define-test read-double-denormals
|
|
195
|
|
- (assert-true (eql (scale-float 1.0d0 -1023)
|
|
196
|
|
- (ext:read-hex-float "0x0.8p-1022")))
|
|
197
|
|
- (assert-true (eql (scale-float 1.0d0 -1074)
|
|
198
|
|
- (ext:read-hex-float "0x0.0000000000001p-1022"))))
|
|
|
104
|
+ (assert-eql (scale-float 1.0d0 -1023)
|
|
|
105
|
+ (ext:read-hex-float "0x0.8p-1022"))
|
|
|
106
|
+ (assert-eql (scale-float 1.0d0 -1074)
|
|
|
107
|
+ (ext:read-hex-float "0x0.0000000000001p-1022")))
|
|
199
|
108
|
|
|
200
|
109
|
(define-test read-double-case-insensitive
|
|
201
|
|
- (assert-true (eql 3.0d0 (ext:read-hex-float "0X1.8P+1")))
|
|
202
|
|
- (assert-true (eql 0.5d0 (ext:read-hex-float "0X1P-1"))))
|
|
|
110
|
+ (assert-eql 3.0d0 (ext:read-hex-float "0X1.8P+1"))
|
|
|
111
|
+ (assert-eql 0.5d0 (ext:read-hex-float "0X1P-1")))
|
|
203
|
112
|
|
|
204
|
113
|
(define-test read-single-zero
|
|
205
|
|
- (assert-true (eql 0.0f0 (ext:read-hex-float "0x0p+0f")))
|
|
206
|
|
- (assert-true (eql -0.0f0 (ext:read-hex-float "-0x0p+0f"))))
|
|
|
114
|
+ (assert-eql 0.0f0 (ext:read-hex-float "0x0p+0f"))
|
|
|
115
|
+ (assert-eql -0.0f0 (ext:read-hex-float "-0x0p+0f")))
|
|
207
|
116
|
|
|
208
|
117
|
(define-test read-single-values
|
|
209
|
|
- (assert-true (eql 1.0f0 (ext:read-hex-float "0x1p+0f")))
|
|
210
|
|
- (assert-true (eql -1.0f0 (ext:read-hex-float "-0x1p+0f")))
|
|
211
|
|
- (assert-true (eql 2.0f0 (ext:read-hex-float "0x1p+1f")))
|
|
212
|
|
- (assert-true (eql 3.0f0 (ext:read-hex-float "0x1.8p+1f")))
|
|
213
|
|
- (assert-true (eql (/ 1.0f0 3.0f0)
|
|
214
|
|
- (ext:read-hex-float "0x1.555556p-2f")))
|
|
215
|
|
- (assert-true (eql most-positive-single-float
|
|
216
|
|
- (ext:read-hex-float "0x1.fffffep+127f")))
|
|
217
|
|
- (assert-true (eql (scale-float 1.0f0 -149)
|
|
218
|
|
- (ext:read-hex-float "0x0.000002p-126f"))))
|
|
|
118
|
+ (assert-eql 1.0f0 (ext:read-hex-float "0x1p+0f"))
|
|
|
119
|
+ (assert-eql -1.0f0 (ext:read-hex-float "-0x1p+0f"))
|
|
|
120
|
+ (assert-eql 2.0f0 (ext:read-hex-float "0x1p+1f"))
|
|
|
121
|
+ (assert-eql 3.0f0 (ext:read-hex-float "0x1.8p+1f"))
|
|
|
122
|
+ (assert-eql (/ 1.0f0 3.0f0)
|
|
|
123
|
+ (ext:read-hex-float "0x1.555556p-2f"))
|
|
|
124
|
+ (assert-eql most-positive-single-float
|
|
|
125
|
+ (ext:read-hex-float "0x1.fffffep+127f"))
|
|
|
126
|
+ (assert-eql (scale-float 1.0f0 -149)
|
|
|
127
|
+ (ext:read-hex-float "0x0.000002p-126f")))
|
|
219
|
128
|
|
|
220
|
129
|
(define-test read-single-case-insensitive
|
|
221
|
|
- (assert-true (eql 3.0f0 (ext:read-hex-float "0x1.8p+1F"))))
|
|
|
130
|
+ (assert-eql 3.0f0 (ext:read-hex-float "0x1.8p+1F")))
|
|
222
|
131
|
|
|
223
|
132
|
(define-test read-double-double-zero
|
|
224
|
|
- (assert-true (eql 0.0w0 (ext:read-hex-float "0x0p+0w")))
|
|
225
|
|
- (assert-true (eql -0.0w0 (ext:read-hex-float "-0x0p+0w"))))
|
|
|
133
|
+ (assert-eql 0.0w0 (ext:read-hex-float "0x0p+0w"))
|
|
|
134
|
+ (assert-eql -0.0w0 (ext:read-hex-float "-0x0p+0w")))
|
|
226
|
135
|
|
|
227
|
136
|
(define-test read-double-double-values
|
|
228
|
|
- (assert-true (eql 1.0w0 (ext:read-hex-float "0x1p+0w")))
|
|
229
|
|
- (assert-true (eql -1.0w0 (ext:read-hex-float "-0x1p+0w")))
|
|
230
|
|
- (assert-true (eql 3.0w0 (ext:read-hex-float "0x1.8p+1w")))
|
|
231
|
|
- (assert-true (eql (scale-float 1.0w0 64)
|
|
232
|
|
- (ext:read-hex-float "0x1p+64w")))
|
|
233
|
|
- (assert-true (eql (coerce pi 'ext:double-double-float)
|
|
234
|
|
- (ext:read-hex-float "0x1.921fb54442d18p+1w"))))
|
|
|
137
|
+ (assert-eql 1.0w0 (ext:read-hex-float "0x1p+0w"))
|
|
|
138
|
+ (assert-eql -1.0w0 (ext:read-hex-float "-0x1p+0w"))
|
|
|
139
|
+ (assert-eql 3.0w0 (ext:read-hex-float "0x1.8p+1w"))
|
|
|
140
|
+ (assert-eql (scale-float 1.0w0 64)
|
|
|
141
|
+ (ext:read-hex-float "0x1p+64w"))
|
|
|
142
|
+ (assert-eql (coerce pi 'ext:double-double-float)
|
|
|
143
|
+ (ext:read-hex-float "0x1.921fb54442d18p+1w")))
|
|
235
|
144
|
|
|
236
|
145
|
(define-test read-double-double-case-insensitive
|
|
237
|
|
- (assert-true (eql 3.0w0 (ext:read-hex-float "0x1.8p+1W"))))
|
|
|
146
|
+ (assert-eql 3.0w0 (ext:read-hex-float "0x1.8p+1W")))
|
|
238
|
147
|
|
|
239
|
148
|
|
|
240
|
149
|
;;; ---- round-trip tests ----------------------------------------------------
|
| ... |
... |
@@ -246,7 +155,7 @@ |
|
246
|
155
|
(scale-float 1.0d0 -1022)
|
|
247
|
156
|
(scale-float 1.0d0 -1074)
|
|
248
|
157
|
(/ 1.0d0 3.0d0)))
|
|
249
|
|
- (assert-true (eql x (ext:read-hex-float (ext:float-to-hex-string x))) x)))
|
|
|
158
|
+ (assert-eql x (ext:read-hex-float (ext:float-to-hex-string x)))))
|
|
250
|
159
|
|
|
251
|
160
|
(define-test round-trip-single
|
|
252
|
161
|
(dolist (x (list 0.0f0 -0.0f0 1.0f0 -1.0f0
|
| ... |
... |
@@ -255,8 +164,7 @@ |
|
255
|
164
|
(scale-float 1.0f0 -126)
|
|
256
|
165
|
(scale-float 1.0f0 -149)
|
|
257
|
166
|
(/ 1.0f0 3.0f0)))
|
|
258
|
|
- (assert-true (eql x (ext:read-hex-float (ext:float-to-hex-string x)))
|
|
259
|
|
- x)))
|
|
|
167
|
+ (assert-eql x (ext:read-hex-float (ext:float-to-hex-string x)))))
|
|
260
|
168
|
|
|
261
|
169
|
(define-test round-trip-double-double
|
|
262
|
170
|
(dolist (x (list 0.0w0 -0.0w0 1.0w0 -1.0w0
|
| ... |
... |
@@ -266,27 +174,27 @@ |
|
266
|
174
|
(- 1.0w0 (scale-float 1.0w0 -54))
|
|
267
|
175
|
ext:most-positive-double-double-float
|
|
268
|
176
|
ext:least-positive-double-double-float))
|
|
269
|
|
- (assert-true (eql x (ext:read-hex-float (ext:float-to-hex-string x))) x)))
|
|
|
177
|
+ (assert-eql x (ext:read-hex-float (ext:float-to-hex-string x)))))
|
|
270
|
178
|
|
|
271
|
179
|
|
|
272
|
180
|
;;; ---- read-hex-float-from-string tests ------------------------------------
|
|
273
|
181
|
|
|
274
|
182
|
(define-test read-from-string-positions
|
|
275
|
183
|
(multiple-value-bind (val pos)
|
|
276
|
|
- (ext::read-hex-float-from-string "0x1.8p+1")
|
|
277
|
|
- (assert-true (eql 3.0d0 val))
|
|
|
184
|
+ (ext:read-hex-float "0x1.8p+1")
|
|
|
185
|
+ (assert-eql 3.0d0 val)
|
|
278
|
186
|
(assert-equal 8 pos))
|
|
279
|
187
|
(multiple-value-bind (val pos)
|
|
280
|
|
- (ext::read-hex-float-from-string "0x1.8p+1f")
|
|
281
|
|
- (assert-true (eql 3.0f0 val))
|
|
|
188
|
+ (ext:read-hex-float "0x1.8p+1f")
|
|
|
189
|
+ (assert-eql 3.0f0 val)
|
|
282
|
190
|
(assert-equal 9 pos))
|
|
283
|
191
|
(multiple-value-bind (val pos)
|
|
284
|
|
- (ext::read-hex-float-from-string "xxx0x1.8p+1" :start 3)
|
|
285
|
|
- (assert-true (eql 3.0d0 val))
|
|
|
192
|
+ (ext:read-hex-float "xxx0x1.8p+1" :start 3)
|
|
|
193
|
+ (assert-eql 3.0d0 val)
|
|
286
|
194
|
(assert-equal 11 pos))
|
|
287
|
195
|
(multiple-value-bind (val pos)
|
|
288
|
|
- (ext::read-hex-float-from-string "0x1.8p+1 etc")
|
|
289
|
|
- (assert-true (eql 3.0d0 val))
|
|
|
196
|
+ (ext:read-hex-float "0x1.8p+1 etc")
|
|
|
197
|
+ (assert-eql 3.0d0 val)
|
|
290
|
198
|
(assert-equal 8 pos)))
|
|
291
|
199
|
|
|
292
|
200
|
|
| ... |
... |
@@ -337,3 +245,58 @@ |
|
337
|
245
|
(assert-error 'ext:hex-float-parse-error
|
|
338
|
246
|
(ext:read-hex-float "-")))
|
|
339
|
247
|
|
|
|
248
|
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
249
|
+(defun get-double-bits (val)
|
|
|
250
|
+ (multiple-value-bind (hi lo) (kernel:double-float-bits val)
|
|
|
251
|
+ (logior (ash (ldb (byte 32 0) hi) 32) (ldb (byte 32 0) lo))))
|
|
|
252
|
+
|
|
|
253
|
+(defun get-single-bits (val)
|
|
|
254
|
+ (ldb (byte 32 0) (kernel:single-float-bits val)))
|
|
|
255
|
+
|
|
|
256
|
+(define-test test-cliff-boundaries
|
|
|
257
|
+ (:tag :precision)
|
|
|
258
|
+ ;; Double Precision (-1022 Cliff)
|
|
|
259
|
+
|
|
|
260
|
+ (assert-equal #x0010000000000000
|
|
|
261
|
+ (get-double-bits (ext:read-hex-float "0x1.0000000000000p-1022")))
|
|
|
262
|
+ (assert-equal #x000fffffffffffff
|
|
|
263
|
+ (get-double-bits (ext:read-hex-float "0x0.fffffffffffffp-1022")))
|
|
|
264
|
+ (assert-equal #x001f0195cb356b8f
|
|
|
265
|
+ (get-double-bits (ext:read-hex-float "0x1.f0195cb356b8fp-1022")))
|
|
|
266
|
+
|
|
|
267
|
+ ;; Single Precision (-126 Cliff)
|
|
|
268
|
+
|
|
|
269
|
+ (assert-equal #x00800000
|
|
|
270
|
+ (get-single-bits (ext:read-hex-float "0x1.000000p-126f")))
|
|
|
271
|
+ (assert-equal #x00400000
|
|
|
272
|
+ (get-single-bits (ext:read-hex-float "0x0.800000p-126f")))
|
|
|
273
|
+ (assert-equal #x7f7fffff
|
|
|
274
|
+ (get-single-bits (ext:read-hex-float "0x1.fffffep+127f"))))
|
|
|
275
|
+
|
|
|
276
|
+(define-test test-double-roundtrip
|
|
|
277
|
+ (:tag :stress)
|
|
|
278
|
+ (loop repeat 10000 do
|
|
|
279
|
+ (let* ((hi-bits (random #x100000000))
|
|
|
280
|
+ (hi (if (logbitp 31 hi-bits) (- hi-bits #x100000000) hi-bits))
|
|
|
281
|
+ (lo (random #x100000000))
|
|
|
282
|
+ (val (kernel:make-double-float hi lo)))
|
|
|
283
|
+ (unless (or (ext:float-nan-p val) (ext:float-infinity-p val))
|
|
|
284
|
+ (let* ((str (ext:float-to-hex-string val))
|
|
|
285
|
+ (parsed (ext:read-hex-float str)))
|
|
|
286
|
+ (assert-equal (get-double-bits val)
|
|
|
287
|
+ (get-double-bits parsed)
|
|
|
288
|
+ val str parsed))))))
|
|
|
289
|
+
|
|
|
290
|
+(define-test test-single-roundtrip
|
|
|
291
|
+ (:tag :stress)
|
|
|
292
|
+ (loop repeat 10000 do
|
|
|
293
|
+ (let* ((bits-raw (random #x100000000))
|
|
|
294
|
+ (bits (if (logbitp 31 bits-raw) (- bits-raw #x100000000) bits-raw))
|
|
|
295
|
+ (val (kernel:make-single-float bits)))
|
|
|
296
|
+ (unless (or (ext:float-nan-p val) (ext:float-infinity-p val))
|
|
|
297
|
+ (let* ((str (concatenate 'string (ext:float-to-hex-string val) "f"))
|
|
|
298
|
+ (parsed (ext:read-hex-float str)))
|
|
|
299
|
+ (assert-equal (get-single-bits val)
|
|
|
300
|
+ (get-single-bits parsed)
|
|
|
301
|
+ val str parsed))))))
|
|
|
302
|
+ |