1 from libc.stdint cimport *
5 # low-level access to rounding modes
7 ROUND_NEAREST_EVEN = cfloat.softfloat_round_near_even
8 ROUND_TO_ZERO = cfloat.softfloat_round_minMag
9 ROUND_DOWN = cfloat.softfloat_round_min
10 ROUND_UP = cfloat.softfloat_round_max
11 ROUND_NEAREST_AWAY = cfloat.softfloat_round_near_maxMag
13 cpdef uint_fast8_t round_get_mode():
14 return cfloat.softfloat_roundingMode
16 cpdef void round_set_mode(uint_fast8_t mode):
17 cfloat.softfloat_roundingMode = mode
19 cpdef bint round_is_nearest_even():
20 return cfloat.softfloat_roundingMode == cfloat.softfloat_round_near_even
22 cpdef void round_set_nearest_even():
23 cfloat.softfloat_roundingMode = cfloat.softfloat_round_near_even
25 cpdef bint round_is_to_zero():
26 return cfloat.softfloat_roundingMode == cfloat.softfloat_round_minMag
28 cpdef void round_set_to_zero():
29 cfloat.softfloat_roundingMode = cfloat.softfloat_round_minMag
31 cpdef bint round_is_down():
32 return cfloat.softfloat_roundingMode == cfloat.softfloat_round_min
34 cpdef void round_set_down():
35 cfloat.softfloat_roundingMode = cfloat.softfloat_round_min
37 cpdef bint round_is_up():
38 return cfloat.softfloat_roundingMode == cfloat.softfloat_round_max
40 cpdef void round_set_up():
41 cfloat.softfloat_roundingMode = cfloat.softfloat_round_max
43 cpdef bint round_is_nearest_away():
44 return cfloat.softfloat_roundingMode == cfloat.softfloat_round_near_maxMag
46 cpdef void round_set_nearest_away():
47 cfloat.softfloat_roundingMode = cfloat.softfloat_round_near_maxMag
50 # low-level access to exception flags
52 FLAG_INEXACT = cfloat.softfloat_flag_inexact
53 FLAG_UNDERFLOW = cfloat.softfloat_flag_underflow
54 FLAG_OVERFLOW = cfloat.softfloat_flag_overflow
55 FLAG_INFINITE = cfloat.softfloat_flag_infinite
56 FLAG_INVALID = cfloat.softfloat_flag_invalid
58 cpdef uint_fast8_t flag_get():
59 return cfloat.softfloat_exceptionFlags
61 cpdef void flag_set(uint_fast8_t flags):
62 cfloat.softfloat_exceptionFlags = flags
64 cpdef void flag_reset():
65 cfloat.softfloat_exceptionFlags = 0
67 cpdef bint flag_get_inexact():
68 return (cfloat.softfloat_exceptionFlags & cfloat.softfloat_flag_inexact) != 0
70 cpdef void flag_raise_inexact():
71 cfloat.softfloat_raiseFlags(cfloat.softfloat_flag_inexact)
73 cpdef void flag_clear_inexact():
74 cfloat.softfloat_exceptionFlags &= ~cfloat.softfloat_flag_inexact
76 cpdef bint flag_get_underflow():
77 return (cfloat.softfloat_exceptionFlags & cfloat.softfloat_flag_underflow) != 0
79 cpdef void flag_raise_underflow():
80 cfloat.softfloat_raiseFlags(cfloat.softfloat_flag_underflow)
82 cpdef void flag_clear_underflow():
83 cfloat.softfloat_exceptionFlags &= ~cfloat.softfloat_flag_underflow
85 cpdef bint flag_get_overflow():
86 return (cfloat.softfloat_exceptionFlags & cfloat.softfloat_flag_overflow) != 0
88 cpdef void flag_raise_overflow():
89 cfloat.softfloat_raiseFlags(cfloat.softfloat_flag_overflow)
91 cpdef void flag_clear_overflow():
92 cfloat.softfloat_exceptionFlags &= ~cfloat.softfloat_flag_overflow
94 cpdef bint flag_get_infinite():
95 return (cfloat.softfloat_exceptionFlags & cfloat.softfloat_flag_infinite) != 0
97 cpdef void flag_raise_infinite():
98 cfloat.softfloat_raiseFlags(cfloat.softfloat_flag_infinite)
100 cpdef void flag_clear_infinite():
101 cfloat.softfloat_exceptionFlags &= ~cfloat.softfloat_flag_infinite
103 cpdef bint flag_get_invalid():
104 return (cfloat.softfloat_exceptionFlags & cfloat.softfloat_flag_invalid) != 0
106 cpdef void flag_raise_invalid():
107 cfloat.softfloat_raiseFlags(cfloat.softfloat_flag_invalid)
109 cpdef void flag_clear_invalid():
110 cfloat.softfloat_exceptionFlags &= ~cfloat.softfloat_flag_invalid
115 cdef inline cfloat.float16_t _f16_neg(cfloat.float16_t f):
119 cdef inline cfloat.float32_t _f32_neg(cfloat.float32_t f):
123 cdef inline cfloat.float64_t _f64_neg(cfloat.float64_t f):
124 f.v ^= 0x8000000000000000
127 cdef inline cfloat.float16_t _f16_abs(cfloat.float16_t f):
131 cdef inline cfloat.float32_t _f32_abs(cfloat.float32_t f):
135 cdef inline cfloat.float64_t _f64_abs(cfloat.float64_t f):
136 f.v &= 0x7fffffffffffffff
142 # the wrapped float value
143 cdef cfloat.float16_t _c_float
145 # factory function constructors that bypass __init__
148 cdef Float16 from_c_float(cfloat.float16_t f):
149 """Factory function to create a Float16 object directly from
152 cdef Float16 obj = Float16.__new__(Float16)
157 def from_bits(uint16_t value):
158 """Factory function to create a Float16 object from a bit pattern
159 represented as an integer.
161 cdef Float16 obj = Float16.__new__(Float16)
162 obj._c_float.v = value
166 def from_double(double value):
167 """Factory function to create a Float16 object from a double.
169 cdef Float16 obj = Float16.__new__(Float16)
170 cdef cfloat.ui64_double ud
171 cdef cfloat.float64_t d
175 obj._c_float = cfloat.f64_to_f16(d)
179 # convenience interface for use inside Python
181 def __init__(self, value):
182 cdef cfloat.ui64_double ud
183 cdef cfloat.float64_t d
185 if isinstance(value, int):
186 self._c_float.v = value
190 self._c_float = cfloat.f64_to_f16(d)
193 cdef cfloat.ui64_double ud
194 ud.u = cfloat.f16_to_f64(self._c_float).v
198 cdef cfloat.ui64_double ud
199 ud.u = cfloat.f16_to_f64(self._c_float).v
203 cdef cfloat.ui64_double ud
204 ud.u = cfloat.f16_to_f64(self._c_float).v
208 cdef cfloat.ui64_double ud
209 ud.u = cfloat.f16_to_f64(self._c_float).v
210 return 'Float16(' + repr(ud.d) + ')'
212 cpdef uint16_t get_bits(self):
213 return self._c_float.v
214 bits = property(get_bits)
218 cpdef Float16 neg(self):
219 cdef cfloat.float16_t f = _f16_neg(self._c_float)
220 return Float16.from_c_float(f)
225 cpdef Float16 abs(self):
226 cdef cfloat.float16_t f = _f16_abs(self._c_float)
227 return Float16.from_c_float(f)
232 cpdef Float16 round_to(self, uint_fast8_t rm, bint exact):
233 cdef cfloat.float16_t f = cfloat.f16_roundToInt(self._c_float, rm, exact)
234 return Float16.from_c_float(f)
236 cpdef Float16 round(self):
237 cdef cfloat.float16_t f = cfloat.f16_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
238 return Float16.from_c_float(f)
243 cpdef Float16 add(self, Float16 other):
244 cdef cfloat.float16_t f = cfloat.f16_add(self._c_float, other._c_float)
245 return Float16.from_c_float(f)
247 def __add__(self, Float16 other):
248 return self.add(other)
250 cpdef Float16 sub(self, Float16 other):
251 cdef cfloat.float16_t f = cfloat.f16_sub(self._c_float, other._c_float)
252 return Float16.from_c_float(f)
254 def __sub__(self, Float16 other):
255 return self.sub(other)
257 cpdef Float16 mul(self, Float16 other):
258 cdef cfloat.float16_t f = cfloat.f16_mul(self._c_float, other._c_float)
259 return Float16.from_c_float(f)
261 def __mul__(self, Float16 other):
262 return self.mul(other)
264 cpdef Float16 fma(self, Float16 a1, Float16 a2):
265 cdef cfloat.float16_t f = cfloat.f16_mulAdd(a1._c_float, a2._c_float, self._c_float)
266 return Float16.from_c_float(f)
268 cpdef Float16 div(self, Float16 other):
269 cdef cfloat.float16_t f = cfloat.f16_div(self._c_float, other._c_float)
270 return Float16.from_c_float(f)
272 def __truediv__(self, Float16 other):
273 return self.div(other)
275 cpdef Float16 rem(self, Float16 other):
276 cdef cfloat.float16_t f = cfloat.f16_rem(self._c_float, other._c_float)
277 return Float16.from_c_float(f)
279 cpdef Float16 sqrt(self):
280 cdef cfloat.float16_t f = cfloat.f16_sqrt(self._c_float)
281 return Float16.from_c_float(f)
283 # in-place arithmetic
285 cpdef void ineg(self):
286 self._c_float = _f16_neg(self._c_float)
288 cpdef void iabs(self):
289 self._c_float = _f16_abs(self._c_float)
291 cpdef void iround_to(self, uint_fast8_t rm, bint exact):
292 self._c_float = cfloat.f16_roundToInt(self._c_float, rm, exact)
294 cpdef void iround(self):
295 self._c_float = cfloat.f16_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
297 cpdef void iadd(self, Float16 other):
298 self._c_float = cfloat.f16_add(self._c_float, other._c_float)
300 def __iadd__(self, Float16 other):
304 cpdef void isub(self, Float16 other):
305 self._c_float = cfloat.f16_sub(self._c_float, other._c_float)
307 def __isub__(self, Float16 other):
311 cpdef void imul(self, Float16 other):
312 self._c_float = cfloat.f16_mul(self._c_float, other._c_float)
314 def __imul__(self, Float16 other):
318 cpdef void ifma(self, Float16 a1, Float16 a2):
319 self._c_float = cfloat.f16_mulAdd(a1._c_float, a2._c_float, self._c_float)
321 cpdef void idiv(self, Float16 other):
322 self._c_float = cfloat.f16_div(self._c_float, other._c_float)
324 def __itruediv__(self, Float16 other):
328 cpdef void irem(self, Float16 other):
329 self._c_float = cfloat.f16_rem(self._c_float, other._c_float)
331 cpdef void isqrt(self):
332 self._c_float = cfloat.f16_sqrt(self._c_float)
336 cpdef bint eq(self, Float16 other):
337 return cfloat.f16_eq(self._c_float, other._c_float)
339 cpdef bint le(self, Float16 other):
340 return cfloat.f16_le(self._c_float, other._c_float)
342 cpdef bint lt(self, Float16 other):
343 return cfloat.f16_lt(self._c_float, other._c_float)
345 def __lt__(self, Float16 other):
346 return self.lt(other)
348 def __le__(self, Float16 other):
349 return self.le(other)
351 def __eq__(self, Float16 other):
352 return self.eq(other)
354 def __ne__(self, Float16 other):
355 return not self.eq(other)
357 def __ge__(self, Float16 other):
358 return other.le(self)
360 def __gt__(self, Float16 other):
361 return other.lt(self)
363 # conversion to other float types
365 cpdef Float32 to_f32(self):
366 cdef cfloat.float32_t f = cfloat.f16_to_f32(self._c_float)
367 return Float32.from_c_float(f)
369 cpdef Float64 to_f64(self):
370 cdef cfloat.float64_t f = cfloat.f16_to_f64(self._c_float)
371 return Float64.from_c_float(f)
374 # external, non-method arithmetic
376 cpdef Float16 f16_neg(Float16 a1):
377 cdef cfloat.float16_t f = _f16_neg(a1._c_float)
378 return Float16.from_c_float(f)
380 cpdef Float16 f16_abs(Float16 a1):
381 cdef cfloat.float16_t f = _f16_abs(a1._c_float)
382 return Float16.from_c_float(f)
384 cpdef Float16 f16_round_to(Float16 a1, uint_fast8_t rm, bint exact):
385 cdef cfloat.float16_t f = cfloat.f16_roundToInt(a1._c_float, rm, exact)
386 return Float16.from_c_float(f)
388 cpdef Float16 f16_round(Float16 a1):
389 cdef cfloat.float16_t f = cfloat.f16_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
390 return Float16.from_c_float(f)
392 cpdef Float16 f16_add(Float16 a1, Float16 a2):
393 cdef cfloat.float16_t f = cfloat.f16_add(a1._c_float, a2._c_float)
394 return Float16.from_c_float(f)
396 cpdef Float16 f16_sub(Float16 a1, Float16 a2):
397 cdef cfloat.float16_t f = cfloat.f16_sub(a1._c_float, a2._c_float)
398 return Float16.from_c_float(f)
400 cpdef Float16 f16_mul(Float16 a1, Float16 a2):
401 cdef cfloat.float16_t f = cfloat.f16_mul(a1._c_float, a2._c_float)
402 return Float16.from_c_float(f)
404 cpdef Float16 f16_fma(Float16 acc, Float16 a1, Float16 a2):
405 cdef cfloat.float16_t f = cfloat.f16_mulAdd(a1._c_float, a2._c_float, acc._c_float)
406 return Float16.from_c_float(f)
408 cpdef Float16 f16_div(Float16 a1, Float16 a2):
409 cdef cfloat.float16_t f = cfloat.f16_div(a1._c_float, a2._c_float)
410 return Float16.from_c_float(f)
412 cpdef Float16 f16_rem(Float16 a1, Float16 a2):
413 cdef cfloat.float16_t f = cfloat.f16_rem(a1._c_float, a2._c_float)
414 return Float16.from_c_float(f)
416 cpdef Float16 f16_sqrt(Float16 a1):
417 cdef cfloat.float16_t f = cfloat.f16_sqrt(a1._c_float)
418 return Float16.from_c_float(f)
420 cpdef bint f16_eq(Float16 a1, Float16 a2):
421 return cfloat.f16_eq(a1._c_float, a2._c_float)
423 cpdef bint f16_le(Float16 a1, Float16 a2):
424 return cfloat.f16_le(a1._c_float, a2._c_float)
426 cpdef bint f16_lt(Float16 a1, Float16 a2):
427 return cfloat.f16_lt(a1._c_float, a2._c_float)
429 cpdef Float32 f16_to_f32(Float16 a1):
430 cdef cfloat.float32_t f = cfloat.f16_to_f32(a1._c_float)
431 return Float32.from_c_float(f)
433 cpdef Float64 f16_to_f64(Float16 a1):
434 cdef cfloat.float64_t f = cfloat.f16_to_f64(a1._c_float)
435 return Float64.from_c_float(f)
440 # the wrapped float value
441 cdef cfloat.float32_t _c_float
443 # factory function constructors that bypass __init__
446 cdef Float32 from_c_float(cfloat.float32_t f):
447 """Factory function to create a Float32 object directly from
450 cdef Float32 obj = Float32.__new__(Float32)
455 def from_bits(uint32_t value):
456 """Factory function to create a Float32 object from a bit pattern
457 represented as an integer.
459 cdef Float32 obj = Float32.__new__(Float32)
460 obj._c_float.v = value
464 def from_double(double value):
465 """Factory function to create a Float32 object from a double.
467 cdef Float32 obj = Float32.__new__(Float32)
468 cdef cfloat.ui64_double ud
469 cdef cfloat.float64_t d
473 obj._c_float = cfloat.f64_to_f32(d)
477 # convenience interface for use inside Python
479 def __init__(self, value):
480 cdef cfloat.ui64_double ud
481 cdef cfloat.float64_t d
483 if isinstance(value, int):
484 self._c_float.v = value
488 self._c_float = cfloat.f64_to_f32(d)
491 cdef cfloat.ui64_double ud
492 ud.u = cfloat.f32_to_f64(self._c_float).v
496 cdef cfloat.ui64_double ud
497 ud.u = cfloat.f32_to_f64(self._c_float).v
501 cdef cfloat.ui64_double ud
502 ud.u = cfloat.f32_to_f64(self._c_float).v
506 cdef cfloat.ui64_double ud
507 ud.u = cfloat.f32_to_f64(self._c_float).v
508 return 'Float32(' + repr(ud.d) + ')'
510 cpdef uint32_t get_bits(self):
511 return self._c_float.v
512 bits = property(get_bits)
516 cpdef Float32 neg(self):
517 cdef cfloat.float32_t f = _f32_neg(self._c_float)
518 return Float32.from_c_float(f)
523 cpdef Float32 abs(self):
524 cdef cfloat.float32_t f = _f32_abs(self._c_float)
525 return Float32.from_c_float(f)
530 cpdef Float32 round_to(self, uint_fast8_t rm, bint exact):
531 cdef cfloat.float32_t f = cfloat.f32_roundToInt(self._c_float, rm, exact)
532 return Float32.from_c_float(f)
534 cpdef Float32 round(self):
535 cdef cfloat.float32_t f = cfloat.f32_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
536 return Float32.from_c_float(f)
541 cpdef Float32 add(self, Float32 other):
542 cdef cfloat.float32_t f = cfloat.f32_add(self._c_float, other._c_float)
543 return Float32.from_c_float(f)
545 def __add__(self, Float32 other):
546 return self.add(other)
548 cpdef Float32 sub(self, Float32 other):
549 cdef cfloat.float32_t f = cfloat.f32_sub(self._c_float, other._c_float)
550 return Float32.from_c_float(f)
552 def __sub__(self, Float32 other):
553 return self.sub(other)
555 cpdef Float32 mul(self, Float32 other):
556 cdef cfloat.float32_t f = cfloat.f32_mul(self._c_float, other._c_float)
557 return Float32.from_c_float(f)
559 def __mul__(self, Float32 other):
560 return self.mul(other)
562 cpdef Float32 fma(self, Float32 a1, Float32 a2):
563 cdef cfloat.float32_t f = cfloat.f32_mulAdd(a1._c_float, a2._c_float, self._c_float)
564 return Float32.from_c_float(f)
566 cpdef Float32 div(self, Float32 other):
567 cdef cfloat.float32_t f = cfloat.f32_div(self._c_float, other._c_float)
568 return Float32.from_c_float(f)
570 def __truediv__(self, Float32 other):
571 return self.div(other)
573 cpdef Float32 rem(self, Float32 other):
574 cdef cfloat.float32_t f = cfloat.f32_rem(self._c_float, other._c_float)
575 return Float32.from_c_float(f)
577 cpdef Float32 sqrt(self):
578 cdef cfloat.float32_t f = cfloat.f32_sqrt(self._c_float)
579 return Float32.from_c_float(f)
581 # in-place arithmetic
583 cpdef void ineg(self):
584 self._c_float = _f32_neg(self._c_float)
586 cpdef void iabs(self):
587 self._c_float = _f32_abs(self._c_float)
589 cpdef void iround_to(self, uint_fast8_t rm, bint exact):
590 self._c_float = cfloat.f32_roundToInt(self._c_float, rm, exact)
592 cpdef void iround(self):
593 self._c_float = cfloat.f32_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
595 cpdef void iadd(self, Float32 other):
596 self._c_float = cfloat.f32_add(self._c_float, other._c_float)
598 def __iadd__(self, Float32 other):
602 cpdef void isub(self, Float32 other):
603 self._c_float = cfloat.f32_sub(self._c_float, other._c_float)
605 def __isub__(self, Float32 other):
609 cpdef void imul(self, Float32 other):
610 self._c_float = cfloat.f32_mul(self._c_float, other._c_float)
612 def __imul__(self, Float32 other):
616 cpdef void ifma(self, Float32 a1, Float32 a2):
617 self._c_float = cfloat.f32_mulAdd(a1._c_float, a2._c_float, self._c_float)
619 cpdef void idiv(self, Float32 other):
620 self._c_float = cfloat.f32_div(self._c_float, other._c_float)
622 def __itruediv__(self, Float32 other):
626 cpdef void irem(self, Float32 other):
627 self._c_float = cfloat.f32_rem(self._c_float, other._c_float)
629 cpdef void isqrt(self):
630 self._c_float = cfloat.f32_sqrt(self._c_float)
634 cpdef bint eq(self, Float32 other):
635 return cfloat.f32_eq(self._c_float, other._c_float)
637 cpdef bint le(self, Float32 other):
638 return cfloat.f32_le(self._c_float, other._c_float)
640 cpdef bint lt(self, Float32 other):
641 return cfloat.f32_lt(self._c_float, other._c_float)
643 def __lt__(self, Float32 other):
644 return self.lt(other)
646 def __le__(self, Float32 other):
647 return self.le(other)
649 def __eq__(self, Float32 other):
650 return self.eq(other)
652 def __ne__(self, Float32 other):
653 return not self.eq(other)
655 def __ge__(self, Float32 other):
656 return other.le(self)
658 def __gt__(self, Float32 other):
659 return other.lt(self)
661 # conversion to other float types
663 cpdef Float16 to_f16(self):
664 cdef cfloat.float16_t f = cfloat.f32_to_f16(self._c_float)
665 return Float16.from_c_float(f)
667 cpdef Float64 to_f64(self):
668 cdef cfloat.float64_t f = cfloat.f32_to_f64(self._c_float)
669 return Float64.from_c_float(f)
672 # external, non-method arithmetic
674 cpdef Float32 f32_neg(Float32 a1):
675 cdef cfloat.float32_t f = _f32_neg(a1._c_float)
676 return Float32.from_c_float(f)
678 cpdef Float32 f32_abs(Float32 a1):
679 cdef cfloat.float32_t f = _f32_abs(a1._c_float)
680 return Float32.from_c_float(f)
682 cpdef Float32 f32_round_to(Float32 a1, uint_fast8_t rm, bint exact):
683 cdef cfloat.float32_t f = cfloat.f32_roundToInt(a1._c_float, rm, exact)
684 return Float32.from_c_float(f)
686 cpdef Float32 f32_round(Float32 a1):
687 cdef cfloat.float32_t f = cfloat.f32_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
688 return Float32.from_c_float(f)
690 cpdef Float32 f32_add(Float32 a1, Float32 a2):
691 cdef cfloat.float32_t f = cfloat.f32_add(a1._c_float, a2._c_float)
692 return Float32.from_c_float(f)
694 cpdef Float32 f32_sub(Float32 a1, Float32 a2):
695 cdef cfloat.float32_t f = cfloat.f32_sub(a1._c_float, a2._c_float)
696 return Float32.from_c_float(f)
698 cpdef Float32 f32_mul(Float32 a1, Float32 a2):
699 cdef cfloat.float32_t f = cfloat.f32_mul(a1._c_float, a2._c_float)
700 return Float32.from_c_float(f)
702 cpdef Float32 f32_fma(Float32 acc, Float32 a1, Float32 a2):
703 cdef cfloat.float32_t f = cfloat.f32_mulAdd(a1._c_float, a2._c_float, acc._c_float)
704 return Float32.from_c_float(f)
706 cpdef Float32 f32_div(Float32 a1, Float32 a2):
707 cdef cfloat.float32_t f = cfloat.f32_div(a1._c_float, a2._c_float)
708 return Float32.from_c_float(f)
710 cpdef Float32 f32_rem(Float32 a1, Float32 a2):
711 cdef cfloat.float32_t f = cfloat.f32_rem(a1._c_float, a2._c_float)
712 return Float32.from_c_float(f)
714 cpdef Float32 f32_sqrt(Float32 a1):
715 cdef cfloat.float32_t f = cfloat.f32_sqrt(a1._c_float)
716 return Float32.from_c_float(f)
718 cpdef bint f32_eq(Float32 a1, Float32 a2):
719 return cfloat.f32_eq(a1._c_float, a2._c_float)
721 cpdef bint f32_le(Float32 a1, Float32 a2):
722 return cfloat.f32_le(a1._c_float, a2._c_float)
724 cpdef bint f32_lt(Float32 a1, Float32 a2):
725 return cfloat.f32_lt(a1._c_float, a2._c_float)
727 cpdef Float16 f32_to_f16(Float32 a1):
728 cdef cfloat.float16_t f = cfloat.f32_to_f16(a1._c_float)
729 return Float16.from_c_float(f)
731 cpdef Float64 f32_to_f64(Float32 a1):
732 cdef cfloat.float64_t f = cfloat.f32_to_f64(a1._c_float)
733 return Float64.from_c_float(f)
738 # the wrapped float value
739 cdef cfloat.float64_t _c_float
741 # factory function constructors that bypass __init__
744 cdef Float64 from_c_float(cfloat.float64_t f):
745 """Factory function to create a Float64 object directly from
748 cdef Float64 obj = Float64.__new__(Float64)
753 def from_bits(uint64_t value):
754 """Factory function to create a Float64 object from a bit pattern
755 represented as an integer.
757 cdef Float64 obj = Float64.__new__(Float64)
758 obj._c_float.v = value
762 def from_double(double value):
763 """Factory function to create a Float64 object from a double.
765 cdef Float64 obj = Float64.__new__(Float64)
766 cdef cfloat.ui64_double ud
767 cdef cfloat.float64_t d
770 obj._c_float.v = ud.u
774 # convenience interface for use inside Python
776 def __init__(self, value):
777 cdef cfloat.ui64_double ud
778 cdef cfloat.float64_t d
780 if isinstance(value, int):
781 self._c_float.v = value
784 self._c_float.v = ud.u
787 cdef cfloat.ui64_double ud
788 ud.u = self._c_float.v
792 cdef cfloat.ui64_double ud
793 ud.u = self._c_float.v
797 cdef cfloat.ui64_double ud
798 ud.u = self._c_float.v
802 cdef cfloat.ui64_double ud
803 ud.u = self._c_float.v
804 return 'Float64(' + repr(ud.d) + ')'
806 cpdef uint64_t get_bits(self):
807 return self._c_float.v
808 bits = property(get_bits)
812 cpdef Float64 neg(self):
813 cdef cfloat.float64_t f = _f64_neg(self._c_float)
814 return Float64.from_c_float(f)
819 cpdef Float64 abs(self):
820 cdef cfloat.float64_t f = _f64_abs(self._c_float)
821 return Float64.from_c_float(f)
826 cpdef Float64 round_to(self, uint_fast8_t rm, bint exact):
827 cdef cfloat.float64_t f = cfloat.f64_roundToInt(self._c_float, rm, exact)
828 return Float64.from_c_float(f)
830 cpdef Float64 round(self):
831 cdef cfloat.float64_t f = cfloat.f64_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
832 return Float64.from_c_float(f)
837 cpdef Float64 add(self, Float64 other):
838 cdef cfloat.float64_t f = cfloat.f64_add(self._c_float, other._c_float)
839 return Float64.from_c_float(f)
841 def __add__(self, Float64 other):
842 return self.add(other)
844 cpdef Float64 sub(self, Float64 other):
845 cdef cfloat.float64_t f = cfloat.f64_sub(self._c_float, other._c_float)
846 return Float64.from_c_float(f)
848 def __sub__(self, Float64 other):
849 return self.sub(other)
851 cpdef Float64 mul(self, Float64 other):
852 cdef cfloat.float64_t f = cfloat.f64_mul(self._c_float, other._c_float)
853 return Float64.from_c_float(f)
855 def __mul__(self, Float64 other):
856 return self.mul(other)
858 cpdef Float64 fma(self, Float64 a1, Float64 a2):
859 cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, self._c_float)
860 return Float64.from_c_float(f)
862 cpdef Float64 div(self, Float64 other):
863 cdef cfloat.float64_t f = cfloat.f64_div(self._c_float, other._c_float)
864 return Float64.from_c_float(f)
866 def __truediv__(self, Float64 other):
867 return self.div(other)
869 cpdef Float64 rem(self, Float64 other):
870 cdef cfloat.float64_t f = cfloat.f64_rem(self._c_float, other._c_float)
871 return Float64.from_c_float(f)
873 cpdef Float64 sqrt(self):
874 cdef cfloat.float64_t f = cfloat.f64_sqrt(self._c_float)
875 return Float64.from_c_float(f)
877 # in-place arithmetic
879 cpdef void ineg(self):
880 self._c_float = _f64_neg(self._c_float)
882 cpdef void iabs(self):
883 self._c_float = _f64_abs(self._c_float)
885 cpdef void iround_to(self, uint_fast8_t rm, bint exact):
886 self._c_float = cfloat.f64_roundToInt(self._c_float, rm, exact)
888 cpdef void iround(self):
889 self._c_float = cfloat.f64_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
891 cpdef void iadd(self, Float64 other):
892 self._c_float = cfloat.f64_add(self._c_float, other._c_float)
894 def __iadd__(self, Float64 other):
898 cpdef void isub(self, Float64 other):
899 self._c_float = cfloat.f64_sub(self._c_float, other._c_float)
901 def __isub__(self, Float64 other):
905 cpdef void imul(self, Float64 other):
906 self._c_float = cfloat.f64_mul(self._c_float, other._c_float)
908 def __imul__(self, Float64 other):
912 cpdef void ifma(self, Float64 a1, Float64 a2):
913 self._c_float = cfloat.f64_mulAdd(a1._c_float, a2._c_float, self._c_float)
915 cpdef void idiv(self, Float64 other):
916 self._c_float = cfloat.f64_div(self._c_float, other._c_float)
918 def __itruediv__(self, Float64 other):
922 cpdef void irem(self, Float64 other):
923 self._c_float = cfloat.f64_rem(self._c_float, other._c_float)
925 cpdef void isqrt(self):
926 self._c_float = cfloat.f64_sqrt(self._c_float)
930 cpdef bint eq(self, Float64 other):
931 return cfloat.f64_eq(self._c_float, other._c_float)
933 cpdef bint le(self, Float64 other):
934 return cfloat.f64_le(self._c_float, other._c_float)
936 cpdef bint lt(self, Float64 other):
937 return cfloat.f64_lt(self._c_float, other._c_float)
939 def __lt__(self, Float64 other):
940 return self.lt(other)
942 def __le__(self, Float64 other):
943 return self.le(other)
945 def __eq__(self, Float64 other):
946 return self.eq(other)
948 def __ne__(self, Float64 other):
949 return not self.eq(other)
951 def __ge__(self, Float64 other):
952 return other.le(self)
954 def __gt__(self, Float64 other):
955 return other.lt(self)
957 # conversion to other float types
959 cpdef Float16 to_f16(self):
960 cdef cfloat.float16_t f = cfloat.f64_to_f16(self._c_float)
961 return Float16.from_c_float(f)
963 cpdef Float32 to_f32(self):
964 cdef cfloat.float32_t f = cfloat.f64_to_f32(self._c_float)
965 return Float32.from_c_float(f)
968 # external, non-method arithmetic
970 cpdef Float64 f64_neg(Float64 a1):
971 cdef cfloat.float64_t f = _f64_neg(a1._c_float)
972 return Float64.from_c_float(f)
974 cpdef Float64 f64_abs(Float64 a1):
975 cdef cfloat.float64_t f = _f64_abs(a1._c_float)
976 return Float64.from_c_float(f)
978 cpdef Float64 f64_round_to(Float64 a1, uint_fast8_t rm, bint exact):
979 cdef cfloat.float64_t f = cfloat.f64_roundToInt(a1._c_float, rm, exact)
980 return Float64.from_c_float(f)
982 cpdef Float64 f64_round(Float64 a1):
983 cdef cfloat.float64_t f = cfloat.f64_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
984 return Float64.from_c_float(f)
986 cpdef Float64 f64_add(Float64 a1, Float64 a2):
987 cdef cfloat.float64_t f = cfloat.f64_add(a1._c_float, a2._c_float)
988 return Float64.from_c_float(f)
990 cpdef Float64 f64_sub(Float64 a1, Float64 a2):
991 cdef cfloat.float64_t f = cfloat.f64_sub(a1._c_float, a2._c_float)
992 return Float64.from_c_float(f)
994 cpdef Float64 f64_mul(Float64 a1, Float64 a2):
995 cdef cfloat.float64_t f = cfloat.f64_mul(a1._c_float, a2._c_float)
996 return Float64.from_c_float(f)
998 cpdef Float64 f64_fma(Float64 acc, Float64 a1, Float64 a2):
999 cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, acc._c_float)
1000 return Float64.from_c_float(f)
1002 cpdef Float64 f64_div(Float64 a1, Float64 a2):
1003 cdef cfloat.float64_t f = cfloat.f64_div(a1._c_float, a2._c_float)
1004 return Float64.from_c_float(f)
1006 cpdef Float64 f64_rem(Float64 a1, Float64 a2):
1007 cdef cfloat.float64_t f = cfloat.f64_rem(a1._c_float, a2._c_float)
1008 return Float64.from_c_float(f)
1010 cpdef Float64 f64_sqrt(Float64 a1):
1011 cdef cfloat.float64_t f = cfloat.f64_sqrt(a1._c_float)
1012 return Float64.from_c_float(f)
1014 cpdef bint f64_eq(Float64 a1, Float64 a2):
1015 return cfloat.f64_eq(a1._c_float, a2._c_float)
1017 cpdef bint f64_le(Float64 a1, Float64 a2):
1018 return cfloat.f64_le(a1._c_float, a2._c_float)
1020 cpdef bint f64_lt(Float64 a1, Float64 a2):
1021 return cfloat.f64_lt(a1._c_float, a2._c_float)
1023 cpdef Float16 f64_to_f16(Float64 a1):
1024 cdef cfloat.float16_t f = cfloat.f64_to_f16(a1._c_float)
1025 return Float16.from_c_float(f)
1027 cpdef Float32 f64_to_f32(Float64 a1):
1028 cdef cfloat.float32_t f = cfloat.f64_to_f32(a1._c_float)
1029 return Float32.from_c_float(f)