--- /dev/null
+from libc.stdint cimport *
+
+# For bitwise conversion between Python floats and the uint containers
+# needed to construct softfloat representations.
+ctypedef union ui64_double:
+ uint64_t u;
+ double d;
+
+cdef extern from '../berkeley-softfloat-3/source/include/softfloat.h':
+
+ # Transparent types so we can have access to the raw bits.
+
+ ctypedef struct float16_t:
+ uint16_t v;
+
+ ctypedef struct float32_t:
+ uint32_t v;
+
+ ctypedef struct float64_t:
+ uint64_t v;
+
+ ctypedef struct float128_t:
+ uint64_t v[2];
+
+ # /*----------------------------------------------------------------------------
+ # | Software floating-point underflow tininess-detection mode.
+ # *----------------------------------------------------------------------------*/
+ # extern uint_fast8_t softfloat_detectTininess; # THREAD_LOCAL
+ # cdef enum:
+ # softfloat_tininess_beforeRounding = 0
+ # softfloat_tininess_afterRounding = 1
+
+ # /*----------------------------------------------------------------------------
+ # | Software floating-point rounding mode. (Mode "odd" is supported only if
+ # | SoftFloat is compiled with macro 'SOFTFLOAT_ROUND_ODD' defined.)
+ # *----------------------------------------------------------------------------*/
+ extern uint_fast8_t softfloat_roundingMode; # THREAD_LOCAL
+ cdef enum:
+ softfloat_round_near_even = 0
+ softfloat_round_minMag = 1
+ softfloat_round_min = 2
+ softfloat_round_max = 3
+ softfloat_round_near_maxMag = 4
+ # softfloat_round_odd = 6
+
+ # /*----------------------------------------------------------------------------
+ # | Software floating-point exception flags.
+ # *----------------------------------------------------------------------------*/
+ extern uint_fast8_t softfloat_exceptionFlags; # THREAD_LOCAL
+ cdef enum:
+ softfloat_flag_inexact = 1
+ softfloat_flag_underflow = 2
+ softfloat_flag_overflow = 4
+ softfloat_flag_infinite = 8
+ softfloat_flag_invalid = 16
+
+ # /*----------------------------------------------------------------------------
+ # | Routine to raise any or all of the software floating-point exception flags.
+ # *----------------------------------------------------------------------------*/
+ void softfloat_raiseFlags( uint_fast8_t );
+
+ # /*----------------------------------------------------------------------------
+ # | Integer-to-floating-point conversion routines.
+ # *----------------------------------------------------------------------------*/
+ float16_t ui32_to_f16( uint32_t );
+ float32_t ui32_to_f32( uint32_t );
+ float64_t ui32_to_f64( uint32_t );
+ # #ifdef SOFTFLOAT_FAST_INT64
+ # extFloat80_t ui32_to_extF80( uint32_t );
+ # float128_t ui32_to_f128( uint32_t );
+ # #endif
+ # void ui32_to_extF80M( uint32_t, extFloat80_t * );
+ # void ui32_to_f128M( uint32_t, float128_t * );
+ float16_t ui64_to_f16( uint64_t );
+ float32_t ui64_to_f32( uint64_t );
+ float64_t ui64_to_f64( uint64_t );
+ # #ifdef SOFTFLOAT_FAST_INT64
+ # extFloat80_t ui64_to_extF80( uint64_t );
+ # float128_t ui64_to_f128( uint64_t );
+ # #endif
+ # void ui64_to_extF80M( uint64_t, extFloat80_t * );
+ # void ui64_to_f128M( uint64_t, float128_t * );
+ float16_t i32_to_f16( int32_t );
+ float32_t i32_to_f32( int32_t );
+ float64_t i32_to_f64( int32_t );
+ # #ifdef SOFTFLOAT_FAST_INT64
+ # extFloat80_t i32_to_extF80( int32_t );
+ # float128_t i32_to_f128( int32_t );
+ # #endif
+ # void i32_to_extF80M( int32_t, extFloat80_t * );
+ # void i32_to_f128M( int32_t, float128_t * );
+ float16_t i64_to_f16( int64_t );
+ float32_t i64_to_f32( int64_t );
+ float64_t i64_to_f64( int64_t );
+ # #ifdef SOFTFLOAT_FAST_INT64
+ # extFloat80_t i64_to_extF80( int64_t );
+ # float128_t i64_to_f128( int64_t );
+ # #endif
+ # void i64_to_extF80M( int64_t, extFloat80_t * );
+ # void i64_to_f128M( int64_t, float128_t * );
+
+ # /*----------------------------------------------------------------------------
+ # | 16-bit (half-precision) floating-point operations.
+ # *----------------------------------------------------------------------------*/
+ uint_fast32_t f16_to_ui32( float16_t, uint_fast8_t, bint );
+ uint_fast64_t f16_to_ui64( float16_t, uint_fast8_t, bint );
+ int_fast32_t f16_to_i32( float16_t, uint_fast8_t, bint );
+ int_fast64_t f16_to_i64( float16_t, uint_fast8_t, bint );
+ uint_fast32_t f16_to_ui32_r_minMag( float16_t, bint );
+ uint_fast64_t f16_to_ui64_r_minMag( float16_t, bint );
+ int_fast32_t f16_to_i32_r_minMag( float16_t, bint );
+ int_fast64_t f16_to_i64_r_minMag( float16_t, bint );
+ float32_t f16_to_f32( float16_t );
+ float64_t f16_to_f64( float16_t );
+ # #ifdef SOFTFLOAT_FAST_INT64
+ # extFloat80_t f16_to_extF80( float16_t );
+ # float128_t f16_to_f128( float16_t );
+ # #endif
+ # void f16_to_extF80M( float16_t, extFloat80_t * );
+ # void f16_to_f128M( float16_t, float128_t * );
+ float16_t f16_roundToInt( float16_t, uint_fast8_t, bint );
+ float16_t f16_add( float16_t, float16_t );
+ float16_t f16_sub( float16_t, float16_t );
+ float16_t f16_mul( float16_t, float16_t );
+ float16_t f16_mulAdd( float16_t, float16_t, float16_t );
+ float16_t f16_div( float16_t, float16_t );
+ float16_t f16_rem( float16_t, float16_t );
+ float16_t f16_sqrt( float16_t );
+ bint f16_eq( float16_t, float16_t );
+ bint f16_le( float16_t, float16_t );
+ bint f16_lt( float16_t, float16_t );
+ bint f16_eq_signaling( float16_t, float16_t );
+ bint f16_le_quiet( float16_t, float16_t );
+ bint f16_lt_quiet( float16_t, float16_t );
+ bint f16_isSignalingNaN( float16_t );
+
+ # /*----------------------------------------------------------------------------
+ # | 32-bit (single-precision) floating-point operations.
+ # *----------------------------------------------------------------------------*/
+ uint_fast32_t f32_to_ui32( float32_t, uint_fast8_t, bint );
+ uint_fast64_t f32_to_ui64( float32_t, uint_fast8_t, bint );
+ int_fast32_t f32_to_i32( float32_t, uint_fast8_t, bint );
+ int_fast64_t f32_to_i64( float32_t, uint_fast8_t, bint );
+ uint_fast32_t f32_to_ui32_r_minMag( float32_t, bint );
+ uint_fast64_t f32_to_ui64_r_minMag( float32_t, bint );
+ int_fast32_t f32_to_i32_r_minMag( float32_t, bint );
+ int_fast64_t f32_to_i64_r_minMag( float32_t, bint );
+ float16_t f32_to_f16( float32_t );
+ float64_t f32_to_f64( float32_t );
+ # #ifdef SOFTFLOAT_FAST_INT64
+ # extFloat80_t f32_to_extF80( float32_t );
+ # float128_t f32_to_f128( float32_t );
+ # #endif
+ # void f32_to_extF80M( float32_t, extFloat80_t * );
+ # void f32_to_f128M( float32_t, float128_t * );
+ float32_t f32_roundToInt( float32_t, uint_fast8_t, bint );
+ float32_t f32_add( float32_t, float32_t );
+ float32_t f32_sub( float32_t, float32_t );
+ float32_t f32_mul( float32_t, float32_t );
+ float32_t f32_mulAdd( float32_t, float32_t, float32_t );
+ float32_t f32_div( float32_t, float32_t );
+ float32_t f32_rem( float32_t, float32_t );
+ float32_t f32_sqrt( float32_t );
+ bint f32_eq( float32_t, float32_t );
+ bint f32_le( float32_t, float32_t );
+ bint f32_lt( float32_t, float32_t );
+ bint f32_eq_signaling( float32_t, float32_t );
+ bint f32_le_quiet( float32_t, float32_t );
+ bint f32_lt_quiet( float32_t, float32_t );
+ bint f32_isSignalingNaN( float32_t );
+
+ # /*----------------------------------------------------------------------------
+ # | 64-bit (double-precision) floating-point operations.
+ # *----------------------------------------------------------------------------*/
+ uint_fast32_t f64_to_ui32( float64_t, uint_fast8_t, bint );
+ uint_fast64_t f64_to_ui64( float64_t, uint_fast8_t, bint );
+ int_fast32_t f64_to_i32( float64_t, uint_fast8_t, bint );
+ int_fast64_t f64_to_i64( float64_t, uint_fast8_t, bint );
+ uint_fast32_t f64_to_ui32_r_minMag( float64_t, bint );
+ uint_fast64_t f64_to_ui64_r_minMag( float64_t, bint );
+ int_fast32_t f64_to_i32_r_minMag( float64_t, bint );
+ int_fast64_t f64_to_i64_r_minMag( float64_t, bint );
+ float16_t f64_to_f16( float64_t );
+ float32_t f64_to_f32( float64_t );
+ # #ifdef SOFTFLOAT_FAST_INT64
+ # extFloat80_t f64_to_extF80( float64_t );
+ # float128_t f64_to_f128( float64_t );
+ # #endif
+ # void f64_to_extF80M( float64_t, extFloat80_t * );
+ # void f64_to_f128M( float64_t, float128_t * );
+ float64_t f64_roundToInt( float64_t, uint_fast8_t, bint );
+ float64_t f64_add( float64_t, float64_t );
+ float64_t f64_sub( float64_t, float64_t );
+ float64_t f64_mul( float64_t, float64_t );
+ float64_t f64_mulAdd( float64_t, float64_t, float64_t );
+ float64_t f64_div( float64_t, float64_t );
+ float64_t f64_rem( float64_t, float64_t );
+ float64_t f64_sqrt( float64_t );
+ bint f64_eq( float64_t, float64_t );
+ bint f64_le( float64_t, float64_t );
+ bint f64_lt( float64_t, float64_t );
+ bint f64_eq_signaling( float64_t, float64_t );
+ bint f64_le_quiet( float64_t, float64_t );
+ bint f64_lt_quiet( float64_t, float64_t );
+ bint f64_isSignalingNaN( float64_t );
+
+ # /*----------------------------------------------------------------------------
+ # | Rounding precision for 80-bit extended double-precision floating-point.
+ # | Valid values are 32, 64, and 80.
+ # *----------------------------------------------------------------------------*/
+ # extern THREAD_LOCAL uint_fast8_t extF80_roundingPrecision;
+
+ # /*----------------------------------------------------------------------------
+ # | 80-bit extended double-precision floating-point operations.
+ # *----------------------------------------------------------------------------*/
+ # #ifdef SOFTFLOAT_FAST_INT64
+ # uint_fast32_t extF80_to_ui32( extFloat80_t, uint_fast8_t, bint );
+ # uint_fast64_t extF80_to_ui64( extFloat80_t, uint_fast8_t, bint );
+ # int_fast32_t extF80_to_i32( extFloat80_t, uint_fast8_t, bint );
+ # int_fast64_t extF80_to_i64( extFloat80_t, uint_fast8_t, bint );
+ # uint_fast32_t extF80_to_ui32_r_minMag( extFloat80_t, bint );
+ # uint_fast64_t extF80_to_ui64_r_minMag( extFloat80_t, bint );
+ # int_fast32_t extF80_to_i32_r_minMag( extFloat80_t, bint );
+ # int_fast64_t extF80_to_i64_r_minMag( extFloat80_t, bint );
+ # float16_t extF80_to_f16( extFloat80_t );
+ # float32_t extF80_to_f32( extFloat80_t );
+ # float64_t extF80_to_f64( extFloat80_t );
+ # float128_t extF80_to_f128( extFloat80_t );
+ # extFloat80_t extF80_roundToInt( extFloat80_t, uint_fast8_t, bint );
+ # extFloat80_t extF80_add( extFloat80_t, extFloat80_t );
+ # extFloat80_t extF80_sub( extFloat80_t, extFloat80_t );
+ # extFloat80_t extF80_mul( extFloat80_t, extFloat80_t );
+ # extFloat80_t extF80_div( extFloat80_t, extFloat80_t );
+ # extFloat80_t extF80_rem( extFloat80_t, extFloat80_t );
+ # extFloat80_t extF80_sqrt( extFloat80_t );
+ # bint extF80_eq( extFloat80_t, extFloat80_t );
+ # bint extF80_le( extFloat80_t, extFloat80_t );
+ # bint extF80_lt( extFloat80_t, extFloat80_t );
+ # bint extF80_eq_signaling( extFloat80_t, extFloat80_t );
+ # bint extF80_le_quiet( extFloat80_t, extFloat80_t );
+ # bint extF80_lt_quiet( extFloat80_t, extFloat80_t );
+ # bint extF80_isSignalingNaN( extFloat80_t );
+ # #endif
+ # uint_fast32_t extF80M_to_ui32( const extFloat80_t *, uint_fast8_t, bint );
+ # uint_fast64_t extF80M_to_ui64( const extFloat80_t *, uint_fast8_t, bint );
+ # int_fast32_t extF80M_to_i32( const extFloat80_t *, uint_fast8_t, bint );
+ # int_fast64_t extF80M_to_i64( const extFloat80_t *, uint_fast8_t, bint );
+ # uint_fast32_t extF80M_to_ui32_r_minMag( const extFloat80_t *, bint );
+ # uint_fast64_t extF80M_to_ui64_r_minMag( const extFloat80_t *, bint );
+ # int_fast32_t extF80M_to_i32_r_minMag( const extFloat80_t *, bint );
+ # int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *, bint );
+ # float16_t extF80M_to_f16( const extFloat80_t * );
+ # float32_t extF80M_to_f32( const extFloat80_t * );
+ # float64_t extF80M_to_f64( const extFloat80_t * );
+ # void extF80M_to_f128M( const extFloat80_t *, float128_t * );
+ # void
+ # extF80M_roundToInt(
+ # const extFloat80_t *, uint_fast8_t, bint, extFloat80_t * );
+ # void extF80M_add( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
+ # void extF80M_sub( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
+ # void extF80M_mul( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
+ # void extF80M_div( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
+ # void extF80M_rem( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
+ # void extF80M_sqrt( const extFloat80_t *, extFloat80_t * );
+ # bint extF80M_eq( const extFloat80_t *, const extFloat80_t * );
+ # bint extF80M_le( const extFloat80_t *, const extFloat80_t * );
+ # bint extF80M_lt( const extFloat80_t *, const extFloat80_t * );
+ # bint extF80M_eq_signaling( const extFloat80_t *, const extFloat80_t * );
+ # bint extF80M_le_quiet( const extFloat80_t *, const extFloat80_t * );
+ # bint extF80M_lt_quiet( const extFloat80_t *, const extFloat80_t * );
+ # bint extF80M_isSignalingNaN( const extFloat80_t * );
+
+ # /*----------------------------------------------------------------------------
+ # | 128-bit (quadruple-precision) floating-point operations.
+ # *----------------------------------------------------------------------------*/
+ # #ifdef SOFTFLOAT_FAST_INT64
+ # uint_fast32_t f128_to_ui32( float128_t, uint_fast8_t, bint );
+ # uint_fast64_t f128_to_ui64( float128_t, uint_fast8_t, bint );
+ # int_fast32_t f128_to_i32( float128_t, uint_fast8_t, bint );
+ # int_fast64_t f128_to_i64( float128_t, uint_fast8_t, bint );
+ # uint_fast32_t f128_to_ui32_r_minMag( float128_t, bint );
+ # uint_fast64_t f128_to_ui64_r_minMag( float128_t, bint );
+ # int_fast32_t f128_to_i32_r_minMag( float128_t, bint );
+ # int_fast64_t f128_to_i64_r_minMag( float128_t, bint );
+ # float16_t f128_to_f16( float128_t );
+ # float32_t f128_to_f32( float128_t );
+ # float64_t f128_to_f64( float128_t );
+ # extFloat80_t f128_to_extF80( float128_t );
+ # float128_t f128_roundToInt( float128_t, uint_fast8_t, bint );
+ # float128_t f128_add( float128_t, float128_t );
+ # float128_t f128_sub( float128_t, float128_t );
+ # float128_t f128_mul( float128_t, float128_t );
+ # float128_t f128_mulAdd( float128_t, float128_t, float128_t );
+ # float128_t f128_div( float128_t, float128_t );
+ # float128_t f128_rem( float128_t, float128_t );
+ # float128_t f128_sqrt( float128_t );
+ # bint f128_eq( float128_t, float128_t );
+ # bint f128_le( float128_t, float128_t );
+ # bint f128_lt( float128_t, float128_t );
+ # bint f128_eq_signaling( float128_t, float128_t );
+ # bint f128_le_quiet( float128_t, float128_t );
+ # bint f128_lt_quiet( float128_t, float128_t );
+ # bint f128_isSignalingNaN( float128_t );
+ # #endif
+ # uint_fast32_t f128M_to_ui32( const float128_t *, uint_fast8_t, bint );
+ # uint_fast64_t f128M_to_ui64( const float128_t *, uint_fast8_t, bint );
+ # int_fast32_t f128M_to_i32( const float128_t *, uint_fast8_t, bint );
+ # int_fast64_t f128M_to_i64( const float128_t *, uint_fast8_t, bint );
+ # uint_fast32_t f128M_to_ui32_r_minMag( const float128_t *, bint );
+ # uint_fast64_t f128M_to_ui64_r_minMag( const float128_t *, bint );
+ # int_fast32_t f128M_to_i32_r_minMag( const float128_t *, bint );
+ # int_fast64_t f128M_to_i64_r_minMag( const float128_t *, bint );
+ # float16_t f128M_to_f16( const float128_t * );
+ # float32_t f128M_to_f32( const float128_t * );
+ # float64_t f128M_to_f64( const float128_t * );
+ # void f128M_to_extF80M( const float128_t *, extFloat80_t * );
+ # void f128M_roundToInt( const float128_t *, uint_fast8_t, bint, float128_t * );
+ # void f128M_add( const float128_t *, const float128_t *, float128_t * );
+ # void f128M_sub( const float128_t *, const float128_t *, float128_t * );
+ # void f128M_mul( const float128_t *, const float128_t *, float128_t * );
+ # void
+ # f128M_mulAdd(
+ # const float128_t *, const float128_t *, const float128_t *, float128_t *
+ # );
+ # void f128M_div( const float128_t *, const float128_t *, float128_t * );
+ # void f128M_rem( const float128_t *, const float128_t *, float128_t * );
+ # void f128M_sqrt( const float128_t *, float128_t * );
+ # bint f128M_eq( const float128_t *, const float128_t * );
+ # bint f128M_le( const float128_t *, const float128_t * );
+ # bint f128M_lt( const float128_t *, const float128_t * );
+ # bint f128M_eq_signaling( const float128_t *, const float128_t * );
+ # bint f128M_le_quiet( const float128_t *, const float128_t * );
+ # bint f128M_lt_quiet( const float128_t *, const float128_t * );
+ # bint f128M_isSignalingNaN( const float128_t * );
--- /dev/null
+from libc.stdint cimport *
+cimport cfloat
+
+
+# low-level access to rounding modes
+
+ROUND_NEAREST_EVEN = cfloat.softfloat_round_near_even
+ROUND_TO_ZERO = cfloat.softfloat_round_minMag
+ROUND_DOWN = cfloat.softfloat_round_min
+ROUND_UP = cfloat.softfloat_round_max
+ROUND_NEAREST_AWAY = cfloat.softfloat_round_near_maxMag
+
+cpdef uint_fast8_t round_get_mode():
+ return cfloat.softfloat_roundingMode
+
+cpdef void round_set_mode(uint_fast8_t mode):
+ cfloat.softfloat_roundingMode = mode
+
+cpdef bint round_is_nearest_even():
+ return cfloat.softfloat_roundingMode == cfloat.softfloat_round_near_even
+
+cpdef void round_set_nearest_even():
+ cfloat.softfloat_roundingMode = cfloat.softfloat_round_near_even
+
+cpdef bint round_is_to_zero():
+ return cfloat.softfloat_roundingMode == cfloat.softfloat_round_minMag
+
+cpdef void round_set_to_zero():
+ cfloat.softfloat_roundingMode = cfloat.softfloat_round_minMag
+
+cpdef bint round_is_down():
+ return cfloat.softfloat_roundingMode == cfloat.softfloat_round_min
+
+cpdef void round_set_down():
+ cfloat.softfloat_roundingMode = cfloat.softfloat_round_min
+
+cpdef bint round_is_up():
+ return cfloat.softfloat_roundingMode == cfloat.softfloat_round_max
+
+cpdef void round_set_up():
+ cfloat.softfloat_roundingMode = cfloat.softfloat_round_max
+
+cpdef bint round_is_nearest_away():
+ return cfloat.softfloat_roundingMode == cfloat.softfloat_round_near_maxMag
+
+cpdef void round_set_nearest_away():
+ cfloat.softfloat_roundingMode = cfloat.softfloat_round_near_maxMag
+
+
+# low-level access to exception flags
+
+FLAG_INEXACT = cfloat.softfloat_flag_inexact
+FLAG_UNDERFLOW = cfloat.softfloat_flag_underflow
+FLAG_OVERFLOW = cfloat.softfloat_flag_overflow
+FLAG_INFINITE = cfloat.softfloat_flag_infinite
+FLAG_INVALID = cfloat.softfloat_flag_invalid
+
+cpdef uint_fast8_t flag_get():
+ return cfloat.softfloat_exceptionFlags
+
+cpdef void flag_set(uint_fast8_t flags):
+ cfloat.softfloat_exceptionFlags = flags
+
+cpdef void flag_reset():
+ cfloat.softfloat_exceptionFlags = 0
+
+cpdef bint flag_get_inexact():
+ return (cfloat.softfloat_exceptionFlags & cfloat.softfloat_flag_inexact) != 0
+
+cpdef void flag_raise_inexact():
+ cfloat.softfloat_raiseFlags(cfloat.softfloat_flag_inexact)
+
+cpdef void flag_clear_inexact():
+ cfloat.softfloat_exceptionFlags &= ~cfloat.softfloat_flag_inexact
+
+cpdef bint flag_get_underflow():
+ return (cfloat.softfloat_exceptionFlags & cfloat.softfloat_flag_underflow) != 0
+
+cpdef void flag_raise_underflow():
+ cfloat.softfloat_raiseFlags(cfloat.softfloat_flag_underflow)
+
+cpdef void flag_clear_underflow():
+ cfloat.softfloat_exceptionFlags &= ~cfloat.softfloat_flag_underflow
+
+cpdef bint flag_get_overflow():
+ return (cfloat.softfloat_exceptionFlags & cfloat.softfloat_flag_overflow) != 0
+
+cpdef void flag_raise_overflow():
+ cfloat.softfloat_raiseFlags(cfloat.softfloat_flag_overflow)
+
+cpdef void flag_clear_overflow():
+ cfloat.softfloat_exceptionFlags &= ~cfloat.softfloat_flag_overflow
+
+cpdef bint flag_get_infinite():
+ return (cfloat.softfloat_exceptionFlags & cfloat.softfloat_flag_infinite) != 0
+
+cpdef void flag_raise_infinite():
+ cfloat.softfloat_raiseFlags(cfloat.softfloat_flag_infinite)
+
+cpdef void flag_clear_infinite():
+ cfloat.softfloat_exceptionFlags &= ~cfloat.softfloat_flag_infinite
+
+cpdef bint flag_get_invalid():
+ return (cfloat.softfloat_exceptionFlags & cfloat.softfloat_flag_invalid) != 0
+
+cpdef void flag_raise_invalid():
+ cfloat.softfloat_raiseFlags(cfloat.softfloat_flag_invalid)
+
+cpdef void flag_clear_invalid():
+ cfloat.softfloat_exceptionFlags &= ~cfloat.softfloat_flag_invalid
+
+
+cdef class Float16:
+
+ # the wrapped float value
+ cdef cfloat.float16_t _c_float
+
+ # factory function constructors that bypass __init__
+
+ @staticmethod
+ cdef Float16 from_c_float(cfloat.float16_t f):
+ """Factory function to create a Float16 object directly from
+ a C float16_t.
+ """
+ cdef Float16 obj = Float16.__new__(Float16)
+ obj._c_float = f
+ return obj
+
+ @staticmethod
+ def from_bits(uint16_t value):
+ """Factory function to create a Float16 object from a bit pattern
+ represented as an integer.
+ """
+ cdef Float16 obj = Float16.__new__(Float16)
+ obj._c_float.v = value
+ return obj
+
+ @staticmethod
+ def from_double(double value):
+ """Factory function to create a Float16 object from a double.
+ """
+ cdef Float16 obj = Float16.__new__(Float16)
+ cdef cfloat.ui64_double ud
+ cdef cfloat.float64_t d
+
+ ud.d = value
+ d.v = ud.u
+ obj._c_float = cfloat.f64_to_f16(d)
+
+ return obj
+
+ # convenience interface for use inside Python
+
+ def __init__(self, value):
+ cdef cfloat.ui64_double ud
+ cdef cfloat.float64_t d
+
+ if isinstance(value, int):
+ self._c_float.v = value
+ else:
+ ud.d = float(value)
+ d.v = ud.u
+ self._c_float = cfloat.f64_to_f16(d)
+
+ def __float__(self):
+ cdef cfloat.ui64_double ud
+ ud.u = cfloat.f16_to_f64(self._c_float).v
+ return ud.d
+
+ def __int__(self):
+ cdef cfloat.ui64_double ud
+ ud.u = cfloat.f16_to_f64(self._c_float).v
+ return int(ud.d)
+
+ def __str__(self):
+ cdef cfloat.ui64_double ud
+ ud.u = cfloat.f16_to_f64(self._c_float).v
+ return repr(ud.d)
+
+ def __repr__(self):
+ cdef cfloat.ui64_double ud
+ ud.u = cfloat.f16_to_f64(self._c_float).v
+ return 'Float16(' + repr(ud.d) + ')'
+
+ cpdef uint16_t get_bits(self):
+ return self._c_float.v
+ bits = property(get_bits)
+
+ # arithmetic
+
+ cpdef Float16 round_to(self, uint_fast8_t rm, bint exact):
+ cdef cfloat.float16_t f = cfloat.f16_roundToInt(self._c_float, rm, exact)
+ return Float16.from_c_float(f)
+
+ cpdef Float16 round(self):
+ cdef cfloat.float16_t f = cfloat.f16_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
+ return Float16.from_c_float(f)
+
+ def __round__(self):
+ return self.round()
+
+ cpdef Float16 add(self, Float16 other):
+ cdef cfloat.float16_t f = cfloat.f16_add(self._c_float, other._c_float)
+ return Float16.from_c_float(f)
+
+ def __add__(self, Float16 other):
+ return self.add(other)
+
+ cpdef Float16 sub(self, Float16 other):
+ cdef cfloat.float16_t f = cfloat.f16_sub(self._c_float, other._c_float)
+ return Float16.from_c_float(f)
+
+ def __sub__(self, Float16 other):
+ return self.sub(other)
+
+ cpdef Float16 mul(self, Float16 other):
+ cdef cfloat.float16_t f = cfloat.f16_mul(self._c_float, other._c_float)
+ return Float16.from_c_float(f)
+
+ def __mul__(self, Float16 other):
+ return self.mul(other)
+
+ cpdef Float16 fma(self, Float16 a2, Float16 a3):
+ cdef cfloat.float16_t f = cfloat.f16_mulAdd(self._c_float, a2._c_float, a3._c_float)
+ return Float16.from_c_float(f)
+
+ cpdef Float16 qma(self, Float16 a1, Float16 a2):
+ cdef cfloat.float16_t f = cfloat.f16_mulAdd(a1._c_float, a2._c_float, self._c_float)
+ return Float16.from_c_float(f)
+
+ cpdef Float16 div(self, Float16 other):
+ cdef cfloat.float16_t f = cfloat.f16_div(self._c_float, other._c_float)
+ return Float16.from_c_float(f)
+
+ def __truediv__(self, Float16 other):
+ return self.div(other)
+
+ cpdef Float16 rem(self, Float16 other):
+ cdef cfloat.float16_t f = cfloat.f16_rem(self._c_float, other._c_float)
+ return Float16.from_c_float(f)
+
+ cpdef Float16 sqrt(self):
+ cdef cfloat.float16_t f = cfloat.f16_sqrt(self._c_float)
+ return Float16.from_c_float(f)
+
+ # in-place arithmetic
+
+ cpdef void iround_to(self, uint_fast8_t rm, bint exact):
+ self._c_float = cfloat.f16_roundToInt(self._c_float, rm, exact)
+
+ cpdef void iround(self):
+ self._c_float = cfloat.f16_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
+
+ cpdef void iadd(self, Float16 other):
+ self._c_float = cfloat.f16_add(self._c_float, other._c_float)
+
+ def __iadd__(self, Float16 other):
+ self.iadd(other)
+ return self
+
+ cpdef void isub(self, Float16 other):
+ self._c_float = cfloat.f16_sub(self._c_float, other._c_float)
+
+ def __isub__(self, Float16 other):
+ self.isub(other)
+ return self
+
+ cpdef void imul(self, Float16 other):
+ self._c_float = cfloat.f16_mul(self._c_float, other._c_float)
+
+ def __imul__(self, Float16 other):
+ self.imul(other)
+ return self
+
+ cpdef void ifma(self, Float16 a2, Float16 a3):
+ self._c_float = cfloat.f16_mulAdd(self._c_float, a2._c_float, a3._c_float)
+
+ cpdef void iqma(self, Float16 a1, Float16 a2):
+ self._c_float = cfloat.f16_mulAdd(a1._c_float, a2._c_float, self._c_float)
+
+ cpdef void idiv(self, Float16 other):
+ self._c_float = cfloat.f16_div(self._c_float, other._c_float)
+
+ def __itruediv__(self, Float16 other):
+ self.idiv(other)
+ return self
+
+ cpdef void irem(self, Float16 other):
+ self._c_float = cfloat.f16_rem(self._c_float, other._c_float)
+
+ cpdef void isqrt(self):
+ self._c_float = cfloat.f16_sqrt(self._c_float)
+
+ # comparison
+
+ cpdef bint eq(self, Float16 other):
+ return cfloat.f16_eq(self._c_float, other._c_float)
+
+ cpdef bint le(self, Float16 other):
+ return cfloat.f16_le(self._c_float, other._c_float)
+
+ cpdef bint lt(self, Float16 other):
+ return cfloat.f16_lt(self._c_float, other._c_float)
+
+ def __lt__(self, Float16 other):
+ return self.lt(other)
+
+ def __le__(self, Float16 other):
+ return self.le(other)
+
+ def __eq__(self, Float16 other):
+ return self.eq(other)
+
+ def __ne__(self, Float16 other):
+ return not self.eq(other)
+
+ def __ge__(self, Float16 other):
+ return other.le(self)
+
+ def __gt__(self, Float16 other):
+ return other.lt(self)
+
+ # conversion to other float types
+
+ cpdef Float32 to_f32(self):
+ cdef cfloat.float32_t f = cfloat.f16_to_f32(self._c_float)
+ return Float32.from_c_float(f)
+
+ cpdef Float64 to_f64(self):
+ cdef cfloat.float64_t f = cfloat.f16_to_f64(self._c_float)
+ return Float64.from_c_float(f)
+
+
+# external, non-method arithmetic
+
+cpdef Float16 f16_round_to(Float16 a1, uint_fast8_t rm, bint exact):
+ cdef cfloat.float16_t f = cfloat.f16_roundToInt(a1._c_float, rm, exact)
+ return Float16.from_c_float(f)
+
+cpdef Float16 f16_round(Float16 a1):
+ cdef cfloat.float16_t f = cfloat.f16_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
+ return Float16.from_c_float(f)
+
+cpdef Float16 f16_add(Float16 a1, Float16 a2):
+ cdef cfloat.float16_t f = cfloat.f16_add(a1._c_float, a2._c_float)
+ return Float16.from_c_float(f)
+
+cpdef Float16 f16_sub(Float16 a1, Float16 a2):
+ cdef cfloat.float16_t f = cfloat.f16_sub(a1._c_float, a2._c_float)
+ return Float16.from_c_float(f)
+
+cpdef Float16 f16_mul(Float16 a1, Float16 a2):
+ cdef cfloat.float16_t f = cfloat.f16_mul(a1._c_float, a2._c_float)
+ return Float16.from_c_float(f)
+
+cpdef Float16 f16_fma(Float16 a1, Float16 a2, Float16 a3):
+ cdef cfloat.float16_t f = cfloat.f16_mulAdd(a1._c_float, a2._c_float, a3._c_float)
+ return Float16.from_c_float(f)
+
+cpdef Float16 f16_qma(Float16 a3, Float16 a1, Float16 a2):
+ cdef cfloat.float16_t f = cfloat.f16_mulAdd(a1._c_float, a2._c_float, a3._c_float)
+ return Float16.from_c_float(f)
+
+cpdef Float16 f16_div(Float16 a1, Float16 a2):
+ cdef cfloat.float16_t f = cfloat.f16_div(a1._c_float, a2._c_float)
+ return Float16.from_c_float(f)
+
+cpdef Float16 f16_rem(Float16 a1, Float16 a2):
+ cdef cfloat.float16_t f = cfloat.f16_rem(a1._c_float, a2._c_float)
+ return Float16.from_c_float(f)
+
+cpdef Float16 f16_sqrt(Float16 a1):
+ cdef cfloat.float16_t f = cfloat.f16_sqrt(a1._c_float)
+ return Float16.from_c_float(f)
+
+cpdef bint f16_eq(Float16 a1, Float16 a2):
+ return cfloat.f16_eq(a1._c_float, a2._c_float)
+
+cpdef bint f16_le(Float16 a1, Float16 a2):
+ return cfloat.f16_le(a1._c_float, a2._c_float)
+
+cpdef bint f16_lt(Float16 a1, Float16 a2):
+ return cfloat.f16_lt(a1._c_float, a2._c_float)
+
+cpdef Float32 f16_to_f32(Float16 a1):
+ cdef cfloat.float32_t f = cfloat.f16_to_f32(a1._c_float)
+ return Float32.from_c_float(f)
+
+cpdef Float64 f16_to_f64(Float16 a1):
+ cdef cfloat.float64_t f = cfloat.f16_to_f64(a1._c_float)
+ return Float64.from_c_float(f)
+
+
+cdef class Float32:
+
+ # the wrapped float value
+ cdef cfloat.float32_t _c_float
+
+ # factory function constructors that bypass __init__
+
+ @staticmethod
+ cdef Float32 from_c_float(cfloat.float32_t f):
+ """Factory function to create a Float32 object directly from
+ a C float32_t.
+ """
+ cdef Float32 obj = Float32.__new__(Float32)
+ obj._c_float = f
+ return obj
+
+ @staticmethod
+ def from_bits(uint32_t value):
+ """Factory function to create a Float32 object from a bit pattern
+ represented as an integer.
+ """
+ cdef Float32 obj = Float32.__new__(Float32)
+ obj._c_float.v = value
+ return obj
+
+ @staticmethod
+ def from_double(double value):
+ """Factory function to create a Float32 object from a double.
+ """
+ cdef Float32 obj = Float32.__new__(Float32)
+ cdef cfloat.ui64_double ud
+ cdef cfloat.float64_t d
+
+ ud.d = value
+ d.v = ud.u
+ obj._c_float = cfloat.f64_to_f32(d)
+
+ return obj
+
+ # convenience interface for use inside Python
+
+ def __init__(self, value):
+ cdef cfloat.ui64_double ud
+ cdef cfloat.float64_t d
+
+ if isinstance(value, int):
+ self._c_float.v = value
+ else:
+ ud.d = float(value)
+ d.v = ud.u
+ self._c_float = cfloat.f64_to_f32(d)
+
+ def __float__(self):
+ cdef cfloat.ui64_double ud
+ ud.u = cfloat.f32_to_f64(self._c_float).v
+ return ud.d
+
+ def __int__(self):
+ cdef cfloat.ui64_double ud
+ ud.u = cfloat.f32_to_f64(self._c_float).v
+ return int(ud.d)
+
+ def __str__(self):
+ cdef cfloat.ui64_double ud
+ ud.u = cfloat.f32_to_f64(self._c_float).v
+ return repr(ud.d)
+
+ def __repr__(self):
+ cdef cfloat.ui64_double ud
+ ud.u = cfloat.f32_to_f64(self._c_float).v
+ return 'Float32(' + repr(ud.d) + ')'
+
+ cpdef uint32_t get_bits(self):
+ return self._c_float.v
+ bits = property(get_bits)
+
+ # arithmetic
+
+ cpdef Float32 round_to(self, uint_fast8_t rm, bint exact):
+ cdef cfloat.float32_t f = cfloat.f32_roundToInt(self._c_float, rm, exact)
+ return Float32.from_c_float(f)
+
+ cpdef Float32 round(self):
+ cdef cfloat.float32_t f = cfloat.f32_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
+ return Float32.from_c_float(f)
+
+ def __round__(self):
+ return self.round()
+
+ cpdef Float32 add(self, Float32 other):
+ cdef cfloat.float32_t f = cfloat.f32_add(self._c_float, other._c_float)
+ return Float32.from_c_float(f)
+
+ def __add__(self, Float32 other):
+ return self.add(other)
+
+ cpdef Float32 sub(self, Float32 other):
+ cdef cfloat.float32_t f = cfloat.f32_sub(self._c_float, other._c_float)
+ return Float32.from_c_float(f)
+
+ def __sub__(self, Float32 other):
+ return self.sub(other)
+
+ cpdef Float32 mul(self, Float32 other):
+ cdef cfloat.float32_t f = cfloat.f32_mul(self._c_float, other._c_float)
+ return Float32.from_c_float(f)
+
+ def __mul__(self, Float32 other):
+ return self.mul(other)
+
+ cpdef Float32 fma(self, Float32 a2, Float32 a3):
+ cdef cfloat.float32_t f = cfloat.f32_mulAdd(self._c_float, a2._c_float, a3._c_float)
+ return Float32.from_c_float(f)
+
+ cpdef Float32 qma(self, Float32 a1, Float32 a2):
+ cdef cfloat.float32_t f = cfloat.f32_mulAdd(a1._c_float, a2._c_float, self._c_float)
+ return Float32.from_c_float(f)
+
+ cpdef Float32 div(self, Float32 other):
+ cdef cfloat.float32_t f = cfloat.f32_div(self._c_float, other._c_float)
+ return Float32.from_c_float(f)
+
+ def __truediv__(self, Float32 other):
+ return self.div(other)
+
+ cpdef Float32 rem(self, Float32 other):
+ cdef cfloat.float32_t f = cfloat.f32_rem(self._c_float, other._c_float)
+ return Float32.from_c_float(f)
+
+ cpdef Float32 sqrt(self):
+ cdef cfloat.float32_t f = cfloat.f32_sqrt(self._c_float)
+ return Float32.from_c_float(f)
+
+ # in-place arithmetic
+
+ cpdef void iround_to(self, uint_fast8_t rm, bint exact):
+ self._c_float = cfloat.f32_roundToInt(self._c_float, rm, exact)
+
+ cpdef void iround(self):
+ self._c_float = cfloat.f32_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
+
+ cpdef void iadd(self, Float32 other):
+ self._c_float = cfloat.f32_add(self._c_float, other._c_float)
+
+ def __iadd__(self, Float32 other):
+ self.iadd(other)
+ return self
+
+ cpdef void isub(self, Float32 other):
+ self._c_float = cfloat.f32_sub(self._c_float, other._c_float)
+
+ def __isub__(self, Float32 other):
+ self.isub(other)
+ return self
+
+ cpdef void imul(self, Float32 other):
+ self._c_float = cfloat.f32_mul(self._c_float, other._c_float)
+
+ def __imul__(self, Float32 other):
+ self.imul(other)
+ return self
+
+ cpdef void ifma(self, Float32 a2, Float32 a3):
+ self._c_float = cfloat.f32_mulAdd(self._c_float, a2._c_float, a3._c_float)
+
+ cpdef void iqma(self, Float32 a1, Float32 a2):
+ self._c_float = cfloat.f32_mulAdd(a1._c_float, a2._c_float, self._c_float)
+
+ cpdef void idiv(self, Float32 other):
+ self._c_float = cfloat.f32_div(self._c_float, other._c_float)
+
+ def __itruediv__(self, Float32 other):
+ self.idiv(other)
+ return self
+
+ cpdef void irem(self, Float32 other):
+ self._c_float = cfloat.f32_rem(self._c_float, other._c_float)
+
+ cpdef void isqrt(self):
+ self._c_float = cfloat.f32_sqrt(self._c_float)
+
+ # comparison
+
+ cpdef bint eq(self, Float32 other):
+ return cfloat.f32_eq(self._c_float, other._c_float)
+
+ cpdef bint le(self, Float32 other):
+ return cfloat.f32_le(self._c_float, other._c_float)
+
+ cpdef bint lt(self, Float32 other):
+ return cfloat.f32_lt(self._c_float, other._c_float)
+
+ def __lt__(self, Float32 other):
+ return self.lt(other)
+
+ def __le__(self, Float32 other):
+ return self.le(other)
+
+ def __eq__(self, Float32 other):
+ return self.eq(other)
+
+ def __ne__(self, Float32 other):
+ return not self.eq(other)
+
+ def __ge__(self, Float32 other):
+ return other.le(self)
+
+ def __gt__(self, Float32 other):
+ return other.lt(self)
+
+ # conversion to other float types
+
+ cpdef Float16 to_f16(self):
+ cdef cfloat.float16_t f = cfloat.f32_to_f16(self._c_float)
+ return Float16.from_c_float(f)
+
+ cpdef Float64 to_f64(self):
+ cdef cfloat.float64_t f = cfloat.f32_to_f64(self._c_float)
+ return Float64.from_c_float(f)
+
+
+# external, non-method arithmetic
+
+cpdef Float32 f32_round_to(Float32 a1, uint_fast8_t rm, bint exact):
+ cdef cfloat.float32_t f = cfloat.f32_roundToInt(a1._c_float, rm, exact)
+ return Float32.from_c_float(f)
+
+cpdef Float32 f32_round(Float32 a1):
+ cdef cfloat.float32_t f = cfloat.f32_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
+ return Float32.from_c_float(f)
+
+cpdef Float32 f32_add(Float32 a1, Float32 a2):
+ cdef cfloat.float32_t f = cfloat.f32_add(a1._c_float, a2._c_float)
+ return Float32.from_c_float(f)
+
+cpdef Float32 f32_sub(Float32 a1, Float32 a2):
+ cdef cfloat.float32_t f = cfloat.f32_sub(a1._c_float, a2._c_float)
+ return Float32.from_c_float(f)
+
+cpdef Float32 f32_mul(Float32 a1, Float32 a2):
+ cdef cfloat.float32_t f = cfloat.f32_mul(a1._c_float, a2._c_float)
+ return Float32.from_c_float(f)
+
+cpdef Float32 f32_fma(Float32 a1, Float32 a2, Float32 a3):
+ cdef cfloat.float32_t f = cfloat.f32_mulAdd(a1._c_float, a2._c_float, a3._c_float)
+ return Float32.from_c_float(f)
+
+cpdef Float32 f32_qma(Float32 a3, Float32 a1, Float32 a2):
+ cdef cfloat.float32_t f = cfloat.f32_mulAdd(a1._c_float, a2._c_float, a3._c_float)
+ return Float32.from_c_float(f)
+
+cpdef Float32 f32_div(Float32 a1, Float32 a2):
+ cdef cfloat.float32_t f = cfloat.f32_div(a1._c_float, a2._c_float)
+ return Float32.from_c_float(f)
+
+cpdef Float32 f32_rem(Float32 a1, Float32 a2):
+ cdef cfloat.float32_t f = cfloat.f32_rem(a1._c_float, a2._c_float)
+ return Float32.from_c_float(f)
+
+cpdef Float32 f32_sqrt(Float32 a1):
+ cdef cfloat.float32_t f = cfloat.f32_sqrt(a1._c_float)
+ return Float32.from_c_float(f)
+
+cpdef bint f32_eq(Float32 a1, Float32 a2):
+ return cfloat.f32_eq(a1._c_float, a2._c_float)
+
+cpdef bint f32_le(Float32 a1, Float32 a2):
+ return cfloat.f32_le(a1._c_float, a2._c_float)
+
+cpdef bint f32_lt(Float32 a1, Float32 a2):
+ return cfloat.f32_lt(a1._c_float, a2._c_float)
+
+cpdef Float16 f32_to_f16(Float32 a1):
+ cdef cfloat.float16_t f = cfloat.f32_to_f16(a1._c_float)
+ return Float16.from_c_float(f)
+
+cpdef Float64 f32_to_f64(Float32 a1):
+ cdef cfloat.float64_t f = cfloat.f32_to_f64(a1._c_float)
+ return Float64.from_c_float(f)
+
+
+cdef class Float64:
+
+ # the wrapped float value
+ cdef cfloat.float64_t _c_float
+
+ # factory function constructors that bypass __init__
+
+ @staticmethod
+ cdef Float64 from_c_float(cfloat.float64_t f):
+ """Factory function to create a Float64 object directly from
+ a C float64_t.
+ """
+ cdef Float64 obj = Float64.__new__(Float64)
+ obj._c_float = f
+ return obj
+
+ @staticmethod
+ def from_bits(uint64_t value):
+ """Factory function to create a Float64 object from a bit pattern
+ represented as an integer.
+ """
+ cdef Float64 obj = Float64.__new__(Float64)
+ obj._c_float.v = value
+ return obj
+
+ @staticmethod
+ def from_double(double value):
+ """Factory function to create a Float64 object from a double.
+ """
+ cdef Float64 obj = Float64.__new__(Float64)
+ cdef cfloat.ui64_double ud
+ cdef cfloat.float64_t d
+
+ ud.d = value
+ obj._c_float.v = ud.u
+
+ return obj
+
+ # convenience interface for use inside Python
+
+ def __init__(self, value):
+ cdef cfloat.ui64_double ud
+ cdef cfloat.float64_t d
+
+ if isinstance(value, int):
+ self._c_float.v = value
+ else:
+ ud.d = float(value)
+ self._c_float.v = ud.u
+
+ def __float__(self):
+ cdef cfloat.ui64_double ud
+ ud.u = self._c_float.v
+ return ud.d
+
+ def __int__(self):
+ cdef cfloat.ui64_double ud
+ ud.u = self._c_float.v
+ return int(ud.d)
+
+ def __str__(self):
+ cdef cfloat.ui64_double ud
+ ud.u = self._c_float.v
+ return repr(ud.d)
+
+ def __repr__(self):
+ cdef cfloat.ui64_double ud
+ ud.u = self._c_float.v
+ return 'Float64(' + repr(ud.d) + ')'
+
+ cpdef uint64_t get_bits(self):
+ return self._c_float.v
+ bits = property(get_bits)
+
+ # arithmetic
+
+ cpdef Float64 round_to(self, uint_fast8_t rm, bint exact):
+ cdef cfloat.float64_t f = cfloat.f64_roundToInt(self._c_float, rm, exact)
+ return Float64.from_c_float(f)
+
+ cpdef Float64 round(self):
+ cdef cfloat.float64_t f = cfloat.f64_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
+ return Float64.from_c_float(f)
+
+ def __round__(self):
+ return self.round()
+
+ cpdef Float64 add(self, Float64 other):
+ cdef cfloat.float64_t f = cfloat.f64_add(self._c_float, other._c_float)
+ return Float64.from_c_float(f)
+
+ def __add__(self, Float64 other):
+ return self.add(other)
+
+ cpdef Float64 sub(self, Float64 other):
+ cdef cfloat.float64_t f = cfloat.f64_sub(self._c_float, other._c_float)
+ return Float64.from_c_float(f)
+
+ def __sub__(self, Float64 other):
+ return self.sub(other)
+
+ cpdef Float64 mul(self, Float64 other):
+ cdef cfloat.float64_t f = cfloat.f64_mul(self._c_float, other._c_float)
+ return Float64.from_c_float(f)
+
+ def __mul__(self, Float64 other):
+ return self.mul(other)
+
+ cpdef Float64 fma(self, Float64 a2, Float64 a3):
+ cdef cfloat.float64_t f = cfloat.f64_mulAdd(self._c_float, a2._c_float, a3._c_float)
+ return Float64.from_c_float(f)
+
+ cpdef Float64 qma(self, Float64 a1, Float64 a2):
+ cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, self._c_float)
+ return Float64.from_c_float(f)
+
+ cpdef Float64 div(self, Float64 other):
+ cdef cfloat.float64_t f = cfloat.f64_div(self._c_float, other._c_float)
+ return Float64.from_c_float(f)
+
+ def __truediv__(self, Float64 other):
+ return self.div(other)
+
+ cpdef Float64 rem(self, Float64 other):
+ cdef cfloat.float64_t f = cfloat.f64_rem(self._c_float, other._c_float)
+ return Float64.from_c_float(f)
+
+ cpdef Float64 sqrt(self):
+ cdef cfloat.float64_t f = cfloat.f64_sqrt(self._c_float)
+ return Float64.from_c_float(f)
+
+ # in-place arithmetic
+
+ cpdef void iround_to(self, uint_fast8_t rm, bint exact):
+ self._c_float = cfloat.f64_roundToInt(self._c_float, rm, exact)
+
+ cpdef void iround(self):
+ self._c_float = cfloat.f64_roundToInt(self._c_float, cfloat.softfloat_roundingMode, True)
+
+ cpdef void iadd(self, Float64 other):
+ self._c_float = cfloat.f64_add(self._c_float, other._c_float)
+
+ def __iadd__(self, Float64 other):
+ self.iadd(other)
+ return self
+
+ cpdef void isub(self, Float64 other):
+ self._c_float = cfloat.f64_sub(self._c_float, other._c_float)
+
+ def __isub__(self, Float64 other):
+ self.isub(other)
+ return self
+
+ cpdef void imul(self, Float64 other):
+ self._c_float = cfloat.f64_mul(self._c_float, other._c_float)
+
+ def __imul__(self, Float64 other):
+ self.imul(other)
+ return self
+
+ cpdef void ifma(self, Float64 a2, Float64 a3):
+ self._c_float = cfloat.f64_mulAdd(self._c_float, a2._c_float, a3._c_float)
+
+ cpdef void iqma(self, Float64 a1, Float64 a2):
+ self._c_float = cfloat.f64_mulAdd(a1._c_float, a2._c_float, self._c_float)
+
+ cpdef void idiv(self, Float64 other):
+ self._c_float = cfloat.f64_div(self._c_float, other._c_float)
+
+ def __itruediv__(self, Float64 other):
+ self.idiv(other)
+ return self
+
+ cpdef void irem(self, Float64 other):
+ self._c_float = cfloat.f64_rem(self._c_float, other._c_float)
+
+ cpdef void isqrt(self):
+ self._c_float = cfloat.f64_sqrt(self._c_float)
+
+ # comparison
+
+ cpdef bint eq(self, Float64 other):
+ return cfloat.f64_eq(self._c_float, other._c_float)
+
+ cpdef bint le(self, Float64 other):
+ return cfloat.f64_le(self._c_float, other._c_float)
+
+ cpdef bint lt(self, Float64 other):
+ return cfloat.f64_lt(self._c_float, other._c_float)
+
+ def __lt__(self, Float64 other):
+ return self.lt(other)
+
+ def __le__(self, Float64 other):
+ return self.le(other)
+
+ def __eq__(self, Float64 other):
+ return self.eq(other)
+
+ def __ne__(self, Float64 other):
+ return not self.eq(other)
+
+ def __ge__(self, Float64 other):
+ return other.le(self)
+
+ def __gt__(self, Float64 other):
+ return other.lt(self)
+
+ # conversion to other float types
+
+ cpdef Float16 to_f16(self):
+ cdef cfloat.float16_t f = cfloat.f64_to_f16(self._c_float)
+ return Float16.from_c_float(f)
+
+ cpdef Float32 to_f32(self):
+ cdef cfloat.float32_t f = cfloat.f64_to_f32(self._c_float)
+ return Float32.from_c_float(f)
+
+
+# external, non-method arithmetic
+
+cpdef Float64 f64_round_to(Float64 a1, uint_fast8_t rm, bint exact):
+ cdef cfloat.float64_t f = cfloat.f64_roundToInt(a1._c_float, rm, exact)
+ return Float64.from_c_float(f)
+
+cpdef Float64 f64_round(Float64 a1):
+ cdef cfloat.float64_t f = cfloat.f64_roundToInt(a1._c_float, cfloat.softfloat_roundingMode, True)
+ return Float64.from_c_float(f)
+
+cpdef Float64 f64_add(Float64 a1, Float64 a2):
+ cdef cfloat.float64_t f = cfloat.f64_add(a1._c_float, a2._c_float)
+ return Float64.from_c_float(f)
+
+cpdef Float64 f64_sub(Float64 a1, Float64 a2):
+ cdef cfloat.float64_t f = cfloat.f64_sub(a1._c_float, a2._c_float)
+ return Float64.from_c_float(f)
+
+cpdef Float64 f64_mul(Float64 a1, Float64 a2):
+ cdef cfloat.float64_t f = cfloat.f64_mul(a1._c_float, a2._c_float)
+ return Float64.from_c_float(f)
+
+cpdef Float64 f64_fma(Float64 a1, Float64 a2, Float64 a3):
+ cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, a3._c_float)
+ return Float64.from_c_float(f)
+
+cpdef Float64 f64_qma(Float64 a3, Float64 a1, Float64 a2):
+ cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, a3._c_float)
+ return Float64.from_c_float(f)
+
+cpdef Float64 f64_div(Float64 a1, Float64 a2):
+ cdef cfloat.float64_t f = cfloat.f64_div(a1._c_float, a2._c_float)
+ return Float64.from_c_float(f)
+
+cpdef Float64 f64_rem(Float64 a1, Float64 a2):
+ cdef cfloat.float64_t f = cfloat.f64_rem(a1._c_float, a2._c_float)
+ return Float64.from_c_float(f)
+
+cpdef Float64 f64_sqrt(Float64 a1):
+ cdef cfloat.float64_t f = cfloat.f64_sqrt(a1._c_float)
+ return Float64.from_c_float(f)
+
+cpdef bint f64_eq(Float64 a1, Float64 a2):
+ return cfloat.f64_eq(a1._c_float, a2._c_float)
+
+cpdef bint f64_le(Float64 a1, Float64 a2):
+ return cfloat.f64_le(a1._c_float, a2._c_float)
+
+cpdef bint f64_lt(Float64 a1, Float64 a2):
+ return cfloat.f64_lt(a1._c_float, a2._c_float)
+
+cpdef Float16 f64_to_f16(Float64 a1):
+ cdef cfloat.float16_t f = cfloat.f64_to_f16(a1._c_float)
+ return Float16.from_c_float(f)
+
+cpdef Float32 f64_to_f32(Float64 a1):
+ cdef cfloat.float32_t f = cfloat.f64_to_f32(a1._c_float)
+ return Float32.from_c_float(f)