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 # external, non-method arithmetic
682 cpdef Float32 f32_neg(Float32 a1):
683 cdef cfloat.float32_t f = _f32_neg(a1._c_float)
684 return Float32.from_c_float(f)
686 cpdef Float32 f32_abs(Float32 a1):
687 cdef cfloat.float32_t f = _f32_abs(a1._c_float)
688 return Float32.from_c_float(f)
690 cpdef Float32 f32_round_to(Float32 a1, uint_fast8_t rm, bint exact):
691 cdef cfloat.float32_t f = cfloat.f32_roundToInt(a1._c_float, rm, exact)
692 return Float32.from_c_float(f)
694 cpdef Float32 f32_round(Float32 a1):
695 cdef cfloat.float32_t f = cfloat.f32_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
696 return Float32.from_c_float(f)
698 cpdef Float32 f32_add(Float32 a1, Float32 a2):
699 cdef cfloat.float32_t f = cfloat.f32_add(a1._c_float, a2._c_float)
700 return Float32.from_c_float(f)
702 cpdef Float32 f32_sub(Float32 a1, Float32 a2):
703 cdef cfloat.float32_t f = cfloat.f32_sub(a1._c_float, a2._c_float)
704 return Float32.from_c_float(f)
706 cpdef Float32 f32_mul(Float32 a1, Float32 a2):
707 cdef cfloat.float32_t f = cfloat.f32_mul(a1._c_float, a2._c_float)
708 return Float32.from_c_float(f)
710 cpdef Float32 f32_fma(Float32 acc, Float32 a1, Float32 a2):
711 cdef cfloat.float32_t f = cfloat.f32_mulAdd(a1._c_float, a2._c_float, acc._c_float)
712 return Float32.from_c_float(f)
714 cpdef Float32 f32_div(Float32 a1, Float32 a2):
715 cdef cfloat.float32_t f = cfloat.f32_div(a1._c_float, a2._c_float)
716 return Float32.from_c_float(f)
718 cpdef Float32 f32_rem(Float32 a1, Float32 a2):
719 cdef cfloat.float32_t f = cfloat.f32_rem(a1._c_float, a2._c_float)
720 return Float32.from_c_float(f)
722 cpdef Float32 f32_sqrt(Float32 a1):
723 cdef cfloat.float32_t f = cfloat.f32_sqrt(a1._c_float)
724 return Float32.from_c_float(f)
726 cpdef bint f32_eq(Float32 a1, Float32 a2):
727 return cfloat.f32_eq(a1._c_float, a2._c_float)
729 cpdef bint f32_le(Float32 a1, Float32 a2):
730 return cfloat.f32_le(a1._c_float, a2._c_float)
732 cpdef bint f32_lt(Float32 a1, Float32 a2):
733 return cfloat.f32_lt(a1._c_float, a2._c_float)
735 cpdef Float16 f32_to_f16(Float32 a1):
736 cdef cfloat.float16_t f = cfloat.f32_to_f16(a1._c_float)
737 return Float16.from_c_float(f)
739 cpdef Float64 f32_to_f64(Float32 a1):
740 cdef cfloat.float64_t f = cfloat.f32_to_f64(a1._c_float)
741 return Float64.from_c_float(f)
746 # the wrapped float value
747 cdef cfloat.float64_t _c_float
749 # factory function constructors that bypass __init__
752 cdef Float64 from_c_float(cfloat.float64_t f):
753 """Factory function to create a Float64 object directly from
756 cdef Float64 obj = Float64.__new__(Float64)
761 def from_bits(uint64_t value):
762 """Factory function to create a Float64 object from a bit pattern
763 represented as an integer.
765 cdef Float64 obj = Float64.__new__(Float64)
766 obj._c_float.v = value
770 def from_double(double value):
771 """Factory function to create a Float64 object from a double.
773 cdef Float64 obj = Float64.__new__(Float64)
774 cdef cfloat.ui64_double ud
775 cdef cfloat.float64_t d
778 obj._c_float.v = ud.u
782 # convenience interface for use inside Python
784 def __init__(self, value):
785 """Given an int, create a Float64 from the bitpattern represented by
786 that int. Otherwise, given some value, create a Float64 from
789 cdef cfloat.ui64_double ud
790 cdef cfloat.float64_t d
792 if isinstance(value, int):
793 self._c_float.v = value
796 self._c_float.v = ud.u
799 cdef cfloat.ui64_double ud
800 ud.u = self._c_float.v
804 cdef cfloat.ui64_double ud
805 ud.u = self._c_float.v
809 cdef cfloat.ui64_double ud
810 ud.u = self._c_float.v
814 cdef cfloat.ui64_double ud
815 ud.u = self._c_float.v
816 return 'Float64(' + repr(ud.d) + ')'
818 cpdef uint64_t get_bits(self):
819 return self._c_float.v
820 bits = property(get_bits)
824 cpdef Float64 neg(self):
825 cdef cfloat.float64_t f = _f64_neg(self._c_float)
826 return Float64.from_c_float(f)
831 cpdef Float64 abs(self):
832 cdef cfloat.float64_t f = _f64_abs(self._c_float)
833 return Float64.from_c_float(f)
838 cpdef Float64 round_to(self, uint_fast8_t rm, bint exact):
839 cdef cfloat.float64_t f = cfloat.f64_roundToInt(self._c_float, rm, exact)
840 return Float64.from_c_float(f)
842 cpdef Float64 round(self):
843 cdef cfloat.float64_t f = cfloat.f64_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
844 return Float64.from_c_float(f)
849 cpdef Float64 add(self, Float64 other):
850 cdef cfloat.float64_t f = cfloat.f64_add(self._c_float, other._c_float)
851 return Float64.from_c_float(f)
853 def __add__(self, Float64 other):
854 return self.add(other)
856 cpdef Float64 sub(self, Float64 other):
857 cdef cfloat.float64_t f = cfloat.f64_sub(self._c_float, other._c_float)
858 return Float64.from_c_float(f)
860 def __sub__(self, Float64 other):
861 return self.sub(other)
863 cpdef Float64 mul(self, Float64 other):
864 cdef cfloat.float64_t f = cfloat.f64_mul(self._c_float, other._c_float)
865 return Float64.from_c_float(f)
867 def __mul__(self, Float64 other):
868 return self.mul(other)
870 cpdef Float64 fma(self, Float64 a1, Float64 a2):
871 cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, self._c_float)
872 return Float64.from_c_float(f)
874 cpdef Float64 div(self, Float64 other):
875 cdef cfloat.float64_t f = cfloat.f64_div(self._c_float, other._c_float)
876 return Float64.from_c_float(f)
878 def __truediv__(self, Float64 other):
879 return self.div(other)
881 cpdef Float64 rem(self, Float64 other):
882 cdef cfloat.float64_t f = cfloat.f64_rem(self._c_float, other._c_float)
883 return Float64.from_c_float(f)
885 cpdef Float64 sqrt(self):
886 cdef cfloat.float64_t f = cfloat.f64_sqrt(self._c_float)
887 return Float64.from_c_float(f)
889 # in-place arithmetic
891 cpdef void ineg(self):
892 self._c_float = _f64_neg(self._c_float)
894 cpdef void iabs(self):
895 self._c_float = _f64_abs(self._c_float)
897 cpdef void iround_to(self, uint_fast8_t rm, bint exact):
898 self._c_float = cfloat.f64_roundToInt(self._c_float, rm, exact)
900 cpdef void iround(self):
901 self._c_float = cfloat.f64_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
903 cpdef void iadd(self, Float64 other):
904 self._c_float = cfloat.f64_add(self._c_float, other._c_float)
906 def __iadd__(self, Float64 other):
910 cpdef void isub(self, Float64 other):
911 self._c_float = cfloat.f64_sub(self._c_float, other._c_float)
913 def __isub__(self, Float64 other):
917 cpdef void imul(self, Float64 other):
918 self._c_float = cfloat.f64_mul(self._c_float, other._c_float)
920 def __imul__(self, Float64 other):
924 cpdef void ifma(self, Float64 a1, Float64 a2):
925 self._c_float = cfloat.f64_mulAdd(a1._c_float, a2._c_float, self._c_float)
927 cpdef void idiv(self, Float64 other):
928 self._c_float = cfloat.f64_div(self._c_float, other._c_float)
930 def __itruediv__(self, Float64 other):
934 cpdef void irem(self, Float64 other):
935 self._c_float = cfloat.f64_rem(self._c_float, other._c_float)
937 cpdef void isqrt(self):
938 self._c_float = cfloat.f64_sqrt(self._c_float)
942 cpdef bint eq(self, Float64 other):
943 return cfloat.f64_eq(self._c_float, other._c_float)
945 cpdef bint le(self, Float64 other):
946 return cfloat.f64_le(self._c_float, other._c_float)
948 cpdef bint lt(self, Float64 other):
949 return cfloat.f64_lt(self._c_float, other._c_float)
951 def __lt__(self, Float64 other):
952 return self.lt(other)
954 def __le__(self, Float64 other):
955 return self.le(other)
957 def __eq__(self, Float64 other):
958 return self.eq(other)
960 def __ne__(self, Float64 other):
961 return not self.eq(other)
963 def __ge__(self, Float64 other):
964 return other.le(self)
966 def __gt__(self, Float64 other):
967 return other.lt(self)
969 # conversion to other float types
971 cpdef Float16 to_f16(self):
972 cdef cfloat.float16_t f = cfloat.f64_to_f16(self._c_float)
973 return Float16.from_c_float(f)
975 cpdef Float32 to_f32(self):
976 cdef cfloat.float32_t f = cfloat.f64_to_f32(self._c_float)
977 return Float32.from_c_float(f)
980 # external, non-method arithmetic
982 cpdef Float64 f64_neg(Float64 a1):
983 cdef cfloat.float64_t f = _f64_neg(a1._c_float)
984 return Float64.from_c_float(f)
986 cpdef Float64 f64_abs(Float64 a1):
987 cdef cfloat.float64_t f = _f64_abs(a1._c_float)
988 return Float64.from_c_float(f)
990 cpdef Float64 f64_round_to(Float64 a1, uint_fast8_t rm, bint exact):
991 cdef cfloat.float64_t f = cfloat.f64_roundToInt(a1._c_float, rm, exact)
992 return Float64.from_c_float(f)
994 cpdef Float64 f64_round(Float64 a1):
995 cdef cfloat.float64_t f = cfloat.f64_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
996 return Float64.from_c_float(f)
998 cpdef Float64 f64_add(Float64 a1, Float64 a2):
999 cdef cfloat.float64_t f = cfloat.f64_add(a1._c_float, a2._c_float)
1000 return Float64.from_c_float(f)
1002 cpdef Float64 f64_sub(Float64 a1, Float64 a2):
1003 cdef cfloat.float64_t f = cfloat.f64_sub(a1._c_float, a2._c_float)
1004 return Float64.from_c_float(f)
1006 cpdef Float64 f64_mul(Float64 a1, Float64 a2):
1007 cdef cfloat.float64_t f = cfloat.f64_mul(a1._c_float, a2._c_float)
1008 return Float64.from_c_float(f)
1010 cpdef Float64 f64_fma(Float64 acc, Float64 a1, Float64 a2):
1011 cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, acc._c_float)
1012 return Float64.from_c_float(f)
1014 cpdef Float64 f64_div(Float64 a1, Float64 a2):
1015 cdef cfloat.float64_t f = cfloat.f64_div(a1._c_float, a2._c_float)
1016 return Float64.from_c_float(f)
1018 cpdef Float64 f64_rem(Float64 a1, Float64 a2):
1019 cdef cfloat.float64_t f = cfloat.f64_rem(a1._c_float, a2._c_float)
1020 return Float64.from_c_float(f)
1022 cpdef Float64 f64_sqrt(Float64 a1):
1023 cdef cfloat.float64_t f = cfloat.f64_sqrt(a1._c_float)
1024 return Float64.from_c_float(f)
1026 cpdef bint f64_eq(Float64 a1, Float64 a2):
1027 return cfloat.f64_eq(a1._c_float, a2._c_float)
1029 cpdef bint f64_le(Float64 a1, Float64 a2):
1030 return cfloat.f64_le(a1._c_float, a2._c_float)
1032 cpdef bint f64_lt(Float64 a1, Float64 a2):
1033 return cfloat.f64_lt(a1._c_float, a2._c_float)
1035 cpdef Float16 f64_to_f16(Float64 a1):
1036 cdef cfloat.float16_t f = cfloat.f64_to_f16(a1._c_float)
1037 return Float16.from_c_float(f)
1039 cpdef Float32 f64_to_f32(Float64 a1):
1040 cdef cfloat.float32_t f = cfloat.f64_to_f32(a1._c_float)
1041 return Float32.from_c_float(f)