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 """Given an int, create a Float16 from the bitpattern represented by
183 that int. Otherwise, given some value, create a Float16 by rounding
186 cdef cfloat.ui64_double ud
187 cdef cfloat.float64_t d
189 if isinstance(value, int):
190 self._c_float.v = value
194 self._c_float = cfloat.f64_to_f16(d)
197 cdef cfloat.ui64_double ud
198 ud.u = cfloat.f16_to_f64(self._c_float).v
202 cdef cfloat.ui64_double ud
203 ud.u = cfloat.f16_to_f64(self._c_float).v
207 cdef cfloat.ui64_double ud
208 ud.u = cfloat.f16_to_f64(self._c_float).v
212 cdef cfloat.ui64_double ud
213 ud.u = cfloat.f16_to_f64(self._c_float).v
214 return 'Float16(' + repr(ud.d) + ')'
216 cpdef uint16_t get_bits(self):
217 return self._c_float.v
218 bits = property(get_bits)
222 cpdef Float16 neg(self):
223 cdef cfloat.float16_t f = _f16_neg(self._c_float)
224 return Float16.from_c_float(f)
229 cpdef Float16 abs(self):
230 cdef cfloat.float16_t f = _f16_abs(self._c_float)
231 return Float16.from_c_float(f)
236 cpdef Float16 round_to(self, uint_fast8_t rm, bint exact):
237 cdef cfloat.float16_t f = cfloat.f16_roundToInt(self._c_float, rm, exact)
238 return Float16.from_c_float(f)
240 cpdef Float16 round(self):
241 cdef cfloat.float16_t f = cfloat.f16_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
242 return Float16.from_c_float(f)
247 cpdef Float16 add(self, Float16 other):
248 cdef cfloat.float16_t f = cfloat.f16_add(self._c_float, other._c_float)
249 return Float16.from_c_float(f)
251 def __add__(self, Float16 other):
252 return self.add(other)
254 cpdef Float16 sub(self, Float16 other):
255 cdef cfloat.float16_t f = cfloat.f16_sub(self._c_float, other._c_float)
256 return Float16.from_c_float(f)
258 def __sub__(self, Float16 other):
259 return self.sub(other)
261 cpdef Float16 mul(self, Float16 other):
262 cdef cfloat.float16_t f = cfloat.f16_mul(self._c_float, other._c_float)
263 return Float16.from_c_float(f)
265 def __mul__(self, Float16 other):
266 return self.mul(other)
268 cpdef Float16 fma(self, Float16 a1, Float16 a2):
269 cdef cfloat.float16_t f = cfloat.f16_mulAdd(a1._c_float, a2._c_float, self._c_float)
270 return Float16.from_c_float(f)
272 cpdef Float16 div(self, Float16 other):
273 cdef cfloat.float16_t f = cfloat.f16_div(self._c_float, other._c_float)
274 return Float16.from_c_float(f)
276 def __truediv__(self, Float16 other):
277 return self.div(other)
279 cpdef Float16 rem(self, Float16 other):
280 cdef cfloat.float16_t f = cfloat.f16_rem(self._c_float, other._c_float)
281 return Float16.from_c_float(f)
283 cpdef Float16 sqrt(self):
284 cdef cfloat.float16_t f = cfloat.f16_sqrt(self._c_float)
285 return Float16.from_c_float(f)
287 # in-place arithmetic
289 cpdef void ineg(self):
290 self._c_float = _f16_neg(self._c_float)
292 cpdef void iabs(self):
293 self._c_float = _f16_abs(self._c_float)
295 cpdef void iround_to(self, uint_fast8_t rm, bint exact):
296 self._c_float = cfloat.f16_roundToInt(self._c_float, rm, exact)
298 cpdef void iround(self):
299 self._c_float = cfloat.f16_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
301 cpdef void iadd(self, Float16 other):
302 self._c_float = cfloat.f16_add(self._c_float, other._c_float)
304 def __iadd__(self, Float16 other):
308 cpdef void isub(self, Float16 other):
309 self._c_float = cfloat.f16_sub(self._c_float, other._c_float)
311 def __isub__(self, Float16 other):
315 cpdef void imul(self, Float16 other):
316 self._c_float = cfloat.f16_mul(self._c_float, other._c_float)
318 def __imul__(self, Float16 other):
322 cpdef void ifma(self, Float16 a1, Float16 a2):
323 self._c_float = cfloat.f16_mulAdd(a1._c_float, a2._c_float, self._c_float)
325 cpdef void idiv(self, Float16 other):
326 self._c_float = cfloat.f16_div(self._c_float, other._c_float)
328 def __itruediv__(self, Float16 other):
332 cpdef void irem(self, Float16 other):
333 self._c_float = cfloat.f16_rem(self._c_float, other._c_float)
335 cpdef void isqrt(self):
336 self._c_float = cfloat.f16_sqrt(self._c_float)
340 cpdef bint eq(self, Float16 other):
341 return cfloat.f16_eq(self._c_float, other._c_float)
343 cpdef bint le(self, Float16 other):
344 return cfloat.f16_le(self._c_float, other._c_float)
346 cpdef bint lt(self, Float16 other):
347 return cfloat.f16_lt(self._c_float, other._c_float)
349 def __lt__(self, Float16 other):
350 return self.lt(other)
352 def __le__(self, Float16 other):
353 return self.le(other)
355 def __eq__(self, Float16 other):
356 return self.eq(other)
358 def __ne__(self, Float16 other):
359 return not self.eq(other)
361 def __ge__(self, Float16 other):
362 return other.le(self)
364 def __gt__(self, Float16 other):
365 return other.lt(self)
367 # conversion to other float types
369 cpdef Float32 to_f32(self):
370 cdef cfloat.float32_t f = cfloat.f16_to_f32(self._c_float)
371 return Float32.from_c_float(f)
373 cpdef Float64 to_f64(self):
374 cdef cfloat.float64_t f = cfloat.f16_to_f64(self._c_float)
375 return Float64.from_c_float(f)
378 # external, non-method arithmetic
380 cpdef Float16 f16_neg(Float16 a1):
381 cdef cfloat.float16_t f = _f16_neg(a1._c_float)
382 return Float16.from_c_float(f)
384 cpdef Float16 f16_abs(Float16 a1):
385 cdef cfloat.float16_t f = _f16_abs(a1._c_float)
386 return Float16.from_c_float(f)
388 cpdef Float16 f16_round_to(Float16 a1, uint_fast8_t rm, bint exact):
389 cdef cfloat.float16_t f = cfloat.f16_roundToInt(a1._c_float, rm, exact)
390 return Float16.from_c_float(f)
392 cpdef Float16 f16_round(Float16 a1):
393 cdef cfloat.float16_t f = cfloat.f16_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
394 return Float16.from_c_float(f)
396 cpdef Float16 f16_add(Float16 a1, Float16 a2):
397 cdef cfloat.float16_t f = cfloat.f16_add(a1._c_float, a2._c_float)
398 return Float16.from_c_float(f)
400 cpdef Float16 f16_sub(Float16 a1, Float16 a2):
401 cdef cfloat.float16_t f = cfloat.f16_sub(a1._c_float, a2._c_float)
402 return Float16.from_c_float(f)
404 cpdef Float16 f16_mul(Float16 a1, Float16 a2):
405 cdef cfloat.float16_t f = cfloat.f16_mul(a1._c_float, a2._c_float)
406 return Float16.from_c_float(f)
408 cpdef Float16 f16_fma(Float16 acc, Float16 a1, Float16 a2):
409 cdef cfloat.float16_t f = cfloat.f16_mulAdd(a1._c_float, a2._c_float, acc._c_float)
410 return Float16.from_c_float(f)
412 cpdef Float16 f16_div(Float16 a1, Float16 a2):
413 cdef cfloat.float16_t f = cfloat.f16_div(a1._c_float, a2._c_float)
414 return Float16.from_c_float(f)
416 cpdef Float16 f16_rem(Float16 a1, Float16 a2):
417 cdef cfloat.float16_t f = cfloat.f16_rem(a1._c_float, a2._c_float)
418 return Float16.from_c_float(f)
420 cpdef Float16 f16_sqrt(Float16 a1):
421 cdef cfloat.float16_t f = cfloat.f16_sqrt(a1._c_float)
422 return Float16.from_c_float(f)
424 cpdef bint f16_eq(Float16 a1, Float16 a2):
425 return cfloat.f16_eq(a1._c_float, a2._c_float)
427 cpdef bint f16_le(Float16 a1, Float16 a2):
428 return cfloat.f16_le(a1._c_float, a2._c_float)
430 cpdef bint f16_lt(Float16 a1, Float16 a2):
431 return cfloat.f16_lt(a1._c_float, a2._c_float)
433 cpdef Float32 f16_to_f32(Float16 a1):
434 cdef cfloat.float32_t f = cfloat.f16_to_f32(a1._c_float)
435 return Float32.from_c_float(f)
437 cpdef Float64 f16_to_f64(Float16 a1):
438 cdef cfloat.float64_t f = cfloat.f16_to_f64(a1._c_float)
439 return Float64.from_c_float(f)
444 # the wrapped float value
445 cdef cfloat.float32_t _c_float
447 # factory function constructors that bypass __init__
450 cdef Float32 from_c_float(cfloat.float32_t f):
451 """Factory function to create a Float32 object directly from
454 cdef Float32 obj = Float32.__new__(Float32)
459 def from_bits(uint32_t value):
460 """Factory function to create a Float32 object from a bit pattern
461 represented as an integer.
463 cdef Float32 obj = Float32.__new__(Float32)
464 obj._c_float.v = value
468 def from_double(double value):
469 """Factory function to create a Float32 object from a double.
471 cdef Float32 obj = Float32.__new__(Float32)
472 cdef cfloat.ui64_double ud
473 cdef cfloat.float64_t d
477 obj._c_float = cfloat.f64_to_f32(d)
481 # convenience interface for use inside Python
483 def __init__(self, value):
484 """Given an int, create a Float32 from the bitpattern represented by
485 that int. Otherwise, given some value, create a Float32 by rounding
488 cdef cfloat.ui64_double ud
489 cdef cfloat.float64_t d
491 if isinstance(value, int):
492 self._c_float.v = value
496 self._c_float = cfloat.f64_to_f32(d)
499 cdef cfloat.ui64_double ud
500 ud.u = cfloat.f32_to_f64(self._c_float).v
504 cdef cfloat.ui64_double ud
505 ud.u = cfloat.f32_to_f64(self._c_float).v
509 cdef cfloat.ui64_double ud
510 ud.u = cfloat.f32_to_f64(self._c_float).v
514 cdef cfloat.ui64_double ud
515 ud.u = cfloat.f32_to_f64(self._c_float).v
516 return 'Float32(' + repr(ud.d) + ')'
518 cpdef uint32_t get_bits(self):
519 return self._c_float.v
520 bits = property(get_bits)
524 cpdef Float32 neg(self):
525 cdef cfloat.float32_t f = _f32_neg(self._c_float)
526 return Float32.from_c_float(f)
531 cpdef Float32 abs(self):
532 cdef cfloat.float32_t f = _f32_abs(self._c_float)
533 return Float32.from_c_float(f)
538 cpdef Float32 round_to(self, uint_fast8_t rm, bint exact):
539 cdef cfloat.float32_t f = cfloat.f32_roundToInt(self._c_float, rm, exact)
540 return Float32.from_c_float(f)
542 cpdef Float32 round(self):
543 cdef cfloat.float32_t f = cfloat.f32_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
544 return Float32.from_c_float(f)
549 cpdef Float32 add(self, Float32 other):
550 cdef cfloat.float32_t f = cfloat.f32_add(self._c_float, other._c_float)
551 return Float32.from_c_float(f)
553 def __add__(self, Float32 other):
554 return self.add(other)
556 cpdef Float32 sub(self, Float32 other):
557 cdef cfloat.float32_t f = cfloat.f32_sub(self._c_float, other._c_float)
558 return Float32.from_c_float(f)
560 def __sub__(self, Float32 other):
561 return self.sub(other)
563 cpdef Float32 mul(self, Float32 other):
564 cdef cfloat.float32_t f = cfloat.f32_mul(self._c_float, other._c_float)
565 return Float32.from_c_float(f)
567 def __mul__(self, Float32 other):
568 return self.mul(other)
570 cpdef Float32 fma(self, Float32 a1, Float32 a2):
571 cdef cfloat.float32_t f = cfloat.f32_mulAdd(a1._c_float, a2._c_float, self._c_float)
572 return Float32.from_c_float(f)
574 cpdef Float32 div(self, Float32 other):
575 cdef cfloat.float32_t f = cfloat.f32_div(self._c_float, other._c_float)
576 return Float32.from_c_float(f)
578 def __truediv__(self, Float32 other):
579 return self.div(other)
581 cpdef Float32 rem(self, Float32 other):
582 cdef cfloat.float32_t f = cfloat.f32_rem(self._c_float, other._c_float)
583 return Float32.from_c_float(f)
585 cpdef Float32 sqrt(self):
586 cdef cfloat.float32_t f = cfloat.f32_sqrt(self._c_float)
587 return Float32.from_c_float(f)
589 # in-place arithmetic
591 cpdef void ineg(self):
592 self._c_float = _f32_neg(self._c_float)
594 cpdef void iabs(self):
595 self._c_float = _f32_abs(self._c_float)
597 cpdef void iround_to(self, uint_fast8_t rm, bint exact):
598 self._c_float = cfloat.f32_roundToInt(self._c_float, rm, exact)
600 cpdef void iround(self):
601 self._c_float = cfloat.f32_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
603 cpdef void iadd(self, Float32 other):
604 self._c_float = cfloat.f32_add(self._c_float, other._c_float)
606 def __iadd__(self, Float32 other):
610 cpdef void isub(self, Float32 other):
611 self._c_float = cfloat.f32_sub(self._c_float, other._c_float)
613 def __isub__(self, Float32 other):
617 cpdef void imul(self, Float32 other):
618 self._c_float = cfloat.f32_mul(self._c_float, other._c_float)
620 def __imul__(self, Float32 other):
624 cpdef void ifma(self, Float32 a1, Float32 a2):
625 self._c_float = cfloat.f32_mulAdd(a1._c_float, a2._c_float, self._c_float)
627 cpdef void idiv(self, Float32 other):
628 self._c_float = cfloat.f32_div(self._c_float, other._c_float)
630 def __itruediv__(self, Float32 other):
634 cpdef void irem(self, Float32 other):
635 self._c_float = cfloat.f32_rem(self._c_float, other._c_float)
637 cpdef void isqrt(self):
638 self._c_float = cfloat.f32_sqrt(self._c_float)
642 cpdef bint eq(self, Float32 other):
643 return cfloat.f32_eq(self._c_float, other._c_float)
645 cpdef bint le(self, Float32 other):
646 return cfloat.f32_le(self._c_float, other._c_float)
648 cpdef bint lt(self, Float32 other):
649 return cfloat.f32_lt(self._c_float, other._c_float)
651 def __lt__(self, Float32 other):
652 return self.lt(other)
654 def __le__(self, Float32 other):
655 return self.le(other)
657 def __eq__(self, Float32 other):
658 return self.eq(other)
660 def __ne__(self, Float32 other):
661 return not self.eq(other)
663 def __ge__(self, Float32 other):
664 return other.le(self)
666 def __gt__(self, Float32 other):
667 return other.lt(self)
669 # conversion to other float types
671 cpdef Float16 to_f16(self):
672 cdef cfloat.float16_t f = cfloat.f32_to_f16(self._c_float)
673 return Float16.from_c_float(f)
675 cpdef Float64 to_f64(self):
676 cdef cfloat.float64_t f = cfloat.f32_to_f64(self._c_float)
677 return Float64.from_c_float(f)
680 # integer conversions
685 cpdef Float16 i32_to_f16(int32_t value):
686 cdef cfloat.float16_t f = cfloat.i32_to_f16(value)
687 return Float16.from_c_float(f)
689 cpdef Float16 ui32_to_f16(uint32_t value):
690 cdef cfloat.float16_t f = cfloat.ui32_to_f16(value)
691 return Float16.from_c_float(f)
693 cpdef uint32_t f16_to_ui32(Float16 a1):
694 cdef uint32_t i = cfloat.f16_to_ui32(a1._c_float,
695 cfloat.softfloat_roundingMode, True)
698 cpdef int32_t f16_to_i32(Float16 a1):
699 cdef int32_t i = cfloat.f16_to_i32(a1._c_float,
700 cfloat.softfloat_roundingMode, True)
705 cpdef Float32 i32_to_f32(int32_t value):
706 cdef cfloat.float32_t f = cfloat.i32_to_f32(value)
707 return Float32.from_c_float(f)
709 cpdef Float32 ui32_to_f32(uint32_t value):
710 cdef cfloat.float32_t f = cfloat.ui32_to_f32(value)
711 return Float32.from_c_float(f)
713 cpdef uint32_t f32_to_ui32(Float32 a1):
714 cdef uint32_t i = cfloat.f32_to_ui32(a1._c_float,
715 cfloat.softfloat_roundingMode, True)
718 cpdef int32_t f32_to_i32(Float32 a1):
719 cdef int32_t i = cfloat.f32_to_i32(a1._c_float,
720 cfloat.softfloat_roundingMode, True)
725 cpdef Float64 i32_to_f64(int32_t value):
726 cdef cfloat.float64_t f = cfloat.i32_to_f64(value)
727 return Float64.from_c_float(f)
729 cpdef Float64 ui32_to_f64(uint32_t value):
730 cdef cfloat.float64_t f = cfloat.ui32_to_f64(value)
731 return Float64.from_c_float(f)
733 cpdef uint32_t f64_to_ui32(Float64 a1):
734 cdef uint32_t i = cfloat.f64_to_ui32(a1._c_float,
735 cfloat.softfloat_roundingMode, True)
738 cpdef int32_t f64_to_i32(Float64 a1):
739 cdef int32_t i = cfloat.f64_to_i32(a1._c_float,
740 cfloat.softfloat_roundingMode, True)
745 cpdef Float16 i64_to_f16(int64_t value):
746 cdef cfloat.float16_t f = cfloat.i64_to_f16(value)
747 return Float16.from_c_float(f)
749 cpdef Float16 ui64_to_f16(uint64_t value):
750 cdef cfloat.float16_t f = cfloat.ui64_to_f16(value)
751 return Float16.from_c_float(f)
753 cpdef uint64_t f16_to_ui64(Float16 a1):
754 cdef uint64_t i = cfloat.f16_to_ui64(a1._c_float,
755 cfloat.softfloat_roundingMode, True)
758 cpdef int64_t f16_to_i64(Float16 a1):
759 cdef int64_t i = cfloat.f16_to_i64(a1._c_float,
760 cfloat.softfloat_roundingMode, True)
765 cpdef Float32 i64_to_f32(int64_t value):
766 cdef cfloat.float32_t f = cfloat.i64_to_f32(value)
767 return Float32.from_c_float(f)
769 cpdef Float32 ui64_to_f32(uint64_t value):
770 cdef cfloat.float32_t f = cfloat.ui64_to_f32(value)
771 return Float32.from_c_float(f)
773 cpdef uint32_t f32_to_ui64(Float32 a1):
774 cdef uint32_t i = cfloat.f32_to_ui64(a1._c_float,
775 cfloat.softfloat_roundingMode, True)
778 cpdef int32_t f32_to_i64(Float32 a1):
779 cdef int32_t i = cfloat.f32_to_i64(a1._c_float,
780 cfloat.softfloat_roundingMode, True)
785 cpdef Float64 i64_to_f64(int64_t value):
786 cdef cfloat.float64_t f = cfloat.i64_to_f64(value)
787 return Float64.from_c_float(f)
789 cpdef Float64 ui64_to_f64(uint64_t value):
790 cdef cfloat.float64_t f = cfloat.ui64_to_f64(value)
791 return Float64.from_c_float(f)
793 cpdef uint64_t f64_to_ui64(Float64 a1):
794 cdef uint64_t i = cfloat.f64_to_ui64(a1._c_float,
795 cfloat.softfloat_roundingMode, True)
798 cpdef int64_t f64_to_i64(Float64 a1):
799 cdef int64_t i = cfloat.f64_to_i64(a1._c_float,
800 cfloat.softfloat_roundingMode, True)
803 # external, non-method arithmetic
805 cpdef Float32 f32_neg(Float32 a1):
806 cdef cfloat.float32_t f = _f32_neg(a1._c_float)
807 return Float32.from_c_float(f)
809 cpdef Float32 f32_abs(Float32 a1):
810 cdef cfloat.float32_t f = _f32_abs(a1._c_float)
811 return Float32.from_c_float(f)
813 cpdef Float32 f32_round_to(Float32 a1, uint_fast8_t rm, bint exact):
814 cdef cfloat.float32_t f = cfloat.f32_roundToInt(a1._c_float, rm, exact)
815 return Float32.from_c_float(f)
817 cpdef Float32 f32_round(Float32 a1):
818 cdef cfloat.float32_t f = cfloat.f32_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
819 return Float32.from_c_float(f)
821 cpdef Float32 f32_add(Float32 a1, Float32 a2):
822 cdef cfloat.float32_t f = cfloat.f32_add(a1._c_float, a2._c_float)
823 return Float32.from_c_float(f)
825 cpdef Float32 f32_sub(Float32 a1, Float32 a2):
826 cdef cfloat.float32_t f = cfloat.f32_sub(a1._c_float, a2._c_float)
827 return Float32.from_c_float(f)
829 cpdef Float32 f32_mul(Float32 a1, Float32 a2):
830 cdef cfloat.float32_t f = cfloat.f32_mul(a1._c_float, a2._c_float)
831 return Float32.from_c_float(f)
833 cpdef Float32 f32_fma(Float32 acc, Float32 a1, Float32 a2):
834 cdef cfloat.float32_t f = cfloat.f32_mulAdd(a1._c_float, a2._c_float, acc._c_float)
835 return Float32.from_c_float(f)
837 cpdef Float32 f32_div(Float32 a1, Float32 a2):
838 cdef cfloat.float32_t f = cfloat.f32_div(a1._c_float, a2._c_float)
839 return Float32.from_c_float(f)
841 cpdef Float32 f32_rem(Float32 a1, Float32 a2):
842 cdef cfloat.float32_t f = cfloat.f32_rem(a1._c_float, a2._c_float)
843 return Float32.from_c_float(f)
845 cpdef Float32 f32_sqrt(Float32 a1):
846 cdef cfloat.float32_t f = cfloat.f32_sqrt(a1._c_float)
847 return Float32.from_c_float(f)
849 cpdef bint f32_eq(Float32 a1, Float32 a2):
850 return cfloat.f32_eq(a1._c_float, a2._c_float)
852 cpdef bint f32_le(Float32 a1, Float32 a2):
853 return cfloat.f32_le(a1._c_float, a2._c_float)
855 cpdef bint f32_lt(Float32 a1, Float32 a2):
856 return cfloat.f32_lt(a1._c_float, a2._c_float)
858 cpdef Float16 f32_to_f16(Float32 a1):
859 cdef cfloat.float16_t f = cfloat.f32_to_f16(a1._c_float)
860 return Float16.from_c_float(f)
862 cpdef Float64 f32_to_f64(Float32 a1):
863 cdef cfloat.float64_t f = cfloat.f32_to_f64(a1._c_float)
864 return Float64.from_c_float(f)
869 # the wrapped float value
870 cdef cfloat.float64_t _c_float
872 # factory function constructors that bypass __init__
875 cdef Float64 from_c_float(cfloat.float64_t f):
876 """Factory function to create a Float64 object directly from
879 cdef Float64 obj = Float64.__new__(Float64)
884 def from_bits(uint64_t value):
885 """Factory function to create a Float64 object from a bit pattern
886 represented as an integer.
888 cdef Float64 obj = Float64.__new__(Float64)
889 obj._c_float.v = value
893 def from_double(double value):
894 """Factory function to create a Float64 object from a double.
896 cdef Float64 obj = Float64.__new__(Float64)
897 cdef cfloat.ui64_double ud
898 cdef cfloat.float64_t d
901 obj._c_float.v = ud.u
905 # convenience interface for use inside Python
907 def __init__(self, value):
908 """Given an int, create a Float64 from the bitpattern represented by
909 that int. Otherwise, given some value, create a Float64 from
912 cdef cfloat.ui64_double ud
913 cdef cfloat.float64_t d
915 if isinstance(value, int):
916 self._c_float.v = value
919 self._c_float.v = ud.u
922 cdef cfloat.ui64_double ud
923 ud.u = self._c_float.v
927 cdef cfloat.ui64_double ud
928 ud.u = self._c_float.v
932 cdef cfloat.ui64_double ud
933 ud.u = self._c_float.v
937 cdef cfloat.ui64_double ud
938 ud.u = self._c_float.v
939 return 'Float64(' + repr(ud.d) + ')'
941 cpdef uint64_t get_bits(self):
942 return self._c_float.v
943 bits = property(get_bits)
947 cpdef Float64 neg(self):
948 cdef cfloat.float64_t f = _f64_neg(self._c_float)
949 return Float64.from_c_float(f)
954 cpdef Float64 abs(self):
955 cdef cfloat.float64_t f = _f64_abs(self._c_float)
956 return Float64.from_c_float(f)
961 cpdef Float64 round_to(self, uint_fast8_t rm, bint exact):
962 cdef cfloat.float64_t f = cfloat.f64_roundToInt(self._c_float, rm, exact)
963 return Float64.from_c_float(f)
965 cpdef Float64 round(self):
966 cdef cfloat.float64_t f = cfloat.f64_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
967 return Float64.from_c_float(f)
972 cpdef Float64 add(self, Float64 other):
973 cdef cfloat.float64_t f = cfloat.f64_add(self._c_float, other._c_float)
974 return Float64.from_c_float(f)
976 def __add__(self, Float64 other):
977 return self.add(other)
979 cpdef Float64 sub(self, Float64 other):
980 cdef cfloat.float64_t f = cfloat.f64_sub(self._c_float, other._c_float)
981 return Float64.from_c_float(f)
983 def __sub__(self, Float64 other):
984 return self.sub(other)
986 cpdef Float64 mul(self, Float64 other):
987 cdef cfloat.float64_t f = cfloat.f64_mul(self._c_float, other._c_float)
988 return Float64.from_c_float(f)
990 def __mul__(self, Float64 other):
991 return self.mul(other)
993 cpdef Float64 fma(self, Float64 a1, Float64 a2):
994 cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, self._c_float)
995 return Float64.from_c_float(f)
997 cpdef Float64 div(self, Float64 other):
998 cdef cfloat.float64_t f = cfloat.f64_div(self._c_float, other._c_float)
999 return Float64.from_c_float(f)
1001 def __truediv__(self, Float64 other):
1002 return self.div(other)
1004 cpdef Float64 rem(self, Float64 other):
1005 cdef cfloat.float64_t f = cfloat.f64_rem(self._c_float, other._c_float)
1006 return Float64.from_c_float(f)
1008 cpdef Float64 sqrt(self):
1009 cdef cfloat.float64_t f = cfloat.f64_sqrt(self._c_float)
1010 return Float64.from_c_float(f)
1012 # in-place arithmetic
1014 cpdef void ineg(self):
1015 self._c_float = _f64_neg(self._c_float)
1017 cpdef void iabs(self):
1018 self._c_float = _f64_abs(self._c_float)
1020 cpdef void iround_to(self, uint_fast8_t rm, bint exact):
1021 self._c_float = cfloat.f64_roundToInt(self._c_float, rm, exact)
1023 cpdef void iround(self):
1024 self._c_float = cfloat.f64_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
1026 cpdef void iadd(self, Float64 other):
1027 self._c_float = cfloat.f64_add(self._c_float, other._c_float)
1029 def __iadd__(self, Float64 other):
1033 cpdef void isub(self, Float64 other):
1034 self._c_float = cfloat.f64_sub(self._c_float, other._c_float)
1036 def __isub__(self, Float64 other):
1040 cpdef void imul(self, Float64 other):
1041 self._c_float = cfloat.f64_mul(self._c_float, other._c_float)
1043 def __imul__(self, Float64 other):
1047 cpdef void ifma(self, Float64 a1, Float64 a2):
1048 self._c_float = cfloat.f64_mulAdd(a1._c_float, a2._c_float, self._c_float)
1050 cpdef void idiv(self, Float64 other):
1051 self._c_float = cfloat.f64_div(self._c_float, other._c_float)
1053 def __itruediv__(self, Float64 other):
1057 cpdef void irem(self, Float64 other):
1058 self._c_float = cfloat.f64_rem(self._c_float, other._c_float)
1060 cpdef void isqrt(self):
1061 self._c_float = cfloat.f64_sqrt(self._c_float)
1065 cpdef bint eq(self, Float64 other):
1066 return cfloat.f64_eq(self._c_float, other._c_float)
1068 cpdef bint le(self, Float64 other):
1069 return cfloat.f64_le(self._c_float, other._c_float)
1071 cpdef bint lt(self, Float64 other):
1072 return cfloat.f64_lt(self._c_float, other._c_float)
1074 def __lt__(self, Float64 other):
1075 return self.lt(other)
1077 def __le__(self, Float64 other):
1078 return self.le(other)
1080 def __eq__(self, Float64 other):
1081 return self.eq(other)
1083 def __ne__(self, Float64 other):
1084 return not self.eq(other)
1086 def __ge__(self, Float64 other):
1087 return other.le(self)
1089 def __gt__(self, Float64 other):
1090 return other.lt(self)
1092 # conversion to other float types
1094 cpdef Float16 to_f16(self):
1095 cdef cfloat.float16_t f = cfloat.f64_to_f16(self._c_float)
1096 return Float16.from_c_float(f)
1098 cpdef Float32 to_f32(self):
1099 cdef cfloat.float32_t f = cfloat.f64_to_f32(self._c_float)
1100 return Float32.from_c_float(f)
1103 # external, non-method arithmetic
1105 cpdef Float64 f64_neg(Float64 a1):
1106 cdef cfloat.float64_t f = _f64_neg(a1._c_float)
1107 return Float64.from_c_float(f)
1109 cpdef Float64 f64_abs(Float64 a1):
1110 cdef cfloat.float64_t f = _f64_abs(a1._c_float)
1111 return Float64.from_c_float(f)
1113 cpdef Float64 f64_round_to(Float64 a1, uint_fast8_t rm, bint exact):
1114 cdef cfloat.float64_t f = cfloat.f64_roundToInt(a1._c_float, rm, exact)
1115 return Float64.from_c_float(f)
1117 cpdef Float64 f64_round(Float64 a1):
1118 cdef cfloat.float64_t f = cfloat.f64_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
1119 return Float64.from_c_float(f)
1121 cpdef Float64 f64_add(Float64 a1, Float64 a2):
1122 cdef cfloat.float64_t f = cfloat.f64_add(a1._c_float, a2._c_float)
1123 return Float64.from_c_float(f)
1125 cpdef Float64 f64_sub(Float64 a1, Float64 a2):
1126 cdef cfloat.float64_t f = cfloat.f64_sub(a1._c_float, a2._c_float)
1127 return Float64.from_c_float(f)
1129 cpdef Float64 f64_mul(Float64 a1, Float64 a2):
1130 cdef cfloat.float64_t f = cfloat.f64_mul(a1._c_float, a2._c_float)
1131 return Float64.from_c_float(f)
1133 cpdef Float64 f64_fma(Float64 acc, Float64 a1, Float64 a2):
1134 cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, acc._c_float)
1135 return Float64.from_c_float(f)
1137 cpdef Float64 f64_div(Float64 a1, Float64 a2):
1138 cdef cfloat.float64_t f = cfloat.f64_div(a1._c_float, a2._c_float)
1139 return Float64.from_c_float(f)
1141 cpdef Float64 f64_rem(Float64 a1, Float64 a2):
1142 cdef cfloat.float64_t f = cfloat.f64_rem(a1._c_float, a2._c_float)
1143 return Float64.from_c_float(f)
1145 cpdef Float64 f64_sqrt(Float64 a1):
1146 cdef cfloat.float64_t f = cfloat.f64_sqrt(a1._c_float)
1147 return Float64.from_c_float(f)
1149 cpdef bint f64_eq(Float64 a1, Float64 a2):
1150 return cfloat.f64_eq(a1._c_float, a2._c_float)
1152 cpdef bint f64_le(Float64 a1, Float64 a2):
1153 return cfloat.f64_le(a1._c_float, a2._c_float)
1155 cpdef bint f64_lt(Float64 a1, Float64 a2):
1156 return cfloat.f64_lt(a1._c_float, a2._c_float)
1158 cpdef Float16 f64_to_f16(Float64 a1):
1159 cdef cfloat.float16_t f = cfloat.f64_to_f16(a1._c_float)
1160 return Float16.from_c_float(f)
1162 cpdef Float32 f64_to_f32(Float64 a1):
1163 cdef cfloat.float32_t f = cfloat.f64_to_f32(a1._c_float)
1164 return Float32.from_c_float(f)