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 a2, Float16 a3):
265 cdef cfloat.float16_t f = cfloat.f16_mulAdd(self._c_float, a2._c_float, a3._c_float)
266 return Float16.from_c_float(f)
268 cpdef Float16 fam(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 a2, Float16 a3):
323 self._c_float = cfloat.f16_mulAdd(self._c_float, a2._c_float, a3._c_float)
325 cpdef void ifam(self, Float16 a1, Float16 a2):
326 self._c_float = cfloat.f16_mulAdd(a1._c_float, a2._c_float, self._c_float)
328 cpdef void idiv(self, Float16 other):
329 self._c_float = cfloat.f16_div(self._c_float, other._c_float)
331 def __itruediv__(self, Float16 other):
335 cpdef void irem(self, Float16 other):
336 self._c_float = cfloat.f16_rem(self._c_float, other._c_float)
338 cpdef void isqrt(self):
339 self._c_float = cfloat.f16_sqrt(self._c_float)
343 cpdef bint eq(self, Float16 other):
344 return cfloat.f16_eq(self._c_float, other._c_float)
346 cpdef bint le(self, Float16 other):
347 return cfloat.f16_le(self._c_float, other._c_float)
349 cpdef bint lt(self, Float16 other):
350 return cfloat.f16_lt(self._c_float, other._c_float)
352 def __lt__(self, Float16 other):
353 return self.lt(other)
355 def __le__(self, Float16 other):
356 return self.le(other)
358 def __eq__(self, Float16 other):
359 return self.eq(other)
361 def __ne__(self, Float16 other):
362 return not self.eq(other)
364 def __ge__(self, Float16 other):
365 return other.le(self)
367 def __gt__(self, Float16 other):
368 return other.lt(self)
370 # conversion to other float types
372 cpdef Float32 to_f32(self):
373 cdef cfloat.float32_t f = cfloat.f16_to_f32(self._c_float)
374 return Float32.from_c_float(f)
376 cpdef Float64 to_f64(self):
377 cdef cfloat.float64_t f = cfloat.f16_to_f64(self._c_float)
378 return Float64.from_c_float(f)
381 # external, non-method arithmetic
383 cpdef Float16 f16_neg(Float16 a1):
384 cdef cfloat.float16_t f = _f16_neg(a1._c_float)
385 return Float16.from_c_float(f)
387 cpdef Float16 f16_abs(Float16 a1):
388 cdef cfloat.float16_t f = _f16_abs(a1._c_float)
389 return Float16.from_c_float(f)
391 cpdef Float16 f16_round_to(Float16 a1, uint_fast8_t rm, bint exact):
392 cdef cfloat.float16_t f = cfloat.f16_roundToInt(a1._c_float, rm, exact)
393 return Float16.from_c_float(f)
395 cpdef Float16 f16_round(Float16 a1):
396 cdef cfloat.float16_t f = cfloat.f16_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
397 return Float16.from_c_float(f)
399 cpdef Float16 f16_add(Float16 a1, Float16 a2):
400 cdef cfloat.float16_t f = cfloat.f16_add(a1._c_float, a2._c_float)
401 return Float16.from_c_float(f)
403 cpdef Float16 f16_sub(Float16 a1, Float16 a2):
404 cdef cfloat.float16_t f = cfloat.f16_sub(a1._c_float, a2._c_float)
405 return Float16.from_c_float(f)
407 cpdef Float16 f16_mul(Float16 a1, Float16 a2):
408 cdef cfloat.float16_t f = cfloat.f16_mul(a1._c_float, a2._c_float)
409 return Float16.from_c_float(f)
411 cpdef Float16 f16_fma(Float16 a1, Float16 a2, Float16 a3):
412 cdef cfloat.float16_t f = cfloat.f16_mulAdd(a1._c_float, a2._c_float, a3._c_float)
413 return Float16.from_c_float(f)
415 cpdef Float16 f16_fam(Float16 a3, Float16 a1, Float16 a2):
416 cdef cfloat.float16_t f = cfloat.f16_mulAdd(a1._c_float, a2._c_float, a3._c_float)
417 return Float16.from_c_float(f)
419 cpdef Float16 f16_div(Float16 a1, Float16 a2):
420 cdef cfloat.float16_t f = cfloat.f16_div(a1._c_float, a2._c_float)
421 return Float16.from_c_float(f)
423 cpdef Float16 f16_rem(Float16 a1, Float16 a2):
424 cdef cfloat.float16_t f = cfloat.f16_rem(a1._c_float, a2._c_float)
425 return Float16.from_c_float(f)
427 cpdef Float16 f16_sqrt(Float16 a1):
428 cdef cfloat.float16_t f = cfloat.f16_sqrt(a1._c_float)
429 return Float16.from_c_float(f)
431 cpdef bint f16_eq(Float16 a1, Float16 a2):
432 return cfloat.f16_eq(a1._c_float, a2._c_float)
434 cpdef bint f16_le(Float16 a1, Float16 a2):
435 return cfloat.f16_le(a1._c_float, a2._c_float)
437 cpdef bint f16_lt(Float16 a1, Float16 a2):
438 return cfloat.f16_lt(a1._c_float, a2._c_float)
440 cpdef Float32 f16_to_f32(Float16 a1):
441 cdef cfloat.float32_t f = cfloat.f16_to_f32(a1._c_float)
442 return Float32.from_c_float(f)
444 cpdef Float64 f16_to_f64(Float16 a1):
445 cdef cfloat.float64_t f = cfloat.f16_to_f64(a1._c_float)
446 return Float64.from_c_float(f)
451 # the wrapped float value
452 cdef cfloat.float32_t _c_float
454 # factory function constructors that bypass __init__
457 cdef Float32 from_c_float(cfloat.float32_t f):
458 """Factory function to create a Float32 object directly from
461 cdef Float32 obj = Float32.__new__(Float32)
466 def from_bits(uint32_t value):
467 """Factory function to create a Float32 object from a bit pattern
468 represented as an integer.
470 cdef Float32 obj = Float32.__new__(Float32)
471 obj._c_float.v = value
475 def from_double(double value):
476 """Factory function to create a Float32 object from a double.
478 cdef Float32 obj = Float32.__new__(Float32)
479 cdef cfloat.ui64_double ud
480 cdef cfloat.float64_t d
484 obj._c_float = cfloat.f64_to_f32(d)
488 # convenience interface for use inside Python
490 def __init__(self, value):
491 cdef cfloat.ui64_double ud
492 cdef cfloat.float64_t d
494 if isinstance(value, int):
495 self._c_float.v = value
499 self._c_float = cfloat.f64_to_f32(d)
502 cdef cfloat.ui64_double ud
503 ud.u = cfloat.f32_to_f64(self._c_float).v
507 cdef cfloat.ui64_double ud
508 ud.u = cfloat.f32_to_f64(self._c_float).v
512 cdef cfloat.ui64_double ud
513 ud.u = cfloat.f32_to_f64(self._c_float).v
517 cdef cfloat.ui64_double ud
518 ud.u = cfloat.f32_to_f64(self._c_float).v
519 return 'Float32(' + repr(ud.d) + ')'
521 cpdef uint32_t get_bits(self):
522 return self._c_float.v
523 bits = property(get_bits)
527 cpdef Float32 neg(self):
528 cdef cfloat.float32_t f = _f32_neg(self._c_float)
529 return Float32.from_c_float(f)
534 cpdef Float32 abs(self):
535 cdef cfloat.float32_t f = _f32_abs(self._c_float)
536 return Float32.from_c_float(f)
541 cpdef Float32 round_to(self, uint_fast8_t rm, bint exact):
542 cdef cfloat.float32_t f = cfloat.f32_roundToInt(self._c_float, rm, exact)
543 return Float32.from_c_float(f)
545 cpdef Float32 round(self):
546 cdef cfloat.float32_t f = cfloat.f32_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
547 return Float32.from_c_float(f)
552 cpdef Float32 add(self, Float32 other):
553 cdef cfloat.float32_t f = cfloat.f32_add(self._c_float, other._c_float)
554 return Float32.from_c_float(f)
556 def __add__(self, Float32 other):
557 return self.add(other)
559 cpdef Float32 sub(self, Float32 other):
560 cdef cfloat.float32_t f = cfloat.f32_sub(self._c_float, other._c_float)
561 return Float32.from_c_float(f)
563 def __sub__(self, Float32 other):
564 return self.sub(other)
566 cpdef Float32 mul(self, Float32 other):
567 cdef cfloat.float32_t f = cfloat.f32_mul(self._c_float, other._c_float)
568 return Float32.from_c_float(f)
570 def __mul__(self, Float32 other):
571 return self.mul(other)
573 cpdef Float32 fma(self, Float32 a2, Float32 a3):
574 cdef cfloat.float32_t f = cfloat.f32_mulAdd(self._c_float, a2._c_float, a3._c_float)
575 return Float32.from_c_float(f)
577 cpdef Float32 fam(self, Float32 a1, Float32 a2):
578 cdef cfloat.float32_t f = cfloat.f32_mulAdd(a1._c_float, a2._c_float, self._c_float)
579 return Float32.from_c_float(f)
581 cpdef Float32 div(self, Float32 other):
582 cdef cfloat.float32_t f = cfloat.f32_div(self._c_float, other._c_float)
583 return Float32.from_c_float(f)
585 def __truediv__(self, Float32 other):
586 return self.div(other)
588 cpdef Float32 rem(self, Float32 other):
589 cdef cfloat.float32_t f = cfloat.f32_rem(self._c_float, other._c_float)
590 return Float32.from_c_float(f)
592 cpdef Float32 sqrt(self):
593 cdef cfloat.float32_t f = cfloat.f32_sqrt(self._c_float)
594 return Float32.from_c_float(f)
596 # in-place arithmetic
598 cpdef void ineg(self):
599 self._c_float = _f32_neg(self._c_float)
601 cpdef void iabs(self):
602 self._c_float = _f32_abs(self._c_float)
604 cpdef void iround_to(self, uint_fast8_t rm, bint exact):
605 self._c_float = cfloat.f32_roundToInt(self._c_float, rm, exact)
607 cpdef void iround(self):
608 self._c_float = cfloat.f32_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
610 cpdef void iadd(self, Float32 other):
611 self._c_float = cfloat.f32_add(self._c_float, other._c_float)
613 def __iadd__(self, Float32 other):
617 cpdef void isub(self, Float32 other):
618 self._c_float = cfloat.f32_sub(self._c_float, other._c_float)
620 def __isub__(self, Float32 other):
624 cpdef void imul(self, Float32 other):
625 self._c_float = cfloat.f32_mul(self._c_float, other._c_float)
627 def __imul__(self, Float32 other):
631 cpdef void ifma(self, Float32 a2, Float32 a3):
632 self._c_float = cfloat.f32_mulAdd(self._c_float, a2._c_float, a3._c_float)
634 cpdef void ifam(self, Float32 a1, Float32 a2):
635 self._c_float = cfloat.f32_mulAdd(a1._c_float, a2._c_float, self._c_float)
637 cpdef void idiv(self, Float32 other):
638 self._c_float = cfloat.f32_div(self._c_float, other._c_float)
640 def __itruediv__(self, Float32 other):
644 cpdef void irem(self, Float32 other):
645 self._c_float = cfloat.f32_rem(self._c_float, other._c_float)
647 cpdef void isqrt(self):
648 self._c_float = cfloat.f32_sqrt(self._c_float)
652 cpdef bint eq(self, Float32 other):
653 return cfloat.f32_eq(self._c_float, other._c_float)
655 cpdef bint le(self, Float32 other):
656 return cfloat.f32_le(self._c_float, other._c_float)
658 cpdef bint lt(self, Float32 other):
659 return cfloat.f32_lt(self._c_float, other._c_float)
661 def __lt__(self, Float32 other):
662 return self.lt(other)
664 def __le__(self, Float32 other):
665 return self.le(other)
667 def __eq__(self, Float32 other):
668 return self.eq(other)
670 def __ne__(self, Float32 other):
671 return not self.eq(other)
673 def __ge__(self, Float32 other):
674 return other.le(self)
676 def __gt__(self, Float32 other):
677 return other.lt(self)
679 # conversion to other float types
681 cpdef Float16 to_f16(self):
682 cdef cfloat.float16_t f = cfloat.f32_to_f16(self._c_float)
683 return Float16.from_c_float(f)
685 cpdef Float64 to_f64(self):
686 cdef cfloat.float64_t f = cfloat.f32_to_f64(self._c_float)
687 return Float64.from_c_float(f)
690 # external, non-method arithmetic
692 cpdef Float32 f32_neg(Float32 a1):
693 cdef cfloat.float32_t f = _f32_neg(a1._c_float)
694 return Float32.from_c_float(f)
696 cpdef Float32 f32_abs(Float32 a1):
697 cdef cfloat.float32_t f = _f32_abs(a1._c_float)
698 return Float32.from_c_float(f)
700 cpdef Float32 f32_round_to(Float32 a1, uint_fast8_t rm, bint exact):
701 cdef cfloat.float32_t f = cfloat.f32_roundToInt(a1._c_float, rm, exact)
702 return Float32.from_c_float(f)
704 cpdef Float32 f32_round(Float32 a1):
705 cdef cfloat.float32_t f = cfloat.f32_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
706 return Float32.from_c_float(f)
708 cpdef Float32 f32_add(Float32 a1, Float32 a2):
709 cdef cfloat.float32_t f = cfloat.f32_add(a1._c_float, a2._c_float)
710 return Float32.from_c_float(f)
712 cpdef Float32 f32_sub(Float32 a1, Float32 a2):
713 cdef cfloat.float32_t f = cfloat.f32_sub(a1._c_float, a2._c_float)
714 return Float32.from_c_float(f)
716 cpdef Float32 f32_mul(Float32 a1, Float32 a2):
717 cdef cfloat.float32_t f = cfloat.f32_mul(a1._c_float, a2._c_float)
718 return Float32.from_c_float(f)
720 cpdef Float32 f32_fma(Float32 a1, Float32 a2, Float32 a3):
721 cdef cfloat.float32_t f = cfloat.f32_mulAdd(a1._c_float, a2._c_float, a3._c_float)
722 return Float32.from_c_float(f)
724 cpdef Float32 f32_fam(Float32 a3, Float32 a1, Float32 a2):
725 cdef cfloat.float32_t f = cfloat.f32_mulAdd(a1._c_float, a2._c_float, a3._c_float)
726 return Float32.from_c_float(f)
728 cpdef Float32 f32_div(Float32 a1, Float32 a2):
729 cdef cfloat.float32_t f = cfloat.f32_div(a1._c_float, a2._c_float)
730 return Float32.from_c_float(f)
732 cpdef Float32 f32_rem(Float32 a1, Float32 a2):
733 cdef cfloat.float32_t f = cfloat.f32_rem(a1._c_float, a2._c_float)
734 return Float32.from_c_float(f)
736 cpdef Float32 f32_sqrt(Float32 a1):
737 cdef cfloat.float32_t f = cfloat.f32_sqrt(a1._c_float)
738 return Float32.from_c_float(f)
740 cpdef bint f32_eq(Float32 a1, Float32 a2):
741 return cfloat.f32_eq(a1._c_float, a2._c_float)
743 cpdef bint f32_le(Float32 a1, Float32 a2):
744 return cfloat.f32_le(a1._c_float, a2._c_float)
746 cpdef bint f32_lt(Float32 a1, Float32 a2):
747 return cfloat.f32_lt(a1._c_float, a2._c_float)
749 cpdef Float16 f32_to_f16(Float32 a1):
750 cdef cfloat.float16_t f = cfloat.f32_to_f16(a1._c_float)
751 return Float16.from_c_float(f)
753 cpdef Float64 f32_to_f64(Float32 a1):
754 cdef cfloat.float64_t f = cfloat.f32_to_f64(a1._c_float)
755 return Float64.from_c_float(f)
760 # the wrapped float value
761 cdef cfloat.float64_t _c_float
763 # factory function constructors that bypass __init__
766 cdef Float64 from_c_float(cfloat.float64_t f):
767 """Factory function to create a Float64 object directly from
770 cdef Float64 obj = Float64.__new__(Float64)
775 def from_bits(uint64_t value):
776 """Factory function to create a Float64 object from a bit pattern
777 represented as an integer.
779 cdef Float64 obj = Float64.__new__(Float64)
780 obj._c_float.v = value
784 def from_double(double value):
785 """Factory function to create a Float64 object from a double.
787 cdef Float64 obj = Float64.__new__(Float64)
788 cdef cfloat.ui64_double ud
789 cdef cfloat.float64_t d
792 obj._c_float.v = ud.u
796 # convenience interface for use inside Python
798 def __init__(self, value):
799 cdef cfloat.ui64_double ud
800 cdef cfloat.float64_t d
802 if isinstance(value, int):
803 self._c_float.v = value
806 self._c_float.v = ud.u
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
819 cdef cfloat.ui64_double ud
820 ud.u = self._c_float.v
824 cdef cfloat.ui64_double ud
825 ud.u = self._c_float.v
826 return 'Float64(' + repr(ud.d) + ')'
828 cpdef uint64_t get_bits(self):
829 return self._c_float.v
830 bits = property(get_bits)
834 cpdef Float64 neg(self):
835 cdef cfloat.float64_t f = _f64_neg(self._c_float)
836 return Float64.from_c_float(f)
841 cpdef Float64 abs(self):
842 cdef cfloat.float64_t f = _f64_abs(self._c_float)
843 return Float64.from_c_float(f)
848 cpdef Float64 round_to(self, uint_fast8_t rm, bint exact):
849 cdef cfloat.float64_t f = cfloat.f64_roundToInt(self._c_float, rm, exact)
850 return Float64.from_c_float(f)
852 cpdef Float64 round(self):
853 cdef cfloat.float64_t f = cfloat.f64_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
854 return Float64.from_c_float(f)
859 cpdef Float64 add(self, Float64 other):
860 cdef cfloat.float64_t f = cfloat.f64_add(self._c_float, other._c_float)
861 return Float64.from_c_float(f)
863 def __add__(self, Float64 other):
864 return self.add(other)
866 cpdef Float64 sub(self, Float64 other):
867 cdef cfloat.float64_t f = cfloat.f64_sub(self._c_float, other._c_float)
868 return Float64.from_c_float(f)
870 def __sub__(self, Float64 other):
871 return self.sub(other)
873 cpdef Float64 mul(self, Float64 other):
874 cdef cfloat.float64_t f = cfloat.f64_mul(self._c_float, other._c_float)
875 return Float64.from_c_float(f)
877 def __mul__(self, Float64 other):
878 return self.mul(other)
880 cpdef Float64 fma(self, Float64 a2, Float64 a3):
881 cdef cfloat.float64_t f = cfloat.f64_mulAdd(self._c_float, a2._c_float, a3._c_float)
882 return Float64.from_c_float(f)
884 cpdef Float64 fam(self, Float64 a1, Float64 a2):
885 cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, self._c_float)
886 return Float64.from_c_float(f)
888 cpdef Float64 div(self, Float64 other):
889 cdef cfloat.float64_t f = cfloat.f64_div(self._c_float, other._c_float)
890 return Float64.from_c_float(f)
892 def __truediv__(self, Float64 other):
893 return self.div(other)
895 cpdef Float64 rem(self, Float64 other):
896 cdef cfloat.float64_t f = cfloat.f64_rem(self._c_float, other._c_float)
897 return Float64.from_c_float(f)
899 cpdef Float64 sqrt(self):
900 cdef cfloat.float64_t f = cfloat.f64_sqrt(self._c_float)
901 return Float64.from_c_float(f)
903 # in-place arithmetic
905 cpdef void ineg(self):
906 self._c_float = _f64_neg(self._c_float)
908 cpdef void iabs(self):
909 self._c_float = _f64_abs(self._c_float)
911 cpdef void iround_to(self, uint_fast8_t rm, bint exact):
912 self._c_float = cfloat.f64_roundToInt(self._c_float, rm, exact)
914 cpdef void iround(self):
915 self._c_float = cfloat.f64_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
917 cpdef void iadd(self, Float64 other):
918 self._c_float = cfloat.f64_add(self._c_float, other._c_float)
920 def __iadd__(self, Float64 other):
924 cpdef void isub(self, Float64 other):
925 self._c_float = cfloat.f64_sub(self._c_float, other._c_float)
927 def __isub__(self, Float64 other):
931 cpdef void imul(self, Float64 other):
932 self._c_float = cfloat.f64_mul(self._c_float, other._c_float)
934 def __imul__(self, Float64 other):
938 cpdef void ifma(self, Float64 a2, Float64 a3):
939 self._c_float = cfloat.f64_mulAdd(self._c_float, a2._c_float, a3._c_float)
941 cpdef void ifam(self, Float64 a1, Float64 a2):
942 self._c_float = cfloat.f64_mulAdd(a1._c_float, a2._c_float, self._c_float)
944 cpdef void idiv(self, Float64 other):
945 self._c_float = cfloat.f64_div(self._c_float, other._c_float)
947 def __itruediv__(self, Float64 other):
951 cpdef void irem(self, Float64 other):
952 self._c_float = cfloat.f64_rem(self._c_float, other._c_float)
954 cpdef void isqrt(self):
955 self._c_float = cfloat.f64_sqrt(self._c_float)
959 cpdef bint eq(self, Float64 other):
960 return cfloat.f64_eq(self._c_float, other._c_float)
962 cpdef bint le(self, Float64 other):
963 return cfloat.f64_le(self._c_float, other._c_float)
965 cpdef bint lt(self, Float64 other):
966 return cfloat.f64_lt(self._c_float, other._c_float)
968 def __lt__(self, Float64 other):
969 return self.lt(other)
971 def __le__(self, Float64 other):
972 return self.le(other)
974 def __eq__(self, Float64 other):
975 return self.eq(other)
977 def __ne__(self, Float64 other):
978 return not self.eq(other)
980 def __ge__(self, Float64 other):
981 return other.le(self)
983 def __gt__(self, Float64 other):
984 return other.lt(self)
986 # conversion to other float types
988 cpdef Float16 to_f16(self):
989 cdef cfloat.float16_t f = cfloat.f64_to_f16(self._c_float)
990 return Float16.from_c_float(f)
992 cpdef Float32 to_f32(self):
993 cdef cfloat.float32_t f = cfloat.f64_to_f32(self._c_float)
994 return Float32.from_c_float(f)
997 # external, non-method arithmetic
999 cpdef Float64 f64_neg(Float64 a1):
1000 cdef cfloat.float64_t f = _f64_neg(a1._c_float)
1001 return Float64.from_c_float(f)
1003 cpdef Float64 f64_abs(Float64 a1):
1004 cdef cfloat.float64_t f = _f64_abs(a1._c_float)
1005 return Float64.from_c_float(f)
1007 cpdef Float64 f64_round_to(Float64 a1, uint_fast8_t rm, bint exact):
1008 cdef cfloat.float64_t f = cfloat.f64_roundToInt(a1._c_float, rm, exact)
1009 return Float64.from_c_float(f)
1011 cpdef Float64 f64_round(Float64 a1):
1012 cdef cfloat.float64_t f = cfloat.f64_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
1013 return Float64.from_c_float(f)
1015 cpdef Float64 f64_add(Float64 a1, Float64 a2):
1016 cdef cfloat.float64_t f = cfloat.f64_add(a1._c_float, a2._c_float)
1017 return Float64.from_c_float(f)
1019 cpdef Float64 f64_sub(Float64 a1, Float64 a2):
1020 cdef cfloat.float64_t f = cfloat.f64_sub(a1._c_float, a2._c_float)
1021 return Float64.from_c_float(f)
1023 cpdef Float64 f64_mul(Float64 a1, Float64 a2):
1024 cdef cfloat.float64_t f = cfloat.f64_mul(a1._c_float, a2._c_float)
1025 return Float64.from_c_float(f)
1027 cpdef Float64 f64_fma(Float64 a1, Float64 a2, Float64 a3):
1028 cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, a3._c_float)
1029 return Float64.from_c_float(f)
1031 cpdef Float64 f64_fam(Float64 a3, Float64 a1, Float64 a2):
1032 cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, a3._c_float)
1033 return Float64.from_c_float(f)
1035 cpdef Float64 f64_div(Float64 a1, Float64 a2):
1036 cdef cfloat.float64_t f = cfloat.f64_div(a1._c_float, a2._c_float)
1037 return Float64.from_c_float(f)
1039 cpdef Float64 f64_rem(Float64 a1, Float64 a2):
1040 cdef cfloat.float64_t f = cfloat.f64_rem(a1._c_float, a2._c_float)
1041 return Float64.from_c_float(f)
1043 cpdef Float64 f64_sqrt(Float64 a1):
1044 cdef cfloat.float64_t f = cfloat.f64_sqrt(a1._c_float)
1045 return Float64.from_c_float(f)
1047 cpdef bint f64_eq(Float64 a1, Float64 a2):
1048 return cfloat.f64_eq(a1._c_float, a2._c_float)
1050 cpdef bint f64_le(Float64 a1, Float64 a2):
1051 return cfloat.f64_le(a1._c_float, a2._c_float)
1053 cpdef bint f64_lt(Float64 a1, Float64 a2):
1054 return cfloat.f64_lt(a1._c_float, a2._c_float)
1056 cpdef Float16 f64_to_f16(Float64 a1):
1057 cdef cfloat.float16_t f = cfloat.f64_to_f16(a1._c_float)
1058 return Float16.from_c_float(f)
1060 cpdef Float32 f64_to_f32(Float64 a1):
1061 cdef cfloat.float32_t f = cfloat.f64_to_f32(a1._c_float)
1062 return Float32.from_c_float(f)