a72f9243feb53bb65d6201a03fe288dbe72d3cd9
[ieee754fpu.git] / src / ieee754 / div_rem_sqrt_rsqrt / test_algorithm.py
1 # SPDX-License-Identifier: LGPL-2.1-or-later
2 # See Notices.txt for copyright information
3
4 from nmigen.hdl.ast import Const
5 from .algorithm import (div_rem, UnsignedDivRem, DivRem,
6 Fixed, fixed_sqrt, FixedSqrt, fixed_rsqrt, FixedRSqrt)
7 import unittest
8 import math
9
10
11 class TestDivRemFn(unittest.TestCase):
12 def test_signed(self):
13 test_cases = [
14 # numerator, denominator, quotient, remainder
15 (-8, -8, 1, 0),
16 (-7, -8, 0, -7),
17 (-6, -8, 0, -6),
18 (-5, -8, 0, -5),
19 (-4, -8, 0, -4),
20 (-3, -8, 0, -3),
21 (-2, -8, 0, -2),
22 (-1, -8, 0, -1),
23 (0, -8, 0, 0),
24 (1, -8, 0, 1),
25 (2, -8, 0, 2),
26 (3, -8, 0, 3),
27 (4, -8, 0, 4),
28 (5, -8, 0, 5),
29 (6, -8, 0, 6),
30 (7, -8, 0, 7),
31 (-8, -7, 1, -1),
32 (-7, -7, 1, 0),
33 (-6, -7, 0, -6),
34 (-5, -7, 0, -5),
35 (-4, -7, 0, -4),
36 (-3, -7, 0, -3),
37 (-2, -7, 0, -2),
38 (-1, -7, 0, -1),
39 (0, -7, 0, 0),
40 (1, -7, 0, 1),
41 (2, -7, 0, 2),
42 (3, -7, 0, 3),
43 (4, -7, 0, 4),
44 (5, -7, 0, 5),
45 (6, -7, 0, 6),
46 (7, -7, -1, 0),
47 (-8, -6, 1, -2),
48 (-7, -6, 1, -1),
49 (-6, -6, 1, 0),
50 (-5, -6, 0, -5),
51 (-4, -6, 0, -4),
52 (-3, -6, 0, -3),
53 (-2, -6, 0, -2),
54 (-1, -6, 0, -1),
55 (0, -6, 0, 0),
56 (1, -6, 0, 1),
57 (2, -6, 0, 2),
58 (3, -6, 0, 3),
59 (4, -6, 0, 4),
60 (5, -6, 0, 5),
61 (6, -6, -1, 0),
62 (7, -6, -1, 1),
63 (-8, -5, 1, -3),
64 (-7, -5, 1, -2),
65 (-6, -5, 1, -1),
66 (-5, -5, 1, 0),
67 (-4, -5, 0, -4),
68 (-3, -5, 0, -3),
69 (-2, -5, 0, -2),
70 (-1, -5, 0, -1),
71 (0, -5, 0, 0),
72 (1, -5, 0, 1),
73 (2, -5, 0, 2),
74 (3, -5, 0, 3),
75 (4, -5, 0, 4),
76 (5, -5, -1, 0),
77 (6, -5, -1, 1),
78 (7, -5, -1, 2),
79 (-8, -4, 2, 0),
80 (-7, -4, 1, -3),
81 (-6, -4, 1, -2),
82 (-5, -4, 1, -1),
83 (-4, -4, 1, 0),
84 (-3, -4, 0, -3),
85 (-2, -4, 0, -2),
86 (-1, -4, 0, -1),
87 (0, -4, 0, 0),
88 (1, -4, 0, 1),
89 (2, -4, 0, 2),
90 (3, -4, 0, 3),
91 (4, -4, -1, 0),
92 (5, -4, -1, 1),
93 (6, -4, -1, 2),
94 (7, -4, -1, 3),
95 (-8, -3, 2, -2),
96 (-7, -3, 2, -1),
97 (-6, -3, 2, 0),
98 (-5, -3, 1, -2),
99 (-4, -3, 1, -1),
100 (-3, -3, 1, 0),
101 (-2, -3, 0, -2),
102 (-1, -3, 0, -1),
103 (0, -3, 0, 0),
104 (1, -3, 0, 1),
105 (2, -3, 0, 2),
106 (3, -3, -1, 0),
107 (4, -3, -1, 1),
108 (5, -3, -1, 2),
109 (6, -3, -2, 0),
110 (7, -3, -2, 1),
111 (-8, -2, 4, 0),
112 (-7, -2, 3, -1),
113 (-6, -2, 3, 0),
114 (-5, -2, 2, -1),
115 (-4, -2, 2, 0),
116 (-3, -2, 1, -1),
117 (-2, -2, 1, 0),
118 (-1, -2, 0, -1),
119 (0, -2, 0, 0),
120 (1, -2, 0, 1),
121 (2, -2, -1, 0),
122 (3, -2, -1, 1),
123 (4, -2, -2, 0),
124 (5, -2, -2, 1),
125 (6, -2, -3, 0),
126 (7, -2, -3, 1),
127 (-8, -1, -8, 0), # overflows and wraps around
128 (-7, -1, 7, 0),
129 (-6, -1, 6, 0),
130 (-5, -1, 5, 0),
131 (-4, -1, 4, 0),
132 (-3, -1, 3, 0),
133 (-2, -1, 2, 0),
134 (-1, -1, 1, 0),
135 (0, -1, 0, 0),
136 (1, -1, -1, 0),
137 (2, -1, -2, 0),
138 (3, -1, -3, 0),
139 (4, -1, -4, 0),
140 (5, -1, -5, 0),
141 (6, -1, -6, 0),
142 (7, -1, -7, 0),
143 (-8, 0, -1, -8),
144 (-7, 0, -1, -7),
145 (-6, 0, -1, -6),
146 (-5, 0, -1, -5),
147 (-4, 0, -1, -4),
148 (-3, 0, -1, -3),
149 (-2, 0, -1, -2),
150 (-1, 0, -1, -1),
151 (0, 0, -1, 0),
152 (1, 0, -1, 1),
153 (2, 0, -1, 2),
154 (3, 0, -1, 3),
155 (4, 0, -1, 4),
156 (5, 0, -1, 5),
157 (6, 0, -1, 6),
158 (7, 0, -1, 7),
159 (-8, 1, -8, 0),
160 (-7, 1, -7, 0),
161 (-6, 1, -6, 0),
162 (-5, 1, -5, 0),
163 (-4, 1, -4, 0),
164 (-3, 1, -3, 0),
165 (-2, 1, -2, 0),
166 (-1, 1, -1, 0),
167 (0, 1, 0, 0),
168 (1, 1, 1, 0),
169 (2, 1, 2, 0),
170 (3, 1, 3, 0),
171 (4, 1, 4, 0),
172 (5, 1, 5, 0),
173 (6, 1, 6, 0),
174 (7, 1, 7, 0),
175 (-8, 2, -4, 0),
176 (-7, 2, -3, -1),
177 (-6, 2, -3, 0),
178 (-5, 2, -2, -1),
179 (-4, 2, -2, 0),
180 (-3, 2, -1, -1),
181 (-2, 2, -1, 0),
182 (-1, 2, 0, -1),
183 (0, 2, 0, 0),
184 (1, 2, 0, 1),
185 (2, 2, 1, 0),
186 (3, 2, 1, 1),
187 (4, 2, 2, 0),
188 (5, 2, 2, 1),
189 (6, 2, 3, 0),
190 (7, 2, 3, 1),
191 (-8, 3, -2, -2),
192 (-7, 3, -2, -1),
193 (-6, 3, -2, 0),
194 (-5, 3, -1, -2),
195 (-4, 3, -1, -1),
196 (-3, 3, -1, 0),
197 (-2, 3, 0, -2),
198 (-1, 3, 0, -1),
199 (0, 3, 0, 0),
200 (1, 3, 0, 1),
201 (2, 3, 0, 2),
202 (3, 3, 1, 0),
203 (4, 3, 1, 1),
204 (5, 3, 1, 2),
205 (6, 3, 2, 0),
206 (7, 3, 2, 1),
207 (-8, 4, -2, 0),
208 (-7, 4, -1, -3),
209 (-6, 4, -1, -2),
210 (-5, 4, -1, -1),
211 (-4, 4, -1, 0),
212 (-3, 4, 0, -3),
213 (-2, 4, 0, -2),
214 (-1, 4, 0, -1),
215 (0, 4, 0, 0),
216 (1, 4, 0, 1),
217 (2, 4, 0, 2),
218 (3, 4, 0, 3),
219 (4, 4, 1, 0),
220 (5, 4, 1, 1),
221 (6, 4, 1, 2),
222 (7, 4, 1, 3),
223 (-8, 5, -1, -3),
224 (-7, 5, -1, -2),
225 (-6, 5, -1, -1),
226 (-5, 5, -1, 0),
227 (-4, 5, 0, -4),
228 (-3, 5, 0, -3),
229 (-2, 5, 0, -2),
230 (-1, 5, 0, -1),
231 (0, 5, 0, 0),
232 (1, 5, 0, 1),
233 (2, 5, 0, 2),
234 (3, 5, 0, 3),
235 (4, 5, 0, 4),
236 (5, 5, 1, 0),
237 (6, 5, 1, 1),
238 (7, 5, 1, 2),
239 (-8, 6, -1, -2),
240 (-7, 6, -1, -1),
241 (-6, 6, -1, 0),
242 (-5, 6, 0, -5),
243 (-4, 6, 0, -4),
244 (-3, 6, 0, -3),
245 (-2, 6, 0, -2),
246 (-1, 6, 0, -1),
247 (0, 6, 0, 0),
248 (1, 6, 0, 1),
249 (2, 6, 0, 2),
250 (3, 6, 0, 3),
251 (4, 6, 0, 4),
252 (5, 6, 0, 5),
253 (6, 6, 1, 0),
254 (7, 6, 1, 1),
255 (-8, 7, -1, -1),
256 (-7, 7, -1, 0),
257 (-6, 7, 0, -6),
258 (-5, 7, 0, -5),
259 (-4, 7, 0, -4),
260 (-3, 7, 0, -3),
261 (-2, 7, 0, -2),
262 (-1, 7, 0, -1),
263 (0, 7, 0, 0),
264 (1, 7, 0, 1),
265 (2, 7, 0, 2),
266 (3, 7, 0, 3),
267 (4, 7, 0, 4),
268 (5, 7, 0, 5),
269 (6, 7, 0, 6),
270 (7, 7, 1, 0),
271 ]
272 for (n, d, q, r) in test_cases:
273 self.assertEqual(div_rem(n, d, 4, True), (q, r))
274
275 def test_unsigned(self):
276 for n in range(16):
277 for d in range(16):
278 if d == 0:
279 q = 16 - 1
280 r = n
281 else:
282 # div_rem matches // and % for unsigned integers
283 q = n // d
284 r = n % d
285 self.assertEqual(div_rem(n, d, 4, False), (q, r))
286
287
288 class TestUnsignedDivRem(unittest.TestCase):
289 def helper(self, log2_radix):
290 bit_width = 4
291 for n in range(1 << bit_width):
292 for d in range(1 << bit_width):
293 q, r = div_rem(n, d, bit_width, False)
294 with self.subTest(n=n, d=d, q=q, r=r):
295 udr = UnsignedDivRem(n, d, bit_width, log2_radix)
296 for _ in range(250 * bit_width):
297 self.assertEqual(n, udr.quotient * udr.divisor
298 + udr.remainder)
299 if udr.calculate_stage():
300 break
301 else:
302 self.fail("infinite loop")
303 self.assertEqual(n, udr.quotient * udr.divisor
304 + udr.remainder)
305 self.assertEqual(udr.quotient, q)
306 self.assertEqual(udr.remainder, r)
307
308 def test_radix_2(self):
309 self.helper(1)
310
311 def test_radix_4(self):
312 self.helper(2)
313
314 def test_radix_8(self):
315 self.helper(3)
316
317 def test_radix_16(self):
318 self.helper(4)
319
320
321 class TestDivRem(unittest.TestCase):
322 def helper(self, log2_radix):
323 bit_width = 4
324 for n in range(1 << bit_width):
325 for d in range(1 << bit_width):
326 for signed in False, True:
327 n = Const.normalize(n, (bit_width, signed))
328 d = Const.normalize(d, (bit_width, signed))
329 q, r = div_rem(n, d, bit_width, signed)
330 with self.subTest(n=n, d=d, q=q, r=r, signed=signed):
331 dr = DivRem(n, d, bit_width, signed, log2_radix)
332 for _ in range(250 * bit_width):
333 if dr.calculate_stage():
334 break
335 else:
336 self.fail("infinite loop")
337 self.assertEqual(dr.quotient, q)
338 self.assertEqual(dr.remainder, r)
339
340 def test_radix_2(self):
341 self.helper(1)
342
343 def test_radix_4(self):
344 self.helper(2)
345
346 def test_radix_8(self):
347 self.helper(3)
348
349 def test_radix_16(self):
350 self.helper(4)
351
352
353 class TestFixed(unittest.TestCase):
354 def test_constructor(self):
355 value = Fixed(0, 0, 1, False)
356 self.assertEqual(value.bits, 0)
357 self.assertEqual(value.fract_width, 0)
358 self.assertEqual(value.bit_width, 1)
359 self.assertEqual(value.signed, False)
360 value = Fixed(1, 2, 3, True)
361 self.assertEqual(value.bits, -4)
362 self.assertEqual(value.fract_width, 2)
363 self.assertEqual(value.bit_width, 3)
364 self.assertEqual(value.signed, True)
365 value = Fixed(1, 2, 4, True)
366 self.assertEqual(value.bits, 4)
367 self.assertEqual(value.fract_width, 2)
368 self.assertEqual(value.bit_width, 4)
369 self.assertEqual(value.signed, True)
370 value = Fixed(1.25, 4, 8, True)
371 self.assertEqual(value.bits, 0x14)
372 self.assertEqual(value.fract_width, 4)
373 self.assertEqual(value.bit_width, 8)
374 self.assertEqual(value.signed, True)
375 value = Fixed(Fixed(2, 0, 12, False), 4, 8, True)
376 self.assertEqual(value.bits, 0x20)
377 self.assertEqual(value.fract_width, 4)
378 self.assertEqual(value.bit_width, 8)
379 self.assertEqual(value.signed, True)
380 value = Fixed(0x2FF / 2 ** 8, 8, 12, False)
381 self.assertEqual(value.bits, 0x2FF)
382 self.assertEqual(value.fract_width, 8)
383 self.assertEqual(value.bit_width, 12)
384 self.assertEqual(value.signed, False)
385 value = Fixed(value, 4, 8, True)
386 self.assertEqual(value.bits, 0x2F)
387 self.assertEqual(value.fract_width, 4)
388 self.assertEqual(value.bit_width, 8)
389 self.assertEqual(value.signed, True)
390
391 def helper_test_from_bits(self, bit_width, fract_width):
392 signed = False
393 for bits in range(1 << bit_width):
394 with self.subTest(bit_width=bit_width,
395 fract_width=fract_width,
396 signed=signed,
397 bits=hex(bits)):
398 value = Fixed.from_bits(bits, fract_width, bit_width, signed)
399 self.assertEqual(value.bit_width, bit_width)
400 self.assertEqual(value.fract_width, fract_width)
401 self.assertEqual(value.signed, signed)
402 self.assertEqual(value.bits, bits)
403 signed = True
404 for bits in range(-1 << (bit_width - 1), 1 << (bit_width - 1)):
405 with self.subTest(bit_width=bit_width,
406 fract_width=fract_width,
407 signed=signed,
408 bits=hex(bits)):
409 value = Fixed.from_bits(bits, fract_width, bit_width, signed)
410 self.assertEqual(value.bit_width, bit_width)
411 self.assertEqual(value.fract_width, fract_width)
412 self.assertEqual(value.signed, signed)
413 self.assertEqual(value.bits, bits)
414
415 def test_from_bits(self):
416 for bit_width in range(1, 5):
417 for fract_width in range(bit_width):
418 self.helper_test_from_bits(bit_width, fract_width)
419
420 def test_repr(self):
421 self.assertEqual(repr(Fixed.from_bits(1, 2, 3, False)),
422 "Fixed.from_bits(1, 2, 3, False)")
423 self.assertEqual(repr(Fixed.from_bits(-4, 2, 3, True)),
424 "Fixed.from_bits(-4, 2, 3, True)")
425 self.assertEqual(repr(Fixed.from_bits(-4, 7, 10, True)),
426 "Fixed.from_bits(-4, 7, 10, True)")
427
428 def test_trunc(self):
429 for i in range(-8, 8):
430 value = Fixed.from_bits(i, 2, 4, True)
431 with self.subTest(value=repr(value)):
432 self.assertEqual(math.trunc(value), math.trunc(i / 4))
433
434 def test_int(self):
435 for i in range(-8, 8):
436 value = Fixed.from_bits(i, 2, 4, True)
437 with self.subTest(value=repr(value)):
438 self.assertEqual(int(value), math.trunc(value))
439
440 def test_float(self):
441 for i in range(-8, 8):
442 value = Fixed.from_bits(i, 2, 4, True)
443 with self.subTest(value=repr(value)):
444 self.assertEqual(float(value), i / 4)
445
446 def test_floor(self):
447 for i in range(-8, 8):
448 value = Fixed.from_bits(i, 2, 4, True)
449 with self.subTest(value=repr(value)):
450 self.assertEqual(math.floor(value), math.floor(i / 4))
451
452 def test_ceil(self):
453 for i in range(-8, 8):
454 value = Fixed.from_bits(i, 2, 4, True)
455 with self.subTest(value=repr(value)):
456 self.assertEqual(math.ceil(value), math.ceil(i / 4))
457
458 def test_neg(self):
459 for i in range(-8, 8):
460 value = Fixed.from_bits(i, 2, 4, True)
461 expected = -i / 4 if i != -8 else -2.0 # handle wrap-around
462 with self.subTest(value=repr(value)):
463 self.assertEqual(float(-value), expected)
464
465 def test_pos(self):
466 for i in range(-8, 8):
467 value = Fixed.from_bits(i, 2, 4, True)
468 with self.subTest(value=repr(value)):
469 value = +value
470 self.assertEqual(value.bits, i)
471
472 def test_abs(self):
473 for i in range(-8, 8):
474 value = Fixed.from_bits(i, 2, 4, True)
475 expected = abs(i) / 4 if i != -8 else -2.0 # handle wrap-around
476 with self.subTest(value=repr(value)):
477 self.assertEqual(float(abs(value)), expected)
478
479 def test_not(self):
480 for i in range(-8, 8):
481 value = Fixed.from_bits(i, 2, 4, True)
482 with self.subTest(value=repr(value)):
483 self.assertEqual(float(~value), (~i) / 4)
484
485 @staticmethod
486 def get_test_values(max_bit_width, include_int):
487 for signed in False, True:
488 if include_int:
489 for bits in range(1 << max_bit_width):
490 int_value = Const.normalize(bits, (max_bit_width, signed))
491 yield int_value
492 for bit_width in range(1, max_bit_width):
493 for fract_width in range(bit_width + 1):
494 for bits in range(1 << bit_width):
495 yield Fixed.from_bits(bits,
496 fract_width,
497 bit_width,
498 signed)
499
500 def binary_op_test_helper(self,
501 operation,
502 is_fixed=True,
503 width_combine_op=max,
504 adjust_bits_op=None):
505 def default_adjust_bits_op(bits, out_fract_width, in_fract_width):
506 return bits << (out_fract_width - in_fract_width)
507 if adjust_bits_op is None:
508 adjust_bits_op = default_adjust_bits_op
509 max_bit_width = 5
510 for lhs in self.get_test_values(max_bit_width, True):
511 lhs_is_int = isinstance(lhs, int)
512 for rhs in self.get_test_values(max_bit_width, not lhs_is_int):
513 rhs_is_int = isinstance(rhs, int)
514 if lhs_is_int:
515 assert not rhs_is_int
516 lhs_int = adjust_bits_op(lhs, rhs.fract_width, 0)
517 int_result = operation(lhs_int, rhs.bits)
518 if is_fixed:
519 expected = Fixed.from_bits(int_result,
520 rhs.fract_width,
521 rhs.bit_width,
522 rhs.signed)
523 else:
524 expected = int_result
525 elif rhs_is_int:
526 rhs_int = adjust_bits_op(rhs, lhs.fract_width, 0)
527 int_result = operation(lhs.bits, rhs_int)
528 if is_fixed:
529 expected = Fixed.from_bits(int_result,
530 lhs.fract_width,
531 lhs.bit_width,
532 lhs.signed)
533 else:
534 expected = int_result
535 elif lhs.signed != rhs.signed:
536 continue
537 else:
538 fract_width = width_combine_op(lhs.fract_width,
539 rhs.fract_width)
540 int_width = width_combine_op(lhs.bit_width
541 - lhs.fract_width,
542 rhs.bit_width
543 - rhs.fract_width)
544 bit_width = fract_width + int_width
545 lhs_int = adjust_bits_op(lhs.bits,
546 fract_width,
547 lhs.fract_width)
548 rhs_int = adjust_bits_op(rhs.bits,
549 fract_width,
550 rhs.fract_width)
551 int_result = operation(lhs_int, rhs_int)
552 if is_fixed:
553 expected = Fixed.from_bits(int_result,
554 fract_width,
555 bit_width,
556 lhs.signed)
557 else:
558 expected = int_result
559 with self.subTest(lhs=repr(lhs),
560 rhs=repr(rhs),
561 expected=repr(expected)):
562 result = operation(lhs, rhs)
563 if is_fixed:
564 self.assertEqual(result.bit_width, expected.bit_width)
565 self.assertEqual(result.signed, expected.signed)
566 self.assertEqual(result.fract_width,
567 expected.fract_width)
568 self.assertEqual(result.bits, expected.bits)
569 else:
570 self.assertEqual(result, expected)
571
572 def test_add(self):
573 self.binary_op_test_helper(lambda lhs, rhs: lhs + rhs)
574
575 def test_sub(self):
576 self.binary_op_test_helper(lambda lhs, rhs: lhs - rhs)
577
578 def test_and(self):
579 self.binary_op_test_helper(lambda lhs, rhs: lhs & rhs)
580
581 def test_or(self):
582 self.binary_op_test_helper(lambda lhs, rhs: lhs | rhs)
583
584 def test_xor(self):
585 self.binary_op_test_helper(lambda lhs, rhs: lhs ^ rhs)
586
587 def test_mul(self):
588 def adjust_bits_op(bits, out_fract_width, in_fract_width):
589 return bits
590 self.binary_op_test_helper(lambda lhs, rhs: lhs * rhs,
591 True,
592 lambda l_width, r_width: l_width + r_width,
593 adjust_bits_op)
594
595 def test_cmp(self):
596 def cmp(lhs, rhs):
597 if lhs < rhs:
598 return -1
599 elif lhs > rhs:
600 return 1
601 return 0
602 self.binary_op_test_helper(cmp, False)
603
604 def test_lt(self):
605 self.binary_op_test_helper(lambda lhs, rhs: lhs < rhs, False)
606
607 def test_le(self):
608 self.binary_op_test_helper(lambda lhs, rhs: lhs <= rhs, False)
609
610 def test_eq(self):
611 self.binary_op_test_helper(lambda lhs, rhs: lhs == rhs, False)
612
613 def test_ne(self):
614 self.binary_op_test_helper(lambda lhs, rhs: lhs != rhs, False)
615
616 def test_gt(self):
617 self.binary_op_test_helper(lambda lhs, rhs: lhs > rhs, False)
618
619 def test_ge(self):
620 self.binary_op_test_helper(lambda lhs, rhs: lhs >= rhs, False)
621
622 def test_bool(self):
623 for v in self.get_test_values(6, False):
624 with self.subTest(v=repr(v)):
625 self.assertEqual(bool(v), bool(v.bits))
626
627 def test_str(self):
628 self.assertEqual(str(Fixed.from_bits(0x1234, 0, 16, False)),
629 "fixed:0x1234.")
630 self.assertEqual(str(Fixed.from_bits(-0x1234, 0, 16, True)),
631 "fixed:-0x1234.")
632 self.assertEqual(str(Fixed.from_bits(0x12345, 3, 20, True)),
633 "fixed:0x2468.a")
634 self.assertEqual(str(Fixed(123.625, 3, 12, True)),
635 "fixed:0x7b.a")
636
637 self.assertEqual(str(Fixed.from_bits(0x1, 0, 20, True)),
638 "fixed:0x1.")
639 self.assertEqual(str(Fixed.from_bits(0x2, 1, 20, True)),
640 "fixed:0x1.0")
641 self.assertEqual(str(Fixed.from_bits(0x4, 2, 20, True)),
642 "fixed:0x1.0")
643 self.assertEqual(str(Fixed.from_bits(0x9, 3, 20, True)),
644 "fixed:0x1.2")
645 self.assertEqual(str(Fixed.from_bits(0x12, 4, 20, True)),
646 "fixed:0x1.2")
647 self.assertEqual(str(Fixed.from_bits(0x24, 5, 20, True)),
648 "fixed:0x1.20")
649 self.assertEqual(str(Fixed.from_bits(0x48, 6, 20, True)),
650 "fixed:0x1.20")
651 self.assertEqual(str(Fixed.from_bits(0x91, 7, 20, True)),
652 "fixed:0x1.22")
653 self.assertEqual(str(Fixed.from_bits(0x123, 8, 20, True)),
654 "fixed:0x1.23")
655 self.assertEqual(str(Fixed.from_bits(0x246, 9, 20, True)),
656 "fixed:0x1.230")
657 self.assertEqual(str(Fixed.from_bits(0x48d, 10, 20, True)),
658 "fixed:0x1.234")
659 self.assertEqual(str(Fixed.from_bits(0x91a, 11, 20, True)),
660 "fixed:0x1.234")
661 self.assertEqual(str(Fixed.from_bits(0x1234, 12, 20, True)),
662 "fixed:0x1.234")
663 self.assertEqual(str(Fixed.from_bits(0x2468, 13, 20, True)),
664 "fixed:0x1.2340")
665 self.assertEqual(str(Fixed.from_bits(0x48d1, 14, 20, True)),
666 "fixed:0x1.2344")
667 self.assertEqual(str(Fixed.from_bits(0x91a2, 15, 20, True)),
668 "fixed:0x1.2344")
669 self.assertEqual(str(Fixed.from_bits(0x12345, 16, 20, True)),
670 "fixed:0x1.2345")
671 self.assertEqual(str(Fixed.from_bits(0x2468a, 17, 20, True)),
672 "fixed:0x1.23450")
673 self.assertEqual(str(Fixed.from_bits(0x48d14, 18, 20, True)),
674 "fixed:0x1.23450")
675 self.assertEqual(str(Fixed.from_bits(0x91a28, 19, 20, True)),
676 "fixed:-0x0.dcbb0")
677 self.assertEqual(str(Fixed.from_bits(0x91a28, 19, 20, False)),
678 "fixed:0x1.23450")
679
680
681 # FIXME: add tests for fract_sqrt, FractSqrt, fract_rsqrt, and FractRSqrt