From: Bill Zorn Date: Tue, 7 Aug 2018 06:27:26 +0000 (-0700) Subject: add negation and absolute value X-Git-Url: https://git.libre-soc.org/?p=sfpy.git;a=commitdiff_plain;h=a618f0d9e48e2704db12f780847e8399a91d49d9 add negation and absolute value --- diff --git a/sfpy/float.pyx b/sfpy/float.pyx index d25a6da..968323f 100644 --- a/sfpy/float.pyx +++ b/sfpy/float.pyx @@ -110,6 +110,33 @@ cpdef void flag_clear_invalid(): 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 @@ -188,6 +215,20 @@ cdef class Float16: # 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) @@ -245,6 +286,12 @@ cdef class Float16: # 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) @@ -333,6 +380,14 @@ cdef class Float16: # 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) @@ -469,6 +524,20 @@ cdef class Float32: # 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) @@ -526,6 +595,12 @@ cdef class Float32: # 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) @@ -614,6 +689,14 @@ cdef class Float32: # 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) @@ -748,6 +831,20 @@ cdef class Float64: # 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) @@ -805,6 +902,12 @@ cdef class Float64: # 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) @@ -893,6 +996,14 @@ cdef class Float64: # 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) diff --git a/sfpy/posit.pyx b/sfpy/posit.pyx index 7816613..83e79b9 100644 --- a/sfpy/posit.pyx +++ b/sfpy/posit.pyx @@ -2,10 +2,26 @@ from libc.stdint cimport * cimport cposit -# special values needed for some initializations +# special values and C helpers -cdef posit8_one = cposit.ui32_to_p8(1) -cdef posit16_one = cposit.ui32_to_p16(1) +cdef _p8_one = cposit.ui32_to_p8(1) +cdef _p16_one = cposit.ui32_to_p16(1) + +cdef inline cposit.posit8_t _p8_neg(cposit.posit8_t f): + f.v = -f.v + return f + +cdef inline cposit.posit16_t _p16_neg(cposit.posit16_t f): + f.v = -f.v + return f + +cdef inline cposit.posit8_t _p8_abs(cposit.posit8_t f): + f.v = abs( f.v) + return f + +cdef inline cposit.posit16_t _p16_abs(cposit.posit16_t f): + f.v = abs( f.v) + return f cdef class Posit8: @@ -68,6 +84,20 @@ cdef class Posit8: # arithmetic + cpdef Posit8 neg(self): + cdef cposit.posit8_t f = _p8_neg(self._c_posit) + return Posit8.from_c_posit(f) + + def __neg__(self): + return self.neg() + + cpdef Posit8 abs(self): + cdef cposit.posit8_t f = _p8_abs(self._c_posit) + return Posit8.from_c_posit(f) + + def __abs__(self): + return self.abs() + cpdef Posit8 round(self): cdef cposit.posit8_t f = cposit.p8_roundToInt(self._c_posit) return Posit8.from_c_posit(f) @@ -117,6 +147,12 @@ cdef class Posit8: # in-place arithmetic + cpdef void ineg(self): + self._c_posit = _p8_neg(self._c_posit) + + cpdef void iabs(self): + self._c_posit = _p8_abs(self._c_posit) + cpdef void iround(self): self._c_posit = cposit.p8_roundToInt(self._c_posit) @@ -195,7 +231,7 @@ cdef class Posit8: cpdef to_quire(self): cdef cposit.quire8_t f cposit.q8_clr(f) - f = cposit.q8_fdp_add(f, self._c_posit, posit8_one) + f = cposit.q8_fdp_add(f, self._c_posit, _p8_one) return Quire8.from_c_quire(f) @@ -232,7 +268,7 @@ cdef class Quire8: else: f = float(value) cposit.q8_clr(self._c_quire) - self._c_quire = cposit.q8_fdp_add(self._c_quire, cposit.convertDoubleToP8(f), posit8_one) + self._c_quire = cposit.q8_fdp_add(self._c_quire, cposit.convertDoubleToP8(f), _p8_one) def __float__(self): return cposit.convertP8ToDouble(cposit.q8_to_p8(self._c_quire)) @@ -278,6 +314,14 @@ cdef class Quire8: # external, non-method arithmetic +cpdef Posit8 p8_neg(Posit8 a1): + cdef cposit.posit8_t f = _p8_neg(a1._c_posit) + return Posit8.from_c_posit(f) + +cpdef Posit8 p8_abs(Posit8 a1): + cdef cposit.posit8_t f = _p8_abs(a1._c_posit) + return Posit8.from_c_posit(f) + cpdef Posit8 p8_round(Posit8 a1): cdef cposit.posit8_t f = cposit.p8_roundToInt(a1._c_posit) return Posit8.from_c_posit(f) @@ -326,7 +370,7 @@ cpdef Posit16 p8_to_p16(Posit8 a1): cpdef Quire8 p8_to_q8(Posit8 a1): cdef cposit.quire8_t f cposit.q8_clr(f) - f = cposit.q8_fdp_add(f, a1._c_posit, posit8_one) + f = cposit.q8_fdp_add(f, a1._c_posit, _p8_one) return Quire8.from_c_quire(f) cpdef Quire8 q8_qam(Quire8 a3, Posit8 a1, Posit8 a2): @@ -402,6 +446,20 @@ cdef class Posit16: # arithmetic + cpdef Posit16 neg(self): + cdef cposit.posit16_t f = _p16_neg(self._c_posit) + return Posit16.from_c_posit(f) + + def __neg__(self): + return self.neg() + + cpdef Posit16 abs(self): + cdef cposit.posit16_t f = _p16_abs(self._c_posit) + return Posit16.from_c_posit(f) + + def __abs__(self): + return self.abs() + cpdef Posit16 round(self): cdef cposit.posit16_t f = cposit.p16_roundToInt(self._c_posit) return Posit16.from_c_posit(f) @@ -451,6 +509,12 @@ cdef class Posit16: # in-place arithmetic + cpdef void ineg(self): + self._c_posit = _p16_neg(self._c_posit) + + cpdef void iabs(self): + self._c_posit = _p16_abs(self._c_posit) + cpdef void iround(self): self._c_posit = cposit.p16_roundToInt(self._c_posit) @@ -529,7 +593,7 @@ cdef class Posit16: cpdef to_quire(self): cdef cposit.quire16_t f cposit.q16_clr(f) - f = cposit.q16_fdp_add(f, self._c_posit, posit16_one) + f = cposit.q16_fdp_add(f, self._c_posit, _p16_one) return Quire16.from_c_quire(f) @@ -580,7 +644,7 @@ cdef class Quire16: else: f = float(value) cposit.q16_clr(self._c_quire) - self._c_quire = cposit.q16_fdp_add(self._c_quire, cposit.convertDoubleToP16(f), posit16_one) + self._c_quire = cposit.q16_fdp_add(self._c_quire, cposit.convertDoubleToP16(f), _p16_one) def __float__(self): return cposit.convertP16ToDouble(cposit.q16_to_p16(self._c_quire)) @@ -630,6 +694,14 @@ cdef class Quire16: # external, non-method arithmetic +cpdef Posit16 p16_neg(Posit16 a1): + cdef cposit.posit16_t f = _p16_neg(a1._c_posit) + return Posit16.from_c_posit(f) + +cpdef Posit16 p16_abs(Posit16 a1): + cdef cposit.posit16_t f = _p16_abs(a1._c_posit) + return Posit16.from_c_posit(f) + cpdef Posit16 p16_round(Posit16 a1): cdef cposit.posit16_t f = cposit.p16_roundToInt(a1._c_posit) return Posit16.from_c_posit(f) @@ -678,7 +750,7 @@ cpdef Posit8 p16_to_p8(Posit16 a1): cpdef Quire16 p16_to_q16(Posit16 a1): cdef cposit.quire16_t f cposit.q16_clr(f) - f = cposit.q16_fdp_add(f, a1._c_posit, posit16_one) + f = cposit.q16_fdp_add(f, a1._c_posit, _p16_one) return Quire16.from_c_quire(f) cpdef Quire16 q16_qam(Quire16 a3, Posit16 a1, Posit16 a2):