cfloat.softfloat_exceptionFlags &= ~cfloat.softfloat_flag_invalid
+# C helpers
+
+cdef inline cfloat.float16_t _f16_neg(cfloat.float16_t f):
+ f.v ^= 0x8000
+ return f
+
+cdef inline cfloat.float32_t _f32_neg(cfloat.float32_t f):
+ f.v ^= 0x80000000
+ return f
+
+cdef inline cfloat.float64_t _f64_neg(cfloat.float64_t f):
+ f.v ^= 0x8000000000000000
+ return f
+
+cdef inline cfloat.float16_t _f16_abs(cfloat.float16_t f):
+ f.v &= 0x7fff
+ return f
+
+cdef inline cfloat.float32_t _f32_abs(cfloat.float32_t f):
+ f.v &= 0x7fffffff
+ return f
+
+cdef inline cfloat.float64_t _f64_abs(cfloat.float64_t f):
+ f.v &= 0x7fffffffffffffff
+ return f
+
+
cdef class Float16:
# the wrapped float value
# convenience interface for use inside Python
def __init__(self, value):
+ """Given an int, create a Float16 from the bitpattern represented by
+ that int. Otherwise, given some value, create a Float16 by rounding
+ float(value).
+ """
cdef cfloat.ui64_double ud
cdef cfloat.float64_t d
# arithmetic
+ cpdef Float16 neg(self):
+ cdef cfloat.float16_t f = _f16_neg(self._c_float)
+ return Float16.from_c_float(f)
+
+ def __neg__(self):
+ return self.neg()
+
+ cpdef Float16 abs(self):
+ cdef cfloat.float16_t f = _f16_abs(self._c_float)
+ return Float16.from_c_float(f)
+
+ def __abs__(self):
+ return self.abs()
+
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)
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):
+ cpdef Float16 fma(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)
# in-place arithmetic
+ cpdef void ineg(self):
+ self._c_float = _f16_neg(self._c_float)
+
+ cpdef void iabs(self):
+ self._c_float = _f16_abs(self._c_float)
+
cpdef void iround_to(self, uint_fast8_t rm, bint exact):
self._c_float = cfloat.f16_roundToInt(self._c_float, rm, exact)
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):
+ cpdef void ifma(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):
# external, non-method arithmetic
+cpdef Float16 f16_neg(Float16 a1):
+ cdef cfloat.float16_t f = _f16_neg(a1._c_float)
+ return Float16.from_c_float(f)
+
+cpdef Float16 f16_abs(Float16 a1):
+ cdef cfloat.float16_t f = _f16_abs(a1._c_float)
+ return Float16.from_c_float(f)
+
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)
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)
+cpdef Float16 f16_fma(Float16 acc, Float16 a1, Float16 a2):
+ cdef cfloat.float16_t f = cfloat.f16_mulAdd(a1._c_float, a2._c_float, acc._c_float)
return Float16.from_c_float(f)
cpdef Float16 f16_div(Float16 a1, Float16 a2):
# convenience interface for use inside Python
def __init__(self, value):
+ """Given an int, create a Float32 from the bitpattern represented by
+ that int. Otherwise, given some value, create a Float32 by rounding
+ float(value).
+ """
cdef cfloat.ui64_double ud
cdef cfloat.float64_t d
# arithmetic
+ cpdef Float32 neg(self):
+ cdef cfloat.float32_t f = _f32_neg(self._c_float)
+ return Float32.from_c_float(f)
+
+ def __neg__(self):
+ return self.neg()
+
+ cpdef Float32 abs(self):
+ cdef cfloat.float32_t f = _f32_abs(self._c_float)
+ return Float32.from_c_float(f)
+
+ def __abs__(self):
+ return self.abs()
+
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)
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):
+ cpdef Float32 fma(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)
# in-place arithmetic
+ cpdef void ineg(self):
+ self._c_float = _f32_neg(self._c_float)
+
+ cpdef void iabs(self):
+ self._c_float = _f32_abs(self._c_float)
+
cpdef void iround_to(self, uint_fast8_t rm, bint exact):
self._c_float = cfloat.f32_roundToInt(self._c_float, rm, exact)
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):
+ cpdef void ifma(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):
# external, non-method arithmetic
+cpdef Float32 f32_neg(Float32 a1):
+ cdef cfloat.float32_t f = _f32_neg(a1._c_float)
+ return Float32.from_c_float(f)
+
+cpdef Float32 f32_abs(Float32 a1):
+ cdef cfloat.float32_t f = _f32_abs(a1._c_float)
+ return Float32.from_c_float(f)
+
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)
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)
+cpdef Float32 f32_fma(Float32 acc, Float32 a1, Float32 a2):
+ cdef cfloat.float32_t f = cfloat.f32_mulAdd(a1._c_float, a2._c_float, acc._c_float)
return Float32.from_c_float(f)
cpdef Float32 f32_div(Float32 a1, Float32 a2):
# convenience interface for use inside Python
def __init__(self, value):
+ """Given an int, create a Float64 from the bitpattern represented by
+ that int. Otherwise, given some value, create a Float64 from
+ float(value).
+ """
cdef cfloat.ui64_double ud
cdef cfloat.float64_t d
# arithmetic
+ cpdef Float64 neg(self):
+ cdef cfloat.float64_t f = _f64_neg(self._c_float)
+ return Float64.from_c_float(f)
+
+ def __neg__(self):
+ return self.neg()
+
+ cpdef Float64 abs(self):
+ cdef cfloat.float64_t f = _f64_abs(self._c_float)
+ return Float64.from_c_float(f)
+
+ def __abs__(self):
+ return self.abs()
+
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)
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):
+ cpdef Float64 fma(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)
# in-place arithmetic
+ cpdef void ineg(self):
+ self._c_float = _f64_neg(self._c_float)
+
+ cpdef void iabs(self):
+ self._c_float = _f64_abs(self._c_float)
+
cpdef void iround_to(self, uint_fast8_t rm, bint exact):
self._c_float = cfloat.f64_roundToInt(self._c_float, rm, exact)
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):
+ cpdef void ifma(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):
# external, non-method arithmetic
+cpdef Float64 f64_neg(Float64 a1):
+ cdef cfloat.float64_t f = _f64_neg(a1._c_float)
+ return Float64.from_c_float(f)
+
+cpdef Float64 f64_abs(Float64 a1):
+ cdef cfloat.float64_t f = _f64_abs(a1._c_float)
+ return Float64.from_c_float(f)
+
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)
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)
+cpdef Float64 f64_fma(Float64 acc, Float64 a1, Float64 a2):
+ cdef cfloat.float64_t f = cfloat.f64_mulAdd(a1._c_float, a2._c_float, acc._c_float)
return Float64.from_c_float(f)
cpdef Float64 f64_div(Float64 a1, Float64 a2):