don't use quire clear macros, hopefully for windows compatibility
[sfpy.git] / sfpy / posit.pyx
1 from libc.stdint cimport *
2 cimport cposit
3
4
5 # special values and C helpers
6
7 cdef _p8_one = cposit.ui32_to_p8(1)
8 cdef _p16_one = cposit.ui32_to_p16(1)
9 cdef _p32_one = cposit.ui32_to_p32(1)
10
11 cdef inline cposit.posit8_t _p8_neg(cposit.posit8_t f):
12 f.v = -f.v
13 return f
14
15 cdef inline cposit.posit16_t _p16_neg(cposit.posit16_t f):
16 f.v = -f.v
17 return f
18
19 cdef inline cposit.posit32_t _p32_neg(cposit.posit32_t f):
20 f.v = -f.v
21 return f
22
23 cdef inline cposit.posit8_t _p8_abs(cposit.posit8_t f):
24 f.v = <uint8_t> abs(<int8_t> f.v)
25 return f
26
27 cdef inline cposit.posit16_t _p16_abs(cposit.posit16_t f):
28 f.v = <uint16_t> abs(<int16_t> f.v)
29 return f
30
31 cdef inline cposit.posit32_t _p32_abs(cposit.posit32_t f):
32 f.v = <uint32_t> abs(<int32_t> f.v)
33 return f
34
35
36 cdef class Posit8:
37
38 # the wrapped posit value
39 cdef cposit.posit8_t _c_posit
40
41 # factory function constructors that bypass __init__
42
43 @staticmethod
44 cdef Posit8 from_c_posit(cposit.posit8_t f):
45 """Factory function to create a Posit8 object directly from
46 a C posit8_t.
47 """
48 cdef Posit8 obj = Posit8.__new__(Posit8)
49 obj._c_posit = f
50 return obj
51
52 @staticmethod
53 def from_bits(uint8_t value):
54 """Factory function to create a Posit8 object from a bit pattern
55 represented as an integer.
56 """
57 cdef Posit8 obj = Posit8.__new__(Posit8)
58 obj._c_posit.v = value
59 return obj
60
61 @staticmethod
62 def from_double(double value):
63 """Factory function to create a Posit8 object from a double.
64 """
65 cdef Posit8 obj = Posit8.__new__(Posit8)
66 obj._c_posit = cposit.convertDoubleToP8(value)
67 return obj
68
69 # convenience interface for use inside Python
70
71 def __init__(self, value):
72 """Given an int, create a Posit8 from the bitpattern represented by
73 that int. Otherwise, given some value, create a Posit8 by rounding
74 float(value).
75 """
76 if isinstance(value, int):
77 self._c_posit.v = value
78 else:
79 f = float(value)
80 self._c_posit = cposit.convertDoubleToP8(f)
81
82 def __float__(self):
83 return cposit.convertP8ToDouble(self._c_posit)
84
85 def __int__(self):
86 return int(cposit.convertP8ToDouble(self._c_posit))
87
88 def __str__(self):
89 return repr(cposit.convertP8ToDouble(self._c_posit))
90
91 def __repr__(self):
92 return 'Posit8(' + repr(cposit.convertP8ToDouble(self._c_posit)) + ')'
93
94 cpdef uint8_t get_bits(self):
95 return self._c_posit.v
96 bits = property(get_bits)
97
98 # arithmetic
99
100 cpdef Posit8 neg(self):
101 cdef cposit.posit8_t f = _p8_neg(self._c_posit)
102 return Posit8.from_c_posit(f)
103
104 def __neg__(self):
105 return self.neg()
106
107 cpdef Posit8 abs(self):
108 cdef cposit.posit8_t f = _p8_abs(self._c_posit)
109 return Posit8.from_c_posit(f)
110
111 def __abs__(self):
112 return self.abs()
113
114 cpdef Posit8 round(self):
115 cdef cposit.posit8_t f = cposit.p8_roundToInt(self._c_posit)
116 return Posit8.from_c_posit(f)
117
118 def __round__(self):
119 return self.round()
120
121 cpdef Posit8 add(self, Posit8 other):
122 cdef cposit.posit8_t f = cposit.p8_add(self._c_posit, other._c_posit)
123 return Posit8.from_c_posit(f)
124
125 def __add__(self, Posit8 other):
126 return self.add(other)
127
128 cpdef Posit8 sub(self, Posit8 other):
129 cdef cposit.posit8_t f = cposit.p8_sub(self._c_posit, other._c_posit)
130 return Posit8.from_c_posit(f)
131
132 def __sub__(self, Posit8 other):
133 return self.sub(other)
134
135 cpdef Posit8 mul(self, Posit8 other):
136 cdef cposit.posit8_t f = cposit.p8_mul(self._c_posit, other._c_posit)
137 return Posit8.from_c_posit(f)
138
139 def __mul__(self, Posit8 other):
140 return self.mul(other)
141
142 cpdef Posit8 fma(self, Posit8 a1, Posit8 a2):
143 cdef cposit.posit8_t f = cposit.p8_mulAdd(a1._c_posit, a2._c_posit, self._c_posit)
144 return Posit8.from_c_posit(f)
145
146 cpdef Posit8 div(self, Posit8 other):
147 cdef cposit.posit8_t f = cposit.p8_div(self._c_posit, other._c_posit)
148 return Posit8.from_c_posit(f)
149
150 def __truediv__(self, Posit8 other):
151 return self.div(other)
152
153 cpdef Posit8 sqrt(self):
154 cdef cposit.posit8_t f = cposit.p8_sqrt(self._c_posit)
155 return Posit8.from_c_posit(f)
156
157 # in-place arithmetic
158
159 cpdef void ineg(self):
160 self._c_posit = _p8_neg(self._c_posit)
161
162 cpdef void iabs(self):
163 self._c_posit = _p8_abs(self._c_posit)
164
165 cpdef void iround(self):
166 self._c_posit = cposit.p8_roundToInt(self._c_posit)
167
168 cpdef void iadd(self, Posit8 other):
169 self._c_posit = cposit.p8_add(self._c_posit, other._c_posit)
170
171 def __iadd__(self, Posit8 other):
172 self.iadd(other)
173 return self
174
175 cpdef void isub(self, Posit8 other):
176 self._c_posit = cposit.p8_sub(self._c_posit, other._c_posit)
177
178 def __isub__(self, Posit8 other):
179 self.isub(other)
180 return self
181
182 cpdef void imul(self, Posit8 other):
183 self._c_posit = cposit.p8_mul(self._c_posit, other._c_posit)
184
185 def __imul__(self, Posit8 other):
186 self.imul(other)
187 return self
188
189 cpdef void ifma(self, Posit8 a1, Posit8 a2):
190 self._c_posit = cposit.p8_mulAdd(a1._c_posit, a2._c_posit, self._c_posit)
191
192 cpdef void idiv(self, Posit8 other):
193 self._c_posit = cposit.p8_div(self._c_posit, other._c_posit)
194
195 def __itruediv__(self, Posit8 other):
196 self.idiv(other)
197 return self
198
199 cpdef void isqrt(self):
200 self._c_posit = cposit.p8_sqrt(self._c_posit)
201
202 # comparison
203
204 cpdef bint eq(self, Posit8 other):
205 return cposit.p8_eq(self._c_posit, other._c_posit)
206
207 cpdef bint le(self, Posit8 other):
208 return cposit.p8_le(self._c_posit, other._c_posit)
209
210 cpdef bint lt(self, Posit8 other):
211 return cposit.p8_lt(self._c_posit, other._c_posit)
212
213 def __lt__(self, Posit8 other):
214 return self.lt(other)
215
216 def __le__(self, Posit8 other):
217 return self.le(other)
218
219 def __eq__(self, Posit8 other):
220 return self.eq(other)
221
222 def __ne__(self, Posit8 other):
223 return not self.eq(other)
224
225 def __ge__(self, Posit8 other):
226 return other.le(self)
227
228 def __gt__(self, Posit8 other):
229 return other.lt(self)
230
231 # conversion to other posit types
232
233 cpdef to_p16(self):
234 cdef cposit.posit16_t f = cposit.p8_to_p16(self._c_posit)
235 return Posit16.from_c_posit(f)
236
237 cpdef to_p32(self):
238 cdef cposit.posit32_t f = cposit.p8_to_p32(self._c_posit)
239 return Posit32.from_c_posit(f)
240
241 cpdef to_quire(self):
242 cdef cposit.quire8_t f
243 f = cposit.q8Clr()
244 f = cposit.q8_fdp_add(f, self._c_posit, _p8_one)
245 return Quire8.from_c_quire(f)
246
247
248 cdef class Quire8:
249
250 # the wrapped quire value
251 cdef cposit.quire8_t _c_quire
252
253 # factory function constructors that bypass init
254
255 @staticmethod
256 cdef Quire8 from_c_quire(cposit.quire8_t f):
257 """Factory function to create a Quire8 object directly from
258 a C quire8_t.
259 """
260 cdef Quire8 obj = Quire8.__new__(Quire8)
261 obj._c_quire = f
262 return obj
263
264 @staticmethod
265 def from_bits(uint32_t value):
266 """Factory function to create a Quire8 object from a bit pattern
267 represented as an integer.
268 """
269 cdef Quire8 obj = Quire8.__new__(Quire8)
270 obj._c_quire.v = value
271 return obj
272
273 # convenience interface for use inside Python
274
275 def __init__(self, value):
276 """Given an int, create a Quire8 from the bitpattern represented by
277 that int. Otherwise, given some value, create a Quire8 by rounding
278 float(value) to a Posit8.
279 """
280 if isinstance(value, int):
281 self._c_quire.v = value
282 else:
283 f = float(value)
284 self._c_quire = cposit.q8Clr()
285 self._c_quire = cposit.q8_fdp_add(self._c_quire, cposit.convertDoubleToP8(f), _p8_one)
286
287 def __float__(self):
288 return cposit.convertP8ToDouble(cposit.q8_to_p8(self._c_quire))
289
290 def __int__(self):
291 return int(cposit.convertP8ToDouble(cposit.q8_to_p8(self._c_quire)))
292
293 def __str__(self):
294 return repr(cposit.convertP8ToDouble(cposit.q8_to_p8(self._c_quire)))
295
296 def __repr__(self):
297 return 'Quire8(' + repr(cposit.convertP8ToDouble(cposit.q8_to_p8(self._c_quire))) + ')'
298
299 cpdef uint32_t get_bits(self):
300 return self._c_quire.v
301 bits = property(get_bits)
302
303 # arithmetic
304
305 cpdef Quire8 qma(self, Posit8 a1, Posit8 a2):
306 cdef cposit.quire8_t f = cposit.q8_fdp_add(self._c_quire, a1._c_posit, a2._c_posit)
307 return Quire8.from_c_quire(f)
308
309 cpdef Quire8 qms(self, Posit8 a1, Posit8 a2):
310 cdef cposit.quire8_t f = cposit.q8_fdp_sub(self._c_quire, a1._c_posit, a2._c_posit)
311 return Quire8.from_c_quire(f)
312
313 cpdef void iqma(self, Posit8 a1, Posit8 a2):
314 self._c_quire = cposit.q8_fdp_add(self._c_quire, a1._c_posit, a2._c_posit)
315
316 cpdef void iqms(self, Posit8 a1, Posit8 a2):
317 self._c_quire = cposit.q8_fdp_sub(self._c_quire, a1._c_posit, a2._c_posit)
318
319 cpdef void iclr(self):
320 self._c_quire = cposit.q8Clr()
321
322 # conversion back to posit
323
324 cpdef Posit8 to_posit(self):
325 cpdef cposit.posit8_t f = cposit.q8_to_p8(self._c_quire)
326 return Posit8.from_c_posit(f)
327
328
329 # external, non-method arithmetic
330
331 cpdef Posit8 p8_neg(Posit8 a1):
332 cdef cposit.posit8_t f = _p8_neg(a1._c_posit)
333 return Posit8.from_c_posit(f)
334
335 cpdef Posit8 p8_abs(Posit8 a1):
336 cdef cposit.posit8_t f = _p8_abs(a1._c_posit)
337 return Posit8.from_c_posit(f)
338
339 cpdef Posit8 p8_round(Posit8 a1):
340 cdef cposit.posit8_t f = cposit.p8_roundToInt(a1._c_posit)
341 return Posit8.from_c_posit(f)
342
343 cpdef Posit8 p8_add(Posit8 a1, Posit8 a2):
344 cdef cposit.posit8_t f = cposit.p8_add(a1._c_posit, a2._c_posit)
345 return Posit8.from_c_posit(f)
346
347 cpdef Posit8 p8_sub(Posit8 a1, Posit8 a2):
348 cdef cposit.posit8_t f = cposit.p8_sub(a1._c_posit, a2._c_posit)
349 return Posit8.from_c_posit(f)
350
351 cpdef Posit8 p8_mul(Posit8 a1, Posit8 a2):
352 cdef cposit.posit8_t f = cposit.p8_mul(a1._c_posit, a2._c_posit)
353 return Posit8.from_c_posit(f)
354
355 cpdef Posit8 p8_fma(Posit8 acc, Posit8 a1, Posit8 a2):
356 cdef cposit.posit8_t f = cposit.p8_mulAdd(a1._c_posit, a2._c_posit, acc._c_posit)
357 return Posit8.from_c_posit(f)
358
359 cpdef Posit8 p8_div(Posit8 a1, Posit8 a2):
360 cdef cposit.posit8_t f = cposit.p8_div(a1._c_posit, a2._c_posit)
361 return Posit8.from_c_posit(f)
362
363 cpdef Posit8 p8_sqrt(Posit8 a1):
364 cdef cposit.posit8_t f = cposit.p8_sqrt(a1._c_posit)
365 return Posit8.from_c_posit(f)
366
367 cpdef bint p8_eq(Posit8 a1, Posit8 a2):
368 return cposit.p8_eq(a1._c_posit, a2._c_posit)
369
370 cpdef bint p8_le(Posit8 a1, Posit8 a2):
371 return cposit.p8_le(a1._c_posit, a2._c_posit)
372
373 cpdef bint p8_lt(Posit8 a1, Posit8 a2):
374 return cposit.p8_lt(a1._c_posit, a2._c_posit)
375
376 cpdef Posit16 p8_to_p16(Posit8 a1):
377 cdef cposit.posit16_t f = cposit.p8_to_p16(a1._c_posit)
378 return Posit16.from_c_posit(f)
379
380 cpdef Posit32 p8_to_p32(Posit8 a1):
381 cdef cposit.posit32_t f = cposit.p8_to_p32(a1._c_posit)
382 return Posit32.from_c_posit(f)
383
384 cpdef Quire8 p8_to_q8(Posit8 a1):
385 cdef cposit.quire8_t f
386 f = cposit.q8Clr()
387 f = cposit.q8_fdp_add(f, a1._c_posit, _p8_one)
388 return Quire8.from_c_quire(f)
389
390 cpdef Quire8 q8_qma(Quire8 acc, Posit8 a1, Posit8 a2):
391 cdef cposit.quire8_t f = cposit.q8_fdp_add(acc._c_quire, a1._c_posit, a2._c_posit)
392 return Quire8.from_c_quire(f)
393
394 cpdef Quire8 q8_qms(Quire8 acc, Posit8 a1, Posit8 a2):
395 cdef cposit.quire8_t f = cposit.q8_fdp_sub(acc._c_quire, a1._c_posit, a2._c_posit)
396 return Quire8.from_c_quire(f)
397
398 cpdef Posit8 q8_to_p8(Quire8 a1):
399 cpdef cposit.posit8_t f = cposit.q8_to_p8(a1._c_quire)
400 return Posit8.from_c_posit(f)
401
402
403 cdef class Posit16:
404
405 # the wrapped posit value
406 cdef cposit.posit16_t _c_posit
407
408 # factory function constructors that bypass __init__
409
410 @staticmethod
411 cdef Posit16 from_c_posit(cposit.posit16_t f):
412 """Factory function to create a Posit16 object directly from
413 a C posit16_t.
414 """
415 cdef Posit16 obj = Posit16.__new__(Posit16)
416 obj._c_posit = f
417 return obj
418
419 @staticmethod
420 def from_bits(uint16_t value):
421 """Factory function to create a Posit16 object from a bit pattern
422 represented as an integer.
423 """
424 cdef Posit16 obj = Posit16.__new__(Posit16)
425 obj._c_posit.v = value
426 return obj
427
428 @staticmethod
429 def from_double(double value):
430 """Factory function to create a Posit16 object from a double.
431 """
432 cdef Posit16 obj = Posit16.__new__(Posit16)
433 obj._c_posit = cposit.convertDoubleToP16(value)
434 return obj
435
436 # convenience interface for use inside Python
437
438 def __init__(self, value):
439 """Given an int, create a Posit16 from the bitpattern represented by
440 that int. Otherwise, given some value, create a Posit16 by rounding
441 float(value).
442 """
443 if isinstance(value, int):
444 self._c_posit.v = value
445 else:
446 f = float(value)
447 self._c_posit = cposit.convertDoubleToP16(f)
448
449 def __float__(self):
450 return cposit.convertP16ToDouble(self._c_posit)
451
452 def __int__(self):
453 return int(cposit.convertP16ToDouble(self._c_posit))
454
455 def __str__(self):
456 return repr(cposit.convertP16ToDouble(self._c_posit))
457
458 def __repr__(self):
459 return 'Posit16(' + repr(cposit.convertP16ToDouble(self._c_posit)) + ')'
460
461 cpdef uint16_t get_bits(self):
462 return self._c_posit.v
463 bits = property(get_bits)
464
465 # arithmetic
466
467 cpdef Posit16 neg(self):
468 cdef cposit.posit16_t f = _p16_neg(self._c_posit)
469 return Posit16.from_c_posit(f)
470
471 def __neg__(self):
472 return self.neg()
473
474 cpdef Posit16 abs(self):
475 cdef cposit.posit16_t f = _p16_abs(self._c_posit)
476 return Posit16.from_c_posit(f)
477
478 def __abs__(self):
479 return self.abs()
480
481 cpdef Posit16 round(self):
482 cdef cposit.posit16_t f = cposit.p16_roundToInt(self._c_posit)
483 return Posit16.from_c_posit(f)
484
485 def __round__(self):
486 return self.round()
487
488 cpdef Posit16 add(self, Posit16 other):
489 cdef cposit.posit16_t f = cposit.p16_add(self._c_posit, other._c_posit)
490 return Posit16.from_c_posit(f)
491
492 def __add__(self, Posit16 other):
493 return self.add(other)
494
495 cpdef Posit16 sub(self, Posit16 other):
496 cdef cposit.posit16_t f = cposit.p16_sub(self._c_posit, other._c_posit)
497 return Posit16.from_c_posit(f)
498
499 def __sub__(self, Posit16 other):
500 return self.sub(other)
501
502 cpdef Posit16 mul(self, Posit16 other):
503 cdef cposit.posit16_t f = cposit.p16_mul(self._c_posit, other._c_posit)
504 return Posit16.from_c_posit(f)
505
506 def __mul__(self, Posit16 other):
507 return self.mul(other)
508
509 cpdef Posit16 fma(self, Posit16 a1, Posit16 a2):
510 cdef cposit.posit16_t f = cposit.p16_mulAdd(a1._c_posit, a2._c_posit, self._c_posit)
511 return Posit16.from_c_posit(f)
512
513 cpdef Posit16 div(self, Posit16 other):
514 cdef cposit.posit16_t f = cposit.p16_div(self._c_posit, other._c_posit)
515 return Posit16.from_c_posit(f)
516
517 def __truediv__(self, Posit16 other):
518 return self.div(other)
519
520 cpdef Posit16 sqrt(self):
521 cdef cposit.posit16_t f = cposit.p16_sqrt(self._c_posit)
522 return Posit16.from_c_posit(f)
523
524 # in-place arithmetic
525
526 cpdef void ineg(self):
527 self._c_posit = _p16_neg(self._c_posit)
528
529 cpdef void iabs(self):
530 self._c_posit = _p16_abs(self._c_posit)
531
532 cpdef void iround(self):
533 self._c_posit = cposit.p16_roundToInt(self._c_posit)
534
535 cpdef void iadd(self, Posit16 other):
536 self._c_posit = cposit.p16_add(self._c_posit, other._c_posit)
537
538 def __iadd__(self, Posit16 other):
539 self.iadd(other)
540 return self
541
542 cpdef void isub(self, Posit16 other):
543 self._c_posit = cposit.p16_sub(self._c_posit, other._c_posit)
544
545 def __isub__(self, Posit16 other):
546 self.isub(other)
547 return self
548
549 cpdef void imul(self, Posit16 other):
550 self._c_posit = cposit.p16_mul(self._c_posit, other._c_posit)
551
552 def __imul__(self, Posit16 other):
553 self.imul(other)
554 return self
555
556 cpdef void ifma(self, Posit16 a1, Posit16 a2):
557 self._c_posit = cposit.p16_mulAdd(a1._c_posit, a2._c_posit, self._c_posit)
558
559 cpdef void idiv(self, Posit16 other):
560 self._c_posit = cposit.p16_div(self._c_posit, other._c_posit)
561
562 def __itruediv__(self, Posit16 other):
563 self.idiv(other)
564 return self
565
566 cpdef void isqrt(self):
567 self._c_posit = cposit.p16_sqrt(self._c_posit)
568
569 # comparison
570
571 cpdef bint eq(self, Posit16 other):
572 return cposit.p16_eq(self._c_posit, other._c_posit)
573
574 cpdef bint le(self, Posit16 other):
575 return cposit.p16_le(self._c_posit, other._c_posit)
576
577 cpdef bint lt(self, Posit16 other):
578 return cposit.p16_lt(self._c_posit, other._c_posit)
579
580 def __lt__(self, Posit16 other):
581 return self.lt(other)
582
583 def __le__(self, Posit16 other):
584 return self.le(other)
585
586 def __eq__(self, Posit16 other):
587 return self.eq(other)
588
589 def __ne__(self, Posit16 other):
590 return not self.eq(other)
591
592 def __ge__(self, Posit16 other):
593 return other.le(self)
594
595 def __gt__(self, Posit16 other):
596 return other.lt(self)
597
598 # conversion to other posit types
599
600 cpdef to_p8(self):
601 cdef cposit.posit8_t f = cposit.p16_to_p8(self._c_posit)
602 return Posit8.from_c_posit(f)
603
604 cpdef to_p32(self):
605 cdef cposit.posit32_t f = cposit.p16_to_p32(self._c_posit)
606 return Posit32.from_c_posit(f)
607
608 cpdef to_quire(self):
609 cdef cposit.quire16_t f
610 f = cposit.q16Clr()
611 f = cposit.q16_fdp_add(f, self._c_posit, _p16_one)
612 return Quire16.from_c_quire(f)
613
614
615 cdef class Quire16:
616
617 # the wrapped quire value
618 cdef cposit.quire16_t _c_quire
619
620 # factory function constructors that bypass init
621
622 @staticmethod
623 cdef Quire16 from_c_quire(cposit.quire16_t f):
624 """Factory function to create a Quire16 object directly from
625 a C quire16_t.
626 """
627 cdef Quire16 obj = Quire16.__new__(Quire16)
628 obj._c_quire = f
629 return obj
630
631 @staticmethod
632 def from_bits(value):
633 """Factory function to create a Quire16 object from a bit pattern
634 represented as an integer.
635 """
636 cdef Quire16 obj = Quire16.__new__(Quire16)
637
638 if not isinstance(value, int):
639 raise TypeError('expecting int, got {}'.format(repr(value)))
640
641 for idx in range(1, -1, -1):
642 obj._c_quire.v[idx] = value & 0xffffffffffffffff
643 value >>= 64
644
645 if not (value == 0):
646 raise OverflowError('value too large to fit in uint64_t[2]')
647
648 return obj
649
650 # convenience interface for use inside Python
651
652 def __init__(self, value):
653 """Given an int, create a Quire16 from the bitpattern represented by
654 that int. Otherwise, given some value, create a Quire16 by rounding
655 float(value) to a Posit16.
656 """
657 if isinstance(value, int):
658 for idx in range(1, -1, -1):
659 self._c_quire.v[idx] = value & 0xffffffffffffffff
660 value >>= 64
661 if not (value == 0):
662 raise OverflowError('value too large to fit in uint64_t[2]')
663 else:
664 f = float(value)
665 self._c_quire = cposit.q16Clr()
666 self._c_quire = cposit.q16_fdp_add(self._c_quire, cposit.convertDoubleToP16(f), _p16_one)
667
668 def __float__(self):
669 return cposit.convertP16ToDouble(cposit.q16_to_p16(self._c_quire))
670
671 def __int__(self):
672 return int(cposit.convertP16ToDouble(cposit.q16_to_p16(self._c_quire)))
673
674 def __str__(self):
675 return repr(cposit.convertP16ToDouble(cposit.q16_to_p16(self._c_quire)))
676
677 def __repr__(self):
678 return 'Quire16(' + repr(cposit.convertP16ToDouble(cposit.q16_to_p16(self._c_quire))) + ')'
679
680 def get_bits(self):
681 b = 0
682 for u in self._c_quire.v:
683 b <<= 64
684 b |= u
685 return b
686 bits = property(get_bits)
687
688 # arithmetic
689
690 cpdef Quire16 qma(self, Posit16 a1, Posit16 a2):
691 cdef cposit.quire16_t f = cposit.q16_fdp_add(self._c_quire, a1._c_posit, a2._c_posit)
692 return Quire16.from_c_quire(f)
693
694 cpdef Quire16 qms(self, Posit16 a1, Posit16 a2):
695 cdef cposit.quire16_t f = cposit.q16_fdp_sub(self._c_quire, a1._c_posit, a2._c_posit)
696 return Quire16.from_c_quire(f)
697
698 cpdef void iqma(self, Posit16 a1, Posit16 a2):
699 self._c_quire = cposit.q16_fdp_add(self._c_quire, a1._c_posit, a2._c_posit)
700
701 cpdef void iqms(self, Posit16 a1, Posit16 a2):
702 self._c_quire = cposit.q16_fdp_sub(self._c_quire, a1._c_posit, a2._c_posit)
703
704 cpdef void iclr(self):
705 self._c_quire = cposit.q16Clr()
706
707 # conversion back to posit
708
709 cpdef Posit16 to_posit(self):
710 cpdef cposit.posit16_t f = cposit.q16_to_p16(self._c_quire)
711 return Posit16.from_c_posit(f)
712
713
714 # external, non-method arithmetic
715
716 cpdef Posit16 p16_neg(Posit16 a1):
717 cdef cposit.posit16_t f = _p16_neg(a1._c_posit)
718 return Posit16.from_c_posit(f)
719
720 cpdef Posit16 p16_abs(Posit16 a1):
721 cdef cposit.posit16_t f = _p16_abs(a1._c_posit)
722 return Posit16.from_c_posit(f)
723
724 cpdef Posit16 p16_round(Posit16 a1):
725 cdef cposit.posit16_t f = cposit.p16_roundToInt(a1._c_posit)
726 return Posit16.from_c_posit(f)
727
728 cpdef Posit16 p16_add(Posit16 a1, Posit16 a2):
729 cdef cposit.posit16_t f = cposit.p16_add(a1._c_posit, a2._c_posit)
730 return Posit16.from_c_posit(f)
731
732 cpdef Posit16 p16_sub(Posit16 a1, Posit16 a2):
733 cdef cposit.posit16_t f = cposit.p16_sub(a1._c_posit, a2._c_posit)
734 return Posit16.from_c_posit(f)
735
736 cpdef Posit16 p16_mul(Posit16 a1, Posit16 a2):
737 cdef cposit.posit16_t f = cposit.p16_mul(a1._c_posit, a2._c_posit)
738 return Posit16.from_c_posit(f)
739
740 cpdef Posit16 p16_fma(Posit16 acc, Posit16 a1, Posit16 a2):
741 cdef cposit.posit16_t f = cposit.p16_mulAdd(a1._c_posit, a2._c_posit, acc._c_posit)
742 return Posit16.from_c_posit(f)
743
744 cpdef Posit16 p16_div(Posit16 a1, Posit16 a2):
745 cdef cposit.posit16_t f = cposit.p16_div(a1._c_posit, a2._c_posit)
746 return Posit16.from_c_posit(f)
747
748 cpdef Posit16 p16_sqrt(Posit16 a1):
749 cdef cposit.posit16_t f = cposit.p16_sqrt(a1._c_posit)
750 return Posit16.from_c_posit(f)
751
752 cpdef bint p16_eq(Posit16 a1, Posit16 a2):
753 return cposit.p16_eq(a1._c_posit, a2._c_posit)
754
755 cpdef bint p16_le(Posit16 a1, Posit16 a2):
756 return cposit.p16_le(a1._c_posit, a2._c_posit)
757
758 cpdef bint p16_lt(Posit16 a1, Posit16 a2):
759 return cposit.p16_lt(a1._c_posit, a2._c_posit)
760
761 cpdef Posit8 p16_to_p8(Posit16 a1):
762 cdef cposit.posit8_t f = cposit.p16_to_p8(a1._c_posit)
763 return Posit8.from_c_posit(f)
764
765 cpdef Posit32 p16_to_p32(Posit16 a1):
766 cdef cposit.posit32_t f = cposit.p16_to_p32(a1._c_posit)
767 return Posit32.from_c_posit(f)
768
769 cpdef Quire16 p16_to_q16(Posit16 a1):
770 cdef cposit.quire16_t f
771 f = cposit.q16Clr()
772 f = cposit.q16_fdp_add(f, a1._c_posit, _p16_one)
773 return Quire16.from_c_quire(f)
774
775 cpdef Quire16 q16_qma(Quire16 acc, Posit16 a1, Posit16 a2):
776 cdef cposit.quire16_t f = cposit.q16_fdp_add(acc._c_quire, a1._c_posit, a2._c_posit)
777 return Quire16.from_c_quire(f)
778
779 cpdef Quire16 q16_qms(Quire16 acc, Posit16 a1, Posit16 a2):
780 cdef cposit.quire16_t f = cposit.q16_fdp_sub(acc._c_quire, a1._c_posit, a2._c_posit)
781 return Quire16.from_c_quire(f)
782
783 cpdef Posit16 q16_to_p16(Quire16 a1):
784 cpdef cposit.posit16_t f = cposit.q16_to_p16(a1._c_quire)
785 return Posit16.from_c_posit(f)
786
787
788 cdef class Posit32:
789
790 # the wrapped posit value
791 cdef cposit.posit32_t _c_posit
792
793 # factory function constructors that bypass __init__
794
795 @staticmethod
796 cdef Posit32 from_c_posit(cposit.posit32_t f):
797 """Factory function to create a Posit32 object directly from
798 a C posit32_t.
799 """
800 cdef Posit32 obj = Posit32.__new__(Posit32)
801 obj._c_posit = f
802 return obj
803
804 @staticmethod
805 def from_bits(uint32_t value):
806 """Factory function to create a Posit32 object from a bit pattern
807 represented as an integer.
808 """
809 cdef Posit32 obj = Posit32.__new__(Posit32)
810 obj._c_posit.v = value
811 return obj
812
813 @staticmethod
814 def from_double(double value):
815 """Factory function to create a Posit32 object from a double.
816 """
817 cdef Posit32 obj = Posit32.__new__(Posit32)
818 obj._c_posit = cposit.convertDoubleToP32(value)
819 return obj
820
821 # convenience interface for use inside Python
822
823 def __init__(self, value):
824 """Given an int, create a Posit32 from the bitpattern represented by
825 that int. Otherwise, given some value, create a Posit32 by rounding
826 float(value).
827 """
828 if isinstance(value, int):
829 self._c_posit.v = value
830 else:
831 f = float(value)
832 self._c_posit = cposit.convertDoubleToP32(f)
833
834 def __float__(self):
835 return cposit.convertP32ToDouble(self._c_posit)
836
837 def __int__(self):
838 return int(cposit.convertP32ToDouble(self._c_posit))
839
840 def __str__(self):
841 return repr(cposit.convertP32ToDouble(self._c_posit))
842
843 def __repr__(self):
844 return 'Posit32(' + repr(cposit.convertP32ToDouble(self._c_posit)) + ')'
845
846 cpdef uint32_t get_bits(self):
847 return self._c_posit.v
848 bits = property(get_bits)
849
850 # arithmetic
851
852 cpdef Posit32 neg(self):
853 cdef cposit.posit32_t f = _p32_neg(self._c_posit)
854 return Posit32.from_c_posit(f)
855
856 def __neg__(self):
857 return self.neg()
858
859 cpdef Posit32 abs(self):
860 cdef cposit.posit32_t f = _p32_abs(self._c_posit)
861 return Posit32.from_c_posit(f)
862
863 def __abs__(self):
864 return self.abs()
865
866 cpdef Posit32 round(self):
867 cdef cposit.posit32_t f = cposit.p32_roundToInt(self._c_posit)
868 return Posit32.from_c_posit(f)
869
870 def __round__(self):
871 return self.round()
872
873 cpdef Posit32 add(self, Posit32 other):
874 cdef cposit.posit32_t f = cposit.p32_add(self._c_posit, other._c_posit)
875 return Posit32.from_c_posit(f)
876
877 def __add__(self, Posit32 other):
878 return self.add(other)
879
880 cpdef Posit32 sub(self, Posit32 other):
881 cdef cposit.posit32_t f = cposit.p32_sub(self._c_posit, other._c_posit)
882 return Posit32.from_c_posit(f)
883
884 def __sub__(self, Posit32 other):
885 return self.sub(other)
886
887 cpdef Posit32 mul(self, Posit32 other):
888 cdef cposit.posit32_t f = cposit.p32_mul(self._c_posit, other._c_posit)
889 return Posit32.from_c_posit(f)
890
891 def __mul__(self, Posit32 other):
892 return self.mul(other)
893
894 cpdef Posit32 fma(self, Posit32 a1, Posit32 a2):
895 cdef cposit.posit32_t f = cposit.p32_mulAdd(a1._c_posit, a2._c_posit, self._c_posit)
896 return Posit32.from_c_posit(f)
897
898 cpdef Posit32 div(self, Posit32 other):
899 cdef cposit.posit32_t f = cposit.p32_div(self._c_posit, other._c_posit)
900 return Posit32.from_c_posit(f)
901
902 def __truediv__(self, Posit32 other):
903 return self.div(other)
904
905 cpdef Posit32 sqrt(self):
906 cdef cposit.posit32_t f = cposit.p32_sqrt(self._c_posit)
907 return Posit32.from_c_posit(f)
908
909 # in-place arithmetic
910
911 cpdef void ineg(self):
912 self._c_posit = _p32_neg(self._c_posit)
913
914 cpdef void iabs(self):
915 self._c_posit = _p32_abs(self._c_posit)
916
917 cpdef void iround(self):
918 self._c_posit = cposit.p32_roundToInt(self._c_posit)
919
920 cpdef void iadd(self, Posit32 other):
921 self._c_posit = cposit.p32_add(self._c_posit, other._c_posit)
922
923 def __iadd__(self, Posit32 other):
924 self.iadd(other)
925 return self
926
927 cpdef void isub(self, Posit32 other):
928 self._c_posit = cposit.p32_sub(self._c_posit, other._c_posit)
929
930 def __isub__(self, Posit32 other):
931 self.isub(other)
932 return self
933
934 cpdef void imul(self, Posit32 other):
935 self._c_posit = cposit.p32_mul(self._c_posit, other._c_posit)
936
937 def __imul__(self, Posit32 other):
938 self.imul(other)
939 return self
940
941 cpdef void ifma(self, Posit32 a1, Posit32 a2):
942 self._c_posit = cposit.p32_mulAdd(a1._c_posit, a2._c_posit, self._c_posit)
943
944 cpdef void idiv(self, Posit32 other):
945 self._c_posit = cposit.p32_div(self._c_posit, other._c_posit)
946
947 def __itruediv__(self, Posit32 other):
948 self.idiv(other)
949 return self
950
951 cpdef void isqrt(self):
952 self._c_posit = cposit.p32_sqrt(self._c_posit)
953
954 # comparison
955
956 cpdef bint eq(self, Posit32 other):
957 return cposit.p32_eq(self._c_posit, other._c_posit)
958
959 cpdef bint le(self, Posit32 other):
960 return cposit.p32_le(self._c_posit, other._c_posit)
961
962 cpdef bint lt(self, Posit32 other):
963 return cposit.p32_lt(self._c_posit, other._c_posit)
964
965 def __lt__(self, Posit32 other):
966 return self.lt(other)
967
968 def __le__(self, Posit32 other):
969 return self.le(other)
970
971 def __eq__(self, Posit32 other):
972 return self.eq(other)
973
974 def __ne__(self, Posit32 other):
975 return not self.eq(other)
976
977 def __ge__(self, Posit32 other):
978 return other.le(self)
979
980 def __gt__(self, Posit32 other):
981 return other.lt(self)
982
983 # conversion to other posit types
984
985 cpdef to_p8(self):
986 cdef cposit.posit8_t f = cposit.p32_to_p8(self._c_posit)
987 return Posit8.from_c_posit(f)
988
989 cpdef to_p16(self):
990 cdef cposit.posit16_t f = cposit.p32_to_p16(self._c_posit)
991 return Posit16.from_c_posit(f)
992
993 cpdef to_quire(self):
994 cdef cposit.quire32_t f
995 f = cposit.q32Clr()
996 f = cposit.q32_fdp_add(f, self._c_posit, _p32_one)
997 return Quire32.from_c_quire(f)
998
999
1000 cdef class Quire32:
1001
1002 # the wrapped quire value
1003 cdef cposit.quire32_t _c_quire
1004
1005 # factory function constructors that bypass init
1006
1007 @staticmethod
1008 cdef Quire32 from_c_quire(cposit.quire32_t f):
1009 """Factory function to create a Quire32 object directly from
1010 a C quire32_t.
1011 """
1012 cdef Quire32 obj = Quire32.__new__(Quire32)
1013 obj._c_quire = f
1014 return obj
1015
1016 @staticmethod
1017 def from_bits(value):
1018 """Factory function to create a Quire32 object from a bit pattern
1019 represented as an integer.
1020 """
1021 cdef Quire32 obj = Quire32.__new__(Quire32)
1022
1023 if not isinstance(value, int):
1024 raise TypeError('expecting int, got {}'.format(repr(value)))
1025
1026 for idx in range(7, -1, -1):
1027 obj._c_quire.v[idx] = value & 0xffffffffffffffff
1028 value >>= 64
1029
1030 if not (value == 0):
1031 raise OverflowError('value too large to fit in uint64_t[8]')
1032
1033 return obj
1034
1035 # convenience interface for use inside Python
1036
1037 def __init__(self, value):
1038 """Given an int, create a Quire32 from the bitpattern represented by
1039 that int. Otherwise, given some value, create a Quire32 by rounding
1040 float(value) to a Posit32.
1041 """
1042 if isinstance(value, int):
1043 for idx in range(7, -1, -1):
1044 self._c_quire.v[idx] = value & 0xffffffffffffffff
1045 value >>= 64
1046 if not (value == 0):
1047 raise OverflowError('value too large to fit in uint64_t[8]')
1048 else:
1049 f = float(value)
1050 self._c_quire = cposit.q32Clr()
1051 self._c_quire = cposit.q32_fdp_add(self._c_quire, cposit.convertDoubleToP32(f), _p32_one)
1052
1053 def __float__(self):
1054 return cposit.convertP32ToDouble(cposit.q32_to_p32(self._c_quire))
1055
1056 def __int__(self):
1057 return int(cposit.convertP32ToDouble(cposit.q32_to_p32(self._c_quire)))
1058
1059 def __str__(self):
1060 return repr(cposit.convertP32ToDouble(cposit.q32_to_p32(self._c_quire)))
1061
1062 def __repr__(self):
1063 return 'Quire32(' + repr(cposit.convertP32ToDouble(cposit.q32_to_p32(self._c_quire))) + ')'
1064
1065 def get_bits(self):
1066 b = 0
1067 for u in self._c_quire.v:
1068 b <<= 64
1069 b |= u
1070 return b
1071 bits = property(get_bits)
1072
1073 # arithmetic
1074
1075 cpdef Quire32 qma(self, Posit32 a1, Posit32 a2):
1076 cdef cposit.quire32_t f = cposit.q32_fdp_add(self._c_quire, a1._c_posit, a2._c_posit)
1077 return Quire32.from_c_quire(f)
1078
1079 cpdef Quire32 qms(self, Posit32 a1, Posit32 a2):
1080 cdef cposit.quire32_t f = cposit.q32_fdp_sub(self._c_quire, a1._c_posit, a2._c_posit)
1081 return Quire32.from_c_quire(f)
1082
1083 cpdef void iqma(self, Posit32 a1, Posit32 a2):
1084 self._c_quire = cposit.q32_fdp_add(self._c_quire, a1._c_posit, a2._c_posit)
1085
1086 cpdef void iqms(self, Posit32 a1, Posit32 a2):
1087 self._c_quire = cposit.q32_fdp_sub(self._c_quire, a1._c_posit, a2._c_posit)
1088
1089 cpdef void iclr(self):
1090 self._c_quire = cposit.q32Clr()
1091
1092 # conversion back to posit
1093
1094 cpdef Posit32 to_posit(self):
1095 cpdef cposit.posit32_t f = cposit.q32_to_p32(self._c_quire)
1096 return Posit32.from_c_posit(f)
1097
1098
1099 # external, non-method arithmetic
1100
1101 cpdef Posit32 p32_neg(Posit32 a1):
1102 cdef cposit.posit32_t f = _p32_neg(a1._c_posit)
1103 return Posit32.from_c_posit(f)
1104
1105 cpdef Posit32 p32_abs(Posit32 a1):
1106 cdef cposit.posit32_t f = _p32_abs(a1._c_posit)
1107 return Posit32.from_c_posit(f)
1108
1109 cpdef Posit32 p32_round(Posit32 a1):
1110 cdef cposit.posit32_t f = cposit.p32_roundToInt(a1._c_posit)
1111 return Posit32.from_c_posit(f)
1112
1113 cpdef Posit32 p32_add(Posit32 a1, Posit32 a2):
1114 cdef cposit.posit32_t f = cposit.p32_add(a1._c_posit, a2._c_posit)
1115 return Posit32.from_c_posit(f)
1116
1117 cpdef Posit32 p32_sub(Posit32 a1, Posit32 a2):
1118 cdef cposit.posit32_t f = cposit.p32_sub(a1._c_posit, a2._c_posit)
1119 return Posit32.from_c_posit(f)
1120
1121 cpdef Posit32 p32_mul(Posit32 a1, Posit32 a2):
1122 cdef cposit.posit32_t f = cposit.p32_mul(a1._c_posit, a2._c_posit)
1123 return Posit32.from_c_posit(f)
1124
1125 cpdef Posit32 p32_fma(Posit32 acc, Posit32 a1, Posit32 a2):
1126 cdef cposit.posit32_t f = cposit.p32_mulAdd(a1._c_posit, a2._c_posit, acc._c_posit)
1127 return Posit32.from_c_posit(f)
1128
1129 cpdef Posit32 p32_div(Posit32 a1, Posit32 a2):
1130 cdef cposit.posit32_t f = cposit.p32_div(a1._c_posit, a2._c_posit)
1131 return Posit32.from_c_posit(f)
1132
1133 cpdef Posit32 p32_sqrt(Posit32 a1):
1134 cdef cposit.posit32_t f = cposit.p32_sqrt(a1._c_posit)
1135 return Posit32.from_c_posit(f)
1136
1137 cpdef bint p32_eq(Posit32 a1, Posit32 a2):
1138 return cposit.p32_eq(a1._c_posit, a2._c_posit)
1139
1140 cpdef bint p32_le(Posit32 a1, Posit32 a2):
1141 return cposit.p32_le(a1._c_posit, a2._c_posit)
1142
1143 cpdef bint p32_lt(Posit32 a1, Posit32 a2):
1144 return cposit.p32_lt(a1._c_posit, a2._c_posit)
1145
1146 cpdef Posit8 p32_to_p8(Posit32 a1):
1147 cdef cposit.posit8_t f = cposit.p32_to_p8(a1._c_posit)
1148 return Posit8.from_c_posit(f)
1149
1150 cpdef Posit16 p32_to_p16(Posit32 a1):
1151 cdef cposit.posit16_t f = cposit.p32_to_p16(a1._c_posit)
1152 return Posit16.from_c_posit(f)
1153
1154 cpdef Quire32 p32_to_q32(Posit32 a1):
1155 cdef cposit.quire32_t f
1156 f = cposit.q32Clr()
1157 f = cposit.q32_fdp_add(f, a1._c_posit, _p32_one)
1158 return Quire32.from_c_quire(f)
1159
1160 cpdef Quire32 q32_qma(Quire32 acc, Posit32 a1, Posit32 a2):
1161 cdef cposit.quire32_t f = cposit.q32_fdp_add(acc._c_quire, a1._c_posit, a2._c_posit)
1162 return Quire32.from_c_quire(f)
1163
1164 cpdef Quire32 q32_qms(Quire32 acc, Posit32 a1, Posit32 a2):
1165 cdef cposit.quire32_t f = cposit.q32_fdp_sub(acc._c_quire, a1._c_posit, a2._c_posit)
1166 return Quire32.from_c_quire(f)
1167
1168 cpdef Posit32 q32_to_p32(Quire32 a1):
1169 cpdef cposit.posit32_t f = cposit.q32_to_p32(a1._c_quire)
1170 return Posit32.from_c_posit(f)