update readme
[sfpy.git] / posit.pyx
1 cimport cposit
2
3 cdef class Posit8:
4
5 # the wrapped posit value
6 cdef cposit.posit8_t _c_posit
7
8 # factory function constructors that bypass __init__
9
10 @staticmethod
11 cdef Posit8 from_c_posit(cposit.posit8_t f):
12 """Factory function to create a Posit8 object directly from
13 a C posit8_t.
14 """
15 cdef Posit8 obj = Posit8.__new__(Posit8)
16 obj._c_posit = f
17 return obj
18
19 @staticmethod
20 def from_bits(int value):
21 """Factory function to create a Posit8 object from a bit pattern
22 represented as an integer.
23 """
24 cdef Posit8 obj = Posit8.__new__(Posit8)
25 obj._c_posit = cposit.castP8(value)
26 return obj
27
28 @staticmethod
29 def from_double(float value):
30 """Factory function to create a Posit8 object from a double.
31 """
32 cdef Posit8 obj = Posit8.__new__(Posit8)
33 obj._c_posit = cposit.convertDoubleToP8(value)
34 return obj
35
36 # convenience interface for use inside Python
37
38 def __init__(self, value):
39 if isinstance(value, int):
40 self._c_posit = cposit.castP8(value)
41 else:
42 f = float(value)
43 self._c_posit = cposit.convertDoubleToP8(f)
44
45 def __str__(self):
46 return repr(cposit.convertP8ToDouble(self._c_posit))
47
48 def __repr__(self):
49 return 'Posit8(' + repr(cposit.convertP8ToDouble(self._c_posit)) + ')'
50
51 cpdef get_bits(self):
52 cdef int u = cposit.castUI8(self._c_posit)
53 return u
54 bits = property(get_bits)
55
56 # arithmetic
57
58 cpdef round(self):
59 cdef cposit.posit8_t f = cposit.p8_roundToInt(self._c_posit)
60 return Posit8.from_c_posit(f)
61
62 def __round__(self, Posit8 other):
63 return self.roundToInt(other)
64
65 cpdef add(self, Posit8 other):
66 cdef cposit.posit8_t f = cposit.p8_add(self._c_posit, other._c_posit)
67 return Posit8.from_c_posit(f)
68
69 def __add__(self, Posit8 other):
70 return self.add(other)
71
72 cpdef sub(self, Posit8 other):
73 cdef cposit.posit8_t f = cposit.p8_sub(self._c_posit, other._c_posit)
74 return Posit8.from_c_posit(f)
75
76 def __sub__(self, Posit8 other):
77 return self.sub(other)
78
79 cpdef mul(self, Posit8 other):
80 cdef cposit.posit8_t f = cposit.p8_mul(self._c_posit, other._c_posit)
81 return Posit8.from_c_posit(f)
82
83 def __mul__(self, Posit8 other):
84 return self.mul(other)
85
86 cpdef fma(self, Posit8 a2, Posit8 a3):
87 cdef cposit.posit8_t f = cposit.p8_mulAdd(self._c_posit, a2._c_posit, a3._c_posit)
88 return Posit8.from_c_posit(f)
89
90 cpdef div(self, Posit8 other):
91 cdef cposit.posit8_t f = cposit.p8_div(self._c_posit, other._c_posit)
92 return Posit8.from_c_posit(f)
93
94 def __truediv__(self, Posit8 other):
95 return self.div(other)
96
97 cpdef sqrt(self):
98 cdef cposit.posit8_t f = cposit.p8_sqrt(self._c_posit)
99 return Posit8.from_c_posit(f)
100
101 # in-place arithmetic
102
103 cpdef iround(self):
104 self._c_posit = cposit.p8_roundToInt(self._c_posit)
105
106 cpdef iadd(self, Posit8 other):
107 self._c_posit = cposit.p8_add(self._c_posit, other._c_posit)
108
109 def __iadd__(self, Posit8 other):
110 self.iadd(other)
111 return self
112
113 cpdef isub(self, Posit8 other):
114 self._c_posit = cposit.p8_sub(self._c_posit, other._c_posit)
115
116 def __isub__(self, Posit8 other):
117 self.isub(other)
118 return self
119
120 cpdef imul(self, Posit8 other):
121 self._c_posit = cposit.p8_mul(self._c_posit, other._c_posit)
122
123 def __imul__(self, Posit8 other):
124 self.imul(other)
125 return self
126
127 cpdef ifma(self, Posit8 a2, Posit8 a3):
128 self._c_posit = cposit.p8_mulAdd(self._c_posit, a2._c_posit, a3._c_posit)
129
130 cpdef idiv(self, Posit8 other):
131 self._c_posit = cposit.p8_div(self._c_posit, other._c_posit)
132
133 def __itruediv__(self, Posit8 other):
134 self.idiv(other)
135 return self
136
137 cpdef isqrt(self):
138 self._c_posit = cposit.p8_sqrt(self._c_posit)
139
140 # comparison
141
142 cpdef eq(self, Posit8 other):
143 cdef bint b = cposit.p8_eq(self._c_posit, other._c_posit)
144 return b
145
146 cpdef le(self, Posit8 other):
147 cdef bint b = cposit.p8_le(self._c_posit, other._c_posit)
148 return b
149
150 cpdef lt(self, Posit8 other):
151 cdef bint b = cposit.p8_lt(self._c_posit, other._c_posit)
152 return b
153
154 def __lt__(self, Posit8 other):
155 return self.lt(other)
156
157 def __le__(self, Posit8 other):
158 return self.le(other)
159
160 def __eq__(self, Posit8 other):
161 return self.eq(other)
162
163 def __ne__(self, Posit8 other):
164 return not self.eq(other)
165
166 def __ge__(self, Posit8 other):
167 return other.le(self)
168
169 def __gt__(self, Posit8 other):
170 return other.lt(self)
171
172 # conversion to other posit types
173
174 cpdef to_p16(self):
175 cdef cposit.posit16_t f = cposit.p8_to_p16(self._c_posit)
176 return Posit16.from_c_posit(f)
177
178
179 cdef class Quire8:
180
181 # the wrapped quire value
182 cdef cposit.quire8_t _c_quire
183
184 # limited interface for now
185
186 def __cinit__(self):
187 cposit.q8_clr(self._c_quire)
188
189 def __str__(self):
190 return repr(cposit.convertP8ToDouble(cposit.q8_to_p8(self._c_quire)))
191
192 def __repr__(self):
193 return 'Quire8(' + repr(cposit.convertP8ToDouble(cposit.q8_to_p8(self._c_quire))) + ')'
194
195 cpdef fdp_add(self, Posit8 a2, Posit8 a3):
196 self._c_quire = cposit.q8_fdp_add(self._c_quire, a2._c_posit, a3._c_posit)
197
198 cpdef fdp_sub(self, Posit8 a2, Posit8 a3):
199 self._c_quire = cposit.q8_fdp_sub(self._c_quire, a2._c_posit, a3._c_posit)
200
201 cpdef get_p8(self):
202 cpdef cposit.posit8_t f = cposit.q8_to_p8(self._c_quire)
203 return Posit8.from_c_posit(f)
204 p8 = property(get_p8)
205
206
207 cdef class Posit16:
208
209 # the wrapped posit value
210 cdef cposit.posit16_t _c_posit
211
212 # factory function constructors that bypass __init__
213
214 @staticmethod
215 cdef Posit16 from_c_posit(cposit.posit16_t f):
216 """Factory function to create a Posit16 object directly from
217 a C posit16_t.
218 """
219 cdef Posit16 obj = Posit16.__new__(Posit16)
220 obj._c_posit = f
221 return obj
222
223 @staticmethod
224 def from_bits(int value):
225 """Factory function to create a Posit16 object from a bit pattern
226 represented as an integer.
227 """
228 cdef Posit16 obj = Posit16.__new__(Posit16)
229 obj._c_posit = cposit.castP16(value)
230 return obj
231
232 @staticmethod
233 def from_double(float value):
234 """Factory function to create a Posit16 object from a double.
235 """
236 cdef Posit16 obj = Posit16.__new__(Posit16)
237 obj._c_posit = cposit.convertDoubleToP16(value)
238 return obj
239
240 # convenience interface for use inside Python
241
242 def __init__(self, value):
243 if isinstance(value, int):
244 self._c_posit = cposit.castP16(value)
245 else:
246 f = float(value)
247 self._c_posit = cposit.convertDoubleToP16(f)
248
249 def __str__(self):
250 return repr(cposit.convertP16ToDouble(self._c_posit))
251
252 def __repr__(self):
253 return 'Posit16(' + repr(cposit.convertP16ToDouble(self._c_posit)) + ')'
254
255 cpdef get_bits(self):
256 cdef int u = cposit.castUI16(self._c_posit)
257 return u
258 bits = property(get_bits)
259
260 # arithmetic
261
262 cpdef round(self):
263 cdef cposit.posit16_t f = cposit.p16_roundToInt(self._c_posit)
264 return Posit16.from_c_posit(f)
265
266 def __round__(self, Posit16 other):
267 return self.roundToInt(other)
268
269 cpdef add(self, Posit16 other):
270 cdef cposit.posit16_t f = cposit.p16_add(self._c_posit, other._c_posit)
271 return Posit16.from_c_posit(f)
272
273 def __add__(self, Posit16 other):
274 return self.add(other)
275
276 cpdef sub(self, Posit16 other):
277 cdef cposit.posit16_t f = cposit.p16_sub(self._c_posit, other._c_posit)
278 return Posit16.from_c_posit(f)
279
280 def __sub__(self, Posit16 other):
281 return self.sub(other)
282
283 cpdef mul(self, Posit16 other):
284 cdef cposit.posit16_t f = cposit.p16_mul(self._c_posit, other._c_posit)
285 return Posit16.from_c_posit(f)
286
287 def __mul__(self, Posit16 other):
288 return self.mul(other)
289
290 cpdef fma(self, Posit16 a2, Posit16 a3):
291 cdef cposit.posit16_t f = cposit.p16_mulAdd(self._c_posit, a2._c_posit, a3._c_posit)
292 return Posit16.from_c_posit(f)
293
294 cpdef div(self, Posit16 other):
295 cdef cposit.posit16_t f = cposit.p16_div(self._c_posit, other._c_posit)
296 return Posit16.from_c_posit(f)
297
298 def __truediv__(self, Posit16 other):
299 return self.div(other)
300
301 cpdef sqrt(self):
302 cdef cposit.posit16_t f = cposit.p16_sqrt(self._c_posit)
303 return Posit16.from_c_posit(f)
304
305 # in-place arithmetic
306
307 cpdef iround(self):
308 self._c_posit = cposit.p16_roundToInt(self._c_posit)
309
310 cpdef iadd(self, Posit16 other):
311 self._c_posit = cposit.p16_add(self._c_posit, other._c_posit)
312
313 def __iadd__(self, Posit16 other):
314 self.iadd(other)
315 return self
316
317 cpdef isub(self, Posit16 other):
318 self._c_posit = cposit.p16_sub(self._c_posit, other._c_posit)
319
320 def __isub__(self, Posit16 other):
321 self.isub(other)
322 return self
323
324 cpdef imul(self, Posit16 other):
325 self._c_posit = cposit.p16_mul(self._c_posit, other._c_posit)
326
327 def __imul__(self, Posit16 other):
328 self.imul(other)
329 return self
330
331 cpdef ifma(self, Posit16 a2, Posit16 a3):
332 self._c_posit = cposit.p16_mulAdd(self._c_posit, a2._c_posit, a3._c_posit)
333
334 cpdef idiv(self, Posit16 other):
335 self._c_posit = cposit.p16_div(self._c_posit, other._c_posit)
336
337 def __itruediv__(self, Posit16 other):
338 self.idiv(other)
339 return self
340
341 cpdef isqrt(self):
342 self._c_posit = cposit.p16_sqrt(self._c_posit)
343
344 # comparison
345
346 cpdef eq(self, Posit16 other):
347 cdef bint b = cposit.p16_eq(self._c_posit, other._c_posit)
348 return b
349
350 cpdef le(self, Posit16 other):
351 cdef bint b = cposit.p16_le(self._c_posit, other._c_posit)
352 return b
353
354 cpdef lt(self, Posit16 other):
355 cdef bint b = cposit.p16_lt(self._c_posit, other._c_posit)
356 return b
357
358 def __lt__(self, Posit16 other):
359 return self.lt(other)
360
361 def __le__(self, Posit16 other):
362 return self.le(other)
363
364 def __eq__(self, Posit16 other):
365 return self.eq(other)
366
367 def __ne__(self, Posit16 other):
368 return not self.eq(other)
369
370 def __ge__(self, Posit16 other):
371 return other.le(self)
372
373 def __gt__(self, Posit16 other):
374 return other.lt(self)
375
376 # conversion to other posit types
377
378 cpdef to_p8(self):
379 cdef cposit.posit8_t f = cposit.p16_to_p8(self._c_posit)
380 return Posit8.from_c_posit(f)
381
382
383 cdef class Quire16:
384
385 # the wrapped quire value
386 cdef cposit.quire16_t _c_quire
387
388 # limited interface for now
389
390 def __cinit__(self):
391 cposit.q16_clr(self._c_quire)
392
393 def __str__(self):
394 return repr(cposit.convertP16ToDouble(cposit.q16_to_p16(self._c_quire)))
395
396 def __repr__(self):
397 return 'Quire16(' + repr(cposit.convertP16ToDouble(cposit.q16_to_p16(self._c_quire))) + ')'
398
399 cpdef fdp_add(self, Posit16 a2, Posit16 a3):
400 self._c_quire = cposit.q16_fdp_add(self._c_quire, a2._c_posit, a3._c_posit)
401
402 cpdef fdp_sub(self, Posit16 a2, Posit16 a3):
403 self._c_quire = cposit.q16_fdp_sub(self._c_quire, a2._c_posit, a3._c_posit)
404
405 cpdef get_p16(self):
406 cpdef cposit.posit16_t f = cposit.q16_to_p16(self._c_quire)
407 return Posit16.from_c_posit(f)
408 p16 = property(get_p16)