add negation and absolute value
[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
10 cdef inline cposit.posit8_t _p8_neg(cposit.posit8_t f):
11 f.v = -f.v
12 return f
13
14 cdef inline cposit.posit16_t _p16_neg(cposit.posit16_t f):
15 f.v = -f.v
16 return f
17
18 cdef inline cposit.posit8_t _p8_abs(cposit.posit8_t f):
19 f.v = <uint8_t> abs(<int8_t> f.v)
20 return f
21
22 cdef inline cposit.posit16_t _p16_abs(cposit.posit16_t f):
23 f.v = <uint16_t> abs(<int16_t> f.v)
24 return f
25
26
27 cdef class Posit8:
28
29 # the wrapped posit value
30 cdef cposit.posit8_t _c_posit
31
32 # factory function constructors that bypass __init__
33
34 @staticmethod
35 cdef Posit8 from_c_posit(cposit.posit8_t f):
36 """Factory function to create a Posit8 object directly from
37 a C posit8_t.
38 """
39 cdef Posit8 obj = Posit8.__new__(Posit8)
40 obj._c_posit = f
41 return obj
42
43 @staticmethod
44 def from_bits(uint8_t value):
45 """Factory function to create a Posit8 object from a bit pattern
46 represented as an integer.
47 """
48 cdef Posit8 obj = Posit8.__new__(Posit8)
49 obj._c_posit.v = value
50 return obj
51
52 @staticmethod
53 def from_double(double value):
54 """Factory function to create a Posit8 object from a double.
55 """
56 cdef Posit8 obj = Posit8.__new__(Posit8)
57 obj._c_posit = cposit.convertDoubleToP8(value)
58 return obj
59
60 # convenience interface for use inside Python
61
62 def __init__(self, value):
63 if isinstance(value, int):
64 self._c_posit.v = value
65 else:
66 f = float(value)
67 self._c_posit = cposit.convertDoubleToP8(f)
68
69 def __float__(self):
70 return cposit.convertP8ToDouble(self._c_posit)
71
72 def __int__(self):
73 return int(cposit.convertP8ToDouble(self._c_posit))
74
75 def __str__(self):
76 return repr(cposit.convertP8ToDouble(self._c_posit))
77
78 def __repr__(self):
79 return 'Posit8(' + repr(cposit.convertP8ToDouble(self._c_posit)) + ')'
80
81 cpdef uint8_t get_bits(self):
82 return self._c_posit.v
83 bits = property(get_bits)
84
85 # arithmetic
86
87 cpdef Posit8 neg(self):
88 cdef cposit.posit8_t f = _p8_neg(self._c_posit)
89 return Posit8.from_c_posit(f)
90
91 def __neg__(self):
92 return self.neg()
93
94 cpdef Posit8 abs(self):
95 cdef cposit.posit8_t f = _p8_abs(self._c_posit)
96 return Posit8.from_c_posit(f)
97
98 def __abs__(self):
99 return self.abs()
100
101 cpdef Posit8 round(self):
102 cdef cposit.posit8_t f = cposit.p8_roundToInt(self._c_posit)
103 return Posit8.from_c_posit(f)
104
105 def __round__(self):
106 return self.round()
107
108 cpdef Posit8 add(self, Posit8 other):
109 cdef cposit.posit8_t f = cposit.p8_add(self._c_posit, other._c_posit)
110 return Posit8.from_c_posit(f)
111
112 def __add__(self, Posit8 other):
113 return self.add(other)
114
115 cpdef Posit8 sub(self, Posit8 other):
116 cdef cposit.posit8_t f = cposit.p8_sub(self._c_posit, other._c_posit)
117 return Posit8.from_c_posit(f)
118
119 def __sub__(self, Posit8 other):
120 return self.sub(other)
121
122 cpdef Posit8 mul(self, Posit8 other):
123 cdef cposit.posit8_t f = cposit.p8_mul(self._c_posit, other._c_posit)
124 return Posit8.from_c_posit(f)
125
126 def __mul__(self, Posit8 other):
127 return self.mul(other)
128
129 cpdef Posit8 fma(self, Posit8 a2, Posit8 a3):
130 cdef cposit.posit8_t f = cposit.p8_mulAdd(self._c_posit, a2._c_posit, a3._c_posit)
131 return Posit8.from_c_posit(f)
132
133 cpdef Posit8 fam(self, Posit8 a1, Posit8 a2):
134 cdef cposit.posit8_t f = cposit.p8_mulAdd(a1._c_posit, a2._c_posit, self._c_posit)
135 return Posit8.from_c_posit(f)
136
137 cpdef Posit8 div(self, Posit8 other):
138 cdef cposit.posit8_t f = cposit.p8_div(self._c_posit, other._c_posit)
139 return Posit8.from_c_posit(f)
140
141 def __truediv__(self, Posit8 other):
142 return self.div(other)
143
144 cpdef Posit8 sqrt(self):
145 cdef cposit.posit8_t f = cposit.p8_sqrt(self._c_posit)
146 return Posit8.from_c_posit(f)
147
148 # in-place arithmetic
149
150 cpdef void ineg(self):
151 self._c_posit = _p8_neg(self._c_posit)
152
153 cpdef void iabs(self):
154 self._c_posit = _p8_abs(self._c_posit)
155
156 cpdef void iround(self):
157 self._c_posit = cposit.p8_roundToInt(self._c_posit)
158
159 cpdef void iadd(self, Posit8 other):
160 self._c_posit = cposit.p8_add(self._c_posit, other._c_posit)
161
162 def __iadd__(self, Posit8 other):
163 self.iadd(other)
164 return self
165
166 cpdef void isub(self, Posit8 other):
167 self._c_posit = cposit.p8_sub(self._c_posit, other._c_posit)
168
169 def __isub__(self, Posit8 other):
170 self.isub(other)
171 return self
172
173 cpdef void imul(self, Posit8 other):
174 self._c_posit = cposit.p8_mul(self._c_posit, other._c_posit)
175
176 def __imul__(self, Posit8 other):
177 self.imul(other)
178 return self
179
180 cpdef void ifma(self, Posit8 a2, Posit8 a3):
181 self._c_posit = cposit.p8_mulAdd(self._c_posit, a2._c_posit, a3._c_posit)
182
183 cpdef void ifam(self, Posit8 a1, Posit8 a2):
184 self._c_posit = cposit.p8_mulAdd(a1._c_posit, a2._c_posit, self._c_posit)
185
186 cpdef void idiv(self, Posit8 other):
187 self._c_posit = cposit.p8_div(self._c_posit, other._c_posit)
188
189 def __itruediv__(self, Posit8 other):
190 self.idiv(other)
191 return self
192
193 cpdef void isqrt(self):
194 self._c_posit = cposit.p8_sqrt(self._c_posit)
195
196 # comparison
197
198 cpdef bint eq(self, Posit8 other):
199 return cposit.p8_eq(self._c_posit, other._c_posit)
200
201 cpdef bint le(self, Posit8 other):
202 return cposit.p8_le(self._c_posit, other._c_posit)
203
204 cpdef bint lt(self, Posit8 other):
205 return cposit.p8_lt(self._c_posit, other._c_posit)
206
207 def __lt__(self, Posit8 other):
208 return self.lt(other)
209
210 def __le__(self, Posit8 other):
211 return self.le(other)
212
213 def __eq__(self, Posit8 other):
214 return self.eq(other)
215
216 def __ne__(self, Posit8 other):
217 return not self.eq(other)
218
219 def __ge__(self, Posit8 other):
220 return other.le(self)
221
222 def __gt__(self, Posit8 other):
223 return other.lt(self)
224
225 # conversion to other posit types
226
227 cpdef to_p16(self):
228 cdef cposit.posit16_t f = cposit.p8_to_p16(self._c_posit)
229 return Posit16.from_c_posit(f)
230
231 cpdef to_quire(self):
232 cdef cposit.quire8_t f
233 cposit.q8_clr(f)
234 f = cposit.q8_fdp_add(f, self._c_posit, _p8_one)
235 return Quire8.from_c_quire(f)
236
237
238 cdef class Quire8:
239
240 # the wrapped quire value
241 cdef cposit.quire8_t _c_quire
242
243 # factory function constructors that bypass init
244
245 @staticmethod
246 cdef Quire8 from_c_quire(cposit.quire8_t f):
247 """Factory function to create a Quire8 object directly from
248 a C quire8_t.
249 """
250 cdef Quire8 obj = Quire8.__new__(Quire8)
251 obj._c_quire = f
252 return obj
253
254 @staticmethod
255 def from_bits(uint32_t value):
256 """Factory function to create a Quire8 object from a bit pattern
257 represented as an integer.
258 """
259 cdef Quire8 obj = Quire8.__new__(Quire8)
260 obj._c_quire.v = value
261 return obj
262
263 # convenience interface for use inside Python
264
265 def __init__(self, value):
266 if isinstance(value, int):
267 self._c_quire.v = value
268 else:
269 f = float(value)
270 cposit.q8_clr(self._c_quire)
271 self._c_quire = cposit.q8_fdp_add(self._c_quire, cposit.convertDoubleToP8(f), _p8_one)
272
273 def __float__(self):
274 return cposit.convertP8ToDouble(cposit.q8_to_p8(self._c_quire))
275
276 def __int__(self):
277 return int(cposit.convertP8ToDouble(cposit.q8_to_p8(self._c_quire)))
278
279 def __str__(self):
280 return repr(cposit.convertP8ToDouble(cposit.q8_to_p8(self._c_quire)))
281
282 def __repr__(self):
283 return 'Quire8(' + repr(cposit.convertP8ToDouble(cposit.q8_to_p8(self._c_quire))) + ')'
284
285 cpdef uint32_t get_bits(self):
286 return self._c_quire.v
287 bits = property(get_bits)
288
289 # arithmetic
290
291 cpdef Quire8 qam(self, Posit8 a1, Posit8 a2):
292 cdef cposit.quire8_t f = cposit.q8_fdp_add(self._c_quire, a1._c_posit, a2._c_posit)
293 return Quire8.from_c_quire(f)
294
295 cpdef Quire8 qsm(self, Posit8 a1, Posit8 a2):
296 cdef cposit.quire8_t f = cposit.q8_fdp_sub(self._c_quire, a1._c_posit, a2._c_posit)
297 return Quire8.from_c_quire(f)
298
299 cpdef void iqam(self, Posit8 a1, Posit8 a2):
300 self._c_quire = cposit.q8_fdp_add(self._c_quire, a1._c_posit, a2._c_posit)
301
302 cpdef void iqsm(self, Posit8 a1, Posit8 a2):
303 self._c_quire = cposit.q8_fdp_sub(self._c_quire, a1._c_posit, a2._c_posit)
304
305 cpdef void iclr(self):
306 cposit.q8_clr(self._c_quire)
307
308 # conversion back to posit
309
310 cpdef Posit8 to_posit(self):
311 cpdef cposit.posit8_t f = cposit.q8_to_p8(self._c_quire)
312 return Posit8.from_c_posit(f)
313
314
315 # external, non-method arithmetic
316
317 cpdef Posit8 p8_neg(Posit8 a1):
318 cdef cposit.posit8_t f = _p8_neg(a1._c_posit)
319 return Posit8.from_c_posit(f)
320
321 cpdef Posit8 p8_abs(Posit8 a1):
322 cdef cposit.posit8_t f = _p8_abs(a1._c_posit)
323 return Posit8.from_c_posit(f)
324
325 cpdef Posit8 p8_round(Posit8 a1):
326 cdef cposit.posit8_t f = cposit.p8_roundToInt(a1._c_posit)
327 return Posit8.from_c_posit(f)
328
329 cpdef Posit8 p8_add(Posit8 a1, Posit8 a2):
330 cdef cposit.posit8_t f = cposit.p8_add(a1._c_posit, a2._c_posit)
331 return Posit8.from_c_posit(f)
332
333 cpdef Posit8 p8_sub(Posit8 a1, Posit8 a2):
334 cdef cposit.posit8_t f = cposit.p8_sub(a1._c_posit, a2._c_posit)
335 return Posit8.from_c_posit(f)
336
337 cpdef Posit8 p8_mul(Posit8 a1, Posit8 a2):
338 cdef cposit.posit8_t f = cposit.p8_mul(a1._c_posit, a2._c_posit)
339 return Posit8.from_c_posit(f)
340
341 cpdef Posit8 p8_fma(Posit8 a1, Posit8 a2, Posit8 a3):
342 cdef cposit.posit8_t f = cposit.p8_mulAdd(a1._c_posit, a2._c_posit, a3._c_posit)
343 return Posit8.from_c_posit(f)
344
345 cpdef Posit8 p8_fam(Posit8 a3, Posit8 a1, Posit8 a2):
346 cdef cposit.posit8_t f = cposit.p8_mulAdd(a1._c_posit, a2._c_posit, a3._c_posit)
347 return Posit8.from_c_posit(f)
348
349 cpdef Posit8 p8_div(Posit8 a1, Posit8 a2):
350 cdef cposit.posit8_t f = cposit.p8_div(a1._c_posit, a2._c_posit)
351 return Posit8.from_c_posit(f)
352
353 cpdef Posit8 p8_sqrt(Posit8 a1):
354 cdef cposit.posit8_t f = cposit.p8_sqrt(a1._c_posit)
355 return Posit8.from_c_posit(f)
356
357 cpdef bint p8_eq(Posit8 a1, Posit8 a2):
358 return cposit.p8_eq(a1._c_posit, a2._c_posit)
359
360 cpdef bint p8_le(Posit8 a1, Posit8 a2):
361 return cposit.p8_le(a1._c_posit, a2._c_posit)
362
363 cpdef bint p8_lt(Posit8 a1, Posit8 a2):
364 return cposit.p8_lt(a1._c_posit, a2._c_posit)
365
366 cpdef Posit16 p8_to_p16(Posit8 a1):
367 cdef cposit.posit16_t f = cposit.p8_to_p16(a1._c_posit)
368 return Posit16.from_c_posit(f)
369
370 cpdef Quire8 p8_to_q8(Posit8 a1):
371 cdef cposit.quire8_t f
372 cposit.q8_clr(f)
373 f = cposit.q8_fdp_add(f, a1._c_posit, _p8_one)
374 return Quire8.from_c_quire(f)
375
376 cpdef Quire8 q8_qam(Quire8 a3, Posit8 a1, Posit8 a2):
377 cdef cposit.quire8_t f = cposit.q8_fdp_add(a3._c_quire, a1._c_posit, a2._c_posit)
378 return Quire8.from_c_quire(f)
379
380 cpdef Quire8 q8_qsm(Quire8 a3, Posit8 a1, Posit8 a2):
381 cdef cposit.quire8_t f = cposit.q8_fdp_sub(a3._c_quire, a1._c_posit, a2._c_posit)
382 return Quire8.from_c_quire(f)
383
384 cpdef Posit8 q8_to_p8(Quire8 a1):
385 cpdef cposit.posit8_t f = cposit.q8_to_p8(a1._c_quire)
386 return Posit8.from_c_posit(f)
387
388
389 cdef class Posit16:
390
391 # the wrapped posit value
392 cdef cposit.posit16_t _c_posit
393
394 # factory function constructors that bypass __init__
395
396 @staticmethod
397 cdef Posit16 from_c_posit(cposit.posit16_t f):
398 """Factory function to create a Posit16 object directly from
399 a C posit16_t.
400 """
401 cdef Posit16 obj = Posit16.__new__(Posit16)
402 obj._c_posit = f
403 return obj
404
405 @staticmethod
406 def from_bits(uint16_t value):
407 """Factory function to create a Posit16 object from a bit pattern
408 represented as an integer.
409 """
410 cdef Posit16 obj = Posit16.__new__(Posit16)
411 obj._c_posit.v = value
412 return obj
413
414 @staticmethod
415 def from_double(double value):
416 """Factory function to create a Posit16 object from a double.
417 """
418 cdef Posit16 obj = Posit16.__new__(Posit16)
419 obj._c_posit = cposit.convertDoubleToP16(value)
420 return obj
421
422 # convenience interface for use inside Python
423
424 def __init__(self, value):
425 if isinstance(value, int):
426 self._c_posit.v = value
427 else:
428 f = float(value)
429 self._c_posit = cposit.convertDoubleToP16(f)
430
431 def __float__(self):
432 return cposit.convertP16ToDouble(self._c_posit)
433
434 def __int__(self):
435 return int(cposit.convertP16ToDouble(self._c_posit))
436
437 def __str__(self):
438 return repr(cposit.convertP16ToDouble(self._c_posit))
439
440 def __repr__(self):
441 return 'Posit16(' + repr(cposit.convertP16ToDouble(self._c_posit)) + ')'
442
443 cpdef uint16_t get_bits(self):
444 return self._c_posit.v
445 bits = property(get_bits)
446
447 # arithmetic
448
449 cpdef Posit16 neg(self):
450 cdef cposit.posit16_t f = _p16_neg(self._c_posit)
451 return Posit16.from_c_posit(f)
452
453 def __neg__(self):
454 return self.neg()
455
456 cpdef Posit16 abs(self):
457 cdef cposit.posit16_t f = _p16_abs(self._c_posit)
458 return Posit16.from_c_posit(f)
459
460 def __abs__(self):
461 return self.abs()
462
463 cpdef Posit16 round(self):
464 cdef cposit.posit16_t f = cposit.p16_roundToInt(self._c_posit)
465 return Posit16.from_c_posit(f)
466
467 def __round__(self):
468 return self.round()
469
470 cpdef Posit16 add(self, Posit16 other):
471 cdef cposit.posit16_t f = cposit.p16_add(self._c_posit, other._c_posit)
472 return Posit16.from_c_posit(f)
473
474 def __add__(self, Posit16 other):
475 return self.add(other)
476
477 cpdef Posit16 sub(self, Posit16 other):
478 cdef cposit.posit16_t f = cposit.p16_sub(self._c_posit, other._c_posit)
479 return Posit16.from_c_posit(f)
480
481 def __sub__(self, Posit16 other):
482 return self.sub(other)
483
484 cpdef Posit16 mul(self, Posit16 other):
485 cdef cposit.posit16_t f = cposit.p16_mul(self._c_posit, other._c_posit)
486 return Posit16.from_c_posit(f)
487
488 def __mul__(self, Posit16 other):
489 return self.mul(other)
490
491 cpdef Posit16 fma(self, Posit16 a2, Posit16 a3):
492 cdef cposit.posit16_t f = cposit.p16_mulAdd(self._c_posit, a2._c_posit, a3._c_posit)
493 return Posit16.from_c_posit(f)
494
495 cpdef Posit16 fam(self, Posit16 a1, Posit16 a2):
496 cdef cposit.posit16_t f = cposit.p16_mulAdd(a1._c_posit, a2._c_posit, self._c_posit)
497 return Posit16.from_c_posit(f)
498
499 cpdef Posit16 div(self, Posit16 other):
500 cdef cposit.posit16_t f = cposit.p16_div(self._c_posit, other._c_posit)
501 return Posit16.from_c_posit(f)
502
503 def __truediv__(self, Posit16 other):
504 return self.div(other)
505
506 cpdef Posit16 sqrt(self):
507 cdef cposit.posit16_t f = cposit.p16_sqrt(self._c_posit)
508 return Posit16.from_c_posit(f)
509
510 # in-place arithmetic
511
512 cpdef void ineg(self):
513 self._c_posit = _p16_neg(self._c_posit)
514
515 cpdef void iabs(self):
516 self._c_posit = _p16_abs(self._c_posit)
517
518 cpdef void iround(self):
519 self._c_posit = cposit.p16_roundToInt(self._c_posit)
520
521 cpdef void iadd(self, Posit16 other):
522 self._c_posit = cposit.p16_add(self._c_posit, other._c_posit)
523
524 def __iadd__(self, Posit16 other):
525 self.iadd(other)
526 return self
527
528 cpdef void isub(self, Posit16 other):
529 self._c_posit = cposit.p16_sub(self._c_posit, other._c_posit)
530
531 def __isub__(self, Posit16 other):
532 self.isub(other)
533 return self
534
535 cpdef void imul(self, Posit16 other):
536 self._c_posit = cposit.p16_mul(self._c_posit, other._c_posit)
537
538 def __imul__(self, Posit16 other):
539 self.imul(other)
540 return self
541
542 cpdef void ifma(self, Posit16 a2, Posit16 a3):
543 self._c_posit = cposit.p16_mulAdd(self._c_posit, a2._c_posit, a3._c_posit)
544
545 cpdef void ifam(self, Posit16 a1, Posit16 a2):
546 self._c_posit = cposit.p16_mulAdd(a1._c_posit, a2._c_posit, self._c_posit)
547
548 cpdef void idiv(self, Posit16 other):
549 self._c_posit = cposit.p16_div(self._c_posit, other._c_posit)
550
551 def __itruediv__(self, Posit16 other):
552 self.idiv(other)
553 return self
554
555 cpdef void isqrt(self):
556 self._c_posit = cposit.p16_sqrt(self._c_posit)
557
558 # comparison
559
560 cpdef bint eq(self, Posit16 other):
561 return cposit.p16_eq(self._c_posit, other._c_posit)
562
563 cpdef bint le(self, Posit16 other):
564 return cposit.p16_le(self._c_posit, other._c_posit)
565
566 cpdef bint lt(self, Posit16 other):
567 return cposit.p16_lt(self._c_posit, other._c_posit)
568
569 def __lt__(self, Posit16 other):
570 return self.lt(other)
571
572 def __le__(self, Posit16 other):
573 return self.le(other)
574
575 def __eq__(self, Posit16 other):
576 return self.eq(other)
577
578 def __ne__(self, Posit16 other):
579 return not self.eq(other)
580
581 def __ge__(self, Posit16 other):
582 return other.le(self)
583
584 def __gt__(self, Posit16 other):
585 return other.lt(self)
586
587 # conversion to other posit types
588
589 cpdef to_p8(self):
590 cdef cposit.posit8_t f = cposit.p16_to_p8(self._c_posit)
591 return Posit8.from_c_posit(f)
592
593 cpdef to_quire(self):
594 cdef cposit.quire16_t f
595 cposit.q16_clr(f)
596 f = cposit.q16_fdp_add(f, self._c_posit, _p16_one)
597 return Quire16.from_c_quire(f)
598
599
600 cdef class Quire16:
601
602 # the wrapped quire value
603 cdef cposit.quire16_t _c_quire
604
605 # factory function constructors that bypass init
606
607 @staticmethod
608 cdef Quire16 from_c_quire(cposit.quire16_t f):
609 """Factory function to create a Quire16 object directly from
610 a C quire16_t.
611 """
612 cdef Quire16 obj = Quire16.__new__(Quire16)
613 obj._c_quire = f
614 return obj
615
616 @staticmethod
617 def from_bits(value):
618 """Factory function to create a Quire16 object from a bit pattern
619 represented as an integer.
620 """
621 cdef Quire16 obj = Quire16.__new__(Quire16)
622
623 if not isinstance(value, int):
624 raise TypeError('expecting int, got {}'.format(repr(value)))
625
626 for idx in range(1, -1, -1):
627 obj._c_quire.v[idx] = value & 0xffffffffffffffff
628 value >>= 64
629
630 if not (value == 0):
631 raise OverflowError('value too large to fit in uint64_t[2]')
632
633 return obj
634
635 # convenience interface for use inside Python
636
637 def __init__(self, value):
638 if isinstance(value, int):
639 for idx in range(1, -1, -1):
640 self._c_quire.v[idx] = value & 0xffffffffffffffff
641 value >>= 64
642 if not (value == 0):
643 raise OverflowError('value too large to fit in uint64_t[2]')
644 else:
645 f = float(value)
646 cposit.q16_clr(self._c_quire)
647 self._c_quire = cposit.q16_fdp_add(self._c_quire, cposit.convertDoubleToP16(f), _p16_one)
648
649 def __float__(self):
650 return cposit.convertP16ToDouble(cposit.q16_to_p16(self._c_quire))
651
652 def __int__(self):
653 return int(cposit.convertP16ToDouble(cposit.q16_to_p16(self._c_quire)))
654
655 def __str__(self):
656 return repr(cposit.convertP16ToDouble(cposit.q16_to_p16(self._c_quire)))
657
658 def __repr__(self):
659 return 'Quire16(' + repr(cposit.convertP16ToDouble(cposit.q16_to_p16(self._c_quire))) + ')'
660
661 def get_bits(self):
662 b = 0
663 for u in self._c_quire.v:
664 b <<= 64
665 b |= u
666 return b
667 bits = property(get_bits)
668
669 # arithmetic
670
671 cpdef Quire16 qam(self, Posit16 a1, Posit16 a2):
672 cdef cposit.quire16_t f = cposit.q16_fdp_add(self._c_quire, a1._c_posit, a2._c_posit)
673 return Quire16.from_c_quire(f)
674
675 cpdef Quire16 qsm(self, Posit16 a1, Posit16 a2):
676 cdef cposit.quire16_t f = cposit.q16_fdp_sub(self._c_quire, a1._c_posit, a2._c_posit)
677 return Quire16.from_c_quire(f)
678
679 cpdef void iqam(self, Posit16 a1, Posit16 a2):
680 self._c_quire = cposit.q16_fdp_add(self._c_quire, a1._c_posit, a2._c_posit)
681
682 cpdef void iqsm(self, Posit16 a1, Posit16 a2):
683 self._c_quire = cposit.q16_fdp_sub(self._c_quire, a1._c_posit, a2._c_posit)
684
685 cpdef void iclr(self):
686 cposit.q16_clr(self._c_quire)
687
688 # conversion back to posit
689
690 cpdef Posit16 to_posit(self):
691 cpdef cposit.posit16_t f = cposit.q16_to_p16(self._c_quire)
692 return Posit16.from_c_posit(f)
693
694
695 # external, non-method arithmetic
696
697 cpdef Posit16 p16_neg(Posit16 a1):
698 cdef cposit.posit16_t f = _p16_neg(a1._c_posit)
699 return Posit16.from_c_posit(f)
700
701 cpdef Posit16 p16_abs(Posit16 a1):
702 cdef cposit.posit16_t f = _p16_abs(a1._c_posit)
703 return Posit16.from_c_posit(f)
704
705 cpdef Posit16 p16_round(Posit16 a1):
706 cdef cposit.posit16_t f = cposit.p16_roundToInt(a1._c_posit)
707 return Posit16.from_c_posit(f)
708
709 cpdef Posit16 p16_add(Posit16 a1, Posit16 a2):
710 cdef cposit.posit16_t f = cposit.p16_add(a1._c_posit, a2._c_posit)
711 return Posit16.from_c_posit(f)
712
713 cpdef Posit16 p16_sub(Posit16 a1, Posit16 a2):
714 cdef cposit.posit16_t f = cposit.p16_sub(a1._c_posit, a2._c_posit)
715 return Posit16.from_c_posit(f)
716
717 cpdef Posit16 p16_mul(Posit16 a1, Posit16 a2):
718 cdef cposit.posit16_t f = cposit.p16_mul(a1._c_posit, a2._c_posit)
719 return Posit16.from_c_posit(f)
720
721 cpdef Posit16 p16_fma(Posit16 a1, Posit16 a2, Posit16 a3):
722 cdef cposit.posit16_t f = cposit.p16_mulAdd(a1._c_posit, a2._c_posit, a3._c_posit)
723 return Posit16.from_c_posit(f)
724
725 cpdef Posit16 p16_fam(Posit16 a3, Posit16 a1, Posit16 a2):
726 cdef cposit.posit16_t f = cposit.p16_mulAdd(a1._c_posit, a2._c_posit, a3._c_posit)
727 return Posit16.from_c_posit(f)
728
729 cpdef Posit16 p16_div(Posit16 a1, Posit16 a2):
730 cdef cposit.posit16_t f = cposit.p16_div(a1._c_posit, a2._c_posit)
731 return Posit16.from_c_posit(f)
732
733 cpdef Posit16 p16_sqrt(Posit16 a1):
734 cdef cposit.posit16_t f = cposit.p16_sqrt(a1._c_posit)
735 return Posit16.from_c_posit(f)
736
737 cpdef bint p16_eq(Posit16 a1, Posit16 a2):
738 return cposit.p16_eq(a1._c_posit, a2._c_posit)
739
740 cpdef bint p16_le(Posit16 a1, Posit16 a2):
741 return cposit.p16_le(a1._c_posit, a2._c_posit)
742
743 cpdef bint p16_lt(Posit16 a1, Posit16 a2):
744 return cposit.p16_lt(a1._c_posit, a2._c_posit)
745
746 cpdef Posit8 p16_to_p8(Posit16 a1):
747 cdef cposit.posit8_t f = cposit.p16_to_p8(a1._c_posit)
748 return Posit8.from_c_posit(f)
749
750 cpdef Quire16 p16_to_q16(Posit16 a1):
751 cdef cposit.quire16_t f
752 cposit.q16_clr(f)
753 f = cposit.q16_fdp_add(f, a1._c_posit, _p16_one)
754 return Quire16.from_c_quire(f)
755
756 cpdef Quire16 q16_qam(Quire16 a3, Posit16 a1, Posit16 a2):
757 cdef cposit.quire16_t f = cposit.q16_fdp_add(a3._c_quire, a1._c_posit, a2._c_posit)
758 return Quire16.from_c_quire(f)
759
760 cpdef Quire16 q16_qsm(Quire16 a3, Posit16 a1, Posit16 a2):
761 cdef cposit.quire16_t f = cposit.q16_fdp_sub(a3._c_quire, a1._c_posit, a2._c_posit)
762 return Quire16.from_c_quire(f)
763
764 cpdef Posit16 q16_to_p16(Quire16 a1):
765 cpdef cposit.posit16_t f = cposit.q16_to_p16(a1._c_quire)
766 return Posit16.from_c_posit(f)