1 #pragma once
2 // posit_decoded.hpp: definition of arbitrary posit number configurations
3 //
4 // Copyright (C) 2017-2018 Stillwater Supercomputing, Inc.
5 //
6 // This file is part of the universal numbers project, which is released under an MIT Open Source license.
7 
8 #include <cmath>
9 #include <cassert>
10 #include <iostream>
11 #include <limits>
12 #include <regex>
13 
14 // to yield a fast regression environment for productive development
15 // we want to leverage the IEEE floating point hardware available on x86 and ARM.
16 // Problem is that neither support a true IEEE 128bit long double.
17 // x86 provides a irreproducible x87 80bit format that is susceptible to inconsistent results due to multi-programming
18 // ARM only provides a 64bit double format.
19 // This conditional section is intended to create a unification of a long double format across
20 // different compilation environments that creates a fast verification environment through consistent hw support.
21 // Another option is to use a multiprecision floating point emulation layer.
22 // Side note: the performance of the bitset<> manipulation is slower than a multiprecision floating point implementation
23 // so this comment is talking about issues that will come to pass when we transition to a high performance sw emulation.
24 
25 #if defined(__clang__)
26 /* Clang/LLVM. ---------------------------------------------- */
27 typedef __128bitdd double_double;
28 
29 #elif defined(__ICC) || defined(__INTEL_COMPILER)
30 /* Intel ICC/ICPC. ------------------------------------------ */
31 typedef __128bitdd double_double;
32 
33 #elif defined(__GNUC__) || defined(__GNUG__)
34 /* GNU GCC/G++. --------------------------------------------- */
35 typedef __128bitdd double_double;
36 
37 #elif defined(__HP_cc) || defined(__HP_aCC)
38 /* Hewlett-Packard C/aC++. ---------------------------------- */
39 
40 #elif defined(__IBMC__) || defined(__IBMCPP__)
41 /* IBM XL C/C++. -------------------------------------------- */
42 
43 #elif defined(_MSC_VER)
44 /* Microsoft Visual Studio. --------------------------------- */
45 typedef __128bitdd double_double;
46 
47 #elif defined(__PGI)
48 /* Portland Group PGCC/PGCPP. ------------------------------- */
49 
50 #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
51 /* Oracle Solaris Studio. ----------------------------------- */
52 
53 #endif
54 
55 // Posits encode error conditions as NaR (Not a Real), propagating the error through arithmetic operations is preferred
56 #include "exceptions.hpp"
57 #include "../native/bit_functions.hpp"
58 #include "../bitblock/bitblock.hpp"
59 #include "trace_constants.hpp"
60 #include "../value/value.hpp"
61 #include "fraction.hpp"
62 #include "exponent.hpp"
63 #include "regime.hpp"
64 #include "posit_functions.hpp"
65 
66 namespace sw {
67 	namespace unum {
68 
69 		// Forward definitions
70 		template<size_t nbits, size_t es> class posit;
71 		template<size_t nbits, size_t es> posit<nbits, es> abs(const posit<nbits, es>& p);
72 		template<size_t nbits, size_t es> posit<nbits, es> sqrt(const posit<nbits, es>& p);
73 		template<size_t nbits, size_t es> constexpr posit<nbits, es>& minpos(posit<nbits, es>& p);
74 		template<size_t nbits, size_t es> constexpr posit<nbits, es>& maxpos(posit<nbits, es>& p);
75 		template<size_t nbits, size_t es> constexpr posit<nbits, es> minpos();
76 		template<size_t nbits, size_t es> constexpr posit<nbits, es> maxpos();
77 
78 		// class posit represents posit numbers of arbitrary configuration and their basic arithmetic operations (add/sub, mul/div)
79 		template<size_t _nbits, size_t _es>
80 		class posit_decoded {
81 
82 			static_assert(_es + 2 <= _nbits, "Value for 'es' is too large for this 'nbits' value");
83 		//	static_assert(sizeof(long double) == 16, "Posit library requires compiler support for 128 bit long double.");
84 		//	static_assert((sizeof(long double) == 16) && (std::numeric_limits<long double>::digits < 113), "C++ math library for long double does not support 128-bit quad precision floats.");
85 
86 
87 		public:
88 			static constexpr size_t nbits   = _nbits;
89 			static constexpr size_t es      = _es;
90 			static constexpr size_t sbits   = 1;                          // number of sign bits:     specified
91 			static constexpr size_t rbits   = nbits - sbits;              // maximum number of regime bits:   derived
92 			static constexpr size_t ebits   = es;                         // maximum number of exponent bits: specified
93 			static constexpr size_t fbits   = (rbits <= 2 ? nbits - 2 - es : nbits - 3 - es);             // maximum number of fraction bits: derived
94 			static constexpr size_t fhbits  = fbits + 1;                  // maximum number of fraction + one hidden bit
95 
96 			static constexpr size_t abits   = fhbits + 3;                 // size of the addend
97 			static constexpr size_t mbits   = 2 * fhbits;                 // size of the multiplier output
98 			static constexpr size_t divbits = 3 * fhbits + 4;             // size of the divider output
99 
posit_decoded()100 			posit_decoded() { setzero();  }
101 
102 			posit_decoded(const posit_decoded&) = default;
103 			posit_decoded(posit_decoded&&) = default;
104 
105 			posit_decoded& operator=(const posit_decoded&) = default;
106 			posit_decoded& operator=(posit_decoded&&) = default;
107 
108 			/// Construct posit from its components
posit_decoded(bool sign,const regime<nbits,es> & r,const exponent<nbits,es> & e,const fraction<fbits> & f)109 			posit_decoded(bool sign, const regime<nbits, es>& r, const exponent<nbits, es>& e, const fraction<fbits>& f)
110 				  : _sign(sign), _regime(r), _exponent(e), _fraction(f) {
111 				// generate raw bit representation
112 				_raw_bits = _sign ? twos_complement(collect()) : collect();
113 				_raw_bits.set(nbits - 1, _sign);
114 			}
115 			/// Construct posit from raw bits
116 			//posit_decoded(const std::bitset<nbits>& raw_bits)     { *this = set(raw_bits); }
117 
118 			// initializers for native types
posit_decoded(const signed char initial_value)119 			posit_decoded(const signed char initial_value)        { *this = initial_value; }
posit_decoded(const short initial_value)120 			posit_decoded(const short initial_value)              { *this = initial_value; }
posit_decoded(const int initial_value)121 			posit_decoded(const int initial_value)                { *this = initial_value; }
posit_decoded(const long initial_value)122 			posit_decoded(const long initial_value)               { *this = initial_value; }
posit_decoded(const long long initial_value)123 			posit_decoded(const long long initial_value)          { *this = initial_value; }
posit_decoded(const char initial_value)124 			posit_decoded(const char initial_value)               { *this = initial_value; }
posit_decoded(const unsigned short initial_value)125 			posit_decoded(const unsigned short initial_value)     { *this = initial_value; }
posit_decoded(const unsigned int initial_value)126 			posit_decoded(const unsigned int initial_value)       { *this = initial_value; }
posit_decoded(const unsigned long initial_value)127 			posit_decoded(const unsigned long initial_value)      { *this = initial_value; }
posit_decoded(const unsigned long long initial_value)128 			posit_decoded(const unsigned long long initial_value) { *this = initial_value; }
posit_decoded(const float initial_value)129 			posit_decoded(const float initial_value)              { *this = initial_value; }
posit_decoded(const double initial_value)130 			posit_decoded(const double initial_value)             { *this = initial_value; }
posit_decoded(const long double initial_value)131 			posit_decoded(const long double initial_value)        { *this = initial_value; }
132 
133 			// assignment operators for native types
operator =(const signed char rhs)134 			posit_decoded& operator=(const signed char rhs) {
135 				value<8*sizeof(signed char)-1> v(rhs);
136 				if (v.iszero()) {
137 					setzero();
138 					return *this;
139 				}
140 				else if (v.isneg()) {
141 					convert(v);
142 					take_2s_complement();
143 				}
144 				else {
145 					convert(v);
146 				}
147 				return *this;
148 			}
operator =(const short rhs)149 			posit_decoded& operator=(const short rhs) {
150 				value<8*sizeof(short)-1> v(rhs);
151 				if (v.iszero()) {
152 					setzero();
153 					return *this;
154 				}
155 				else if (v.isneg()) {
156 					convert(v);
157 					take_2s_complement();
158 				}
159 				else {
160 					convert(v);
161 				}
162 				return *this;
163 			}
operator =(const int rhs)164 			posit_decoded& operator=(const int rhs) {
165 				value<8*sizeof(int)-1> v(rhs);
166 				if (v.iszero()) {
167 					setzero();
168 					return *this;
169 				}
170 				else if (v.isneg()) {
171 					convert(v);
172 					take_2s_complement();
173 				}
174 				else {
175 					convert(v);
176 				}
177 				return *this;
178 			}
operator =(const long rhs)179 			posit_decoded& operator=(const long rhs) {
180 				value<8*sizeof(long)> v(rhs);
181 				if (v.iszero()) {
182 					setzero();
183 					return *this;
184 				}
185 				else if (v.isneg()) {
186 					convert(v);
187 					take_2s_complement();
188 				}
189 				else {
190 					convert(v);
191 				}
192 				return *this;
193 			}
operator =(const long long rhs)194 			posit_decoded& operator=(const long long rhs) {
195 				value<8*sizeof(long long)-1> v(rhs);
196 				if (v.iszero()) {
197 					setzero();
198 					return *this;
199 				}
200 				else if (v.isneg()) {
201 					convert(v);
202 					take_2s_complement();
203 				}
204 				else {
205 					convert(v);
206 				}
207 				return *this;
208 			}
operator =(const char rhs)209 			posit_decoded& operator=(const char rhs) {
210 				value<8*sizeof(char)> v(rhs);
211 				if (v.iszero()) {
212 					setzero();
213 					return *this;
214 				}
215 				else if (v.isneg()) {
216 					convert(v);
217 					take_2s_complement();
218 				}
219 				else {
220 					convert(v);
221 				}
222 				return *this;
223 			}
operator =(const unsigned short rhs)224 			posit_decoded& operator=(const unsigned short rhs) {
225 				value<8*sizeof(unsigned short)> v(rhs);
226 				if (v.iszero()) {
227 					setzero();
228 					return *this;
229 				}
230 				// else if (v.isneg()) {
231 				// 	convert(v);
232 				// 	take_2s_complement();
233 				// }
234 				else {
235 					convert(v);
236 				}
237 				return *this;
238 			}
operator =(const unsigned int rhs)239 			posit_decoded& operator=(const unsigned int rhs) {
240 				value<8*sizeof(unsigned int)> v(rhs);
241 				if (v.iszero()) {
242 					setzero();
243 					return *this;
244 				}
245 				// else if (v.isneg()) {
246 				// 	convert(v);
247 				// 	take_2s_complement();
248 				// }
249 				else {
250 					convert(v);
251 				}
252 				return *this;
253 			}
operator =(const unsigned long rhs)254 			posit_decoded& operator=(const unsigned long rhs) {
255 				value<8*sizeof(unsigned long)> v(rhs);
256 				if (v.iszero()) {
257 					setzero();
258 					return *this;
259 				}
260 				else {
261 					convert(v);
262 				}
263 				// convert(v);
264 				return *this;
265 			}
operator =(const unsigned long long rhs)266 			posit_decoded& operator=(const unsigned long long rhs) {
267 				value<8*sizeof(unsigned long long)> v(rhs);
268 				if (v.iszero()) {
269 					setzero();
270 					return *this;
271 				}
272 				else {
273 					convert(v);
274 				}
275 				// convert(v);
276 				return *this;
277 			}
operator =(const float rhs)278 			posit_decoded& operator=(const float rhs) {
279 				return float_assign(rhs);
280 			}
operator =(const double rhs)281 			posit_decoded& operator=(const double rhs) {
282 				return float_assign(rhs);
283 			}
operator =(const long double rhs)284 			posit_decoded& operator=(const long double rhs) {
285        				return float_assign(rhs);
286 			}
287 
288 			// assignment for value type
289 			template<size_t vbits>
operator =(const value<vbits> & rhs)290 			posit_decoded& operator=(const value<vbits>& rhs) {
291 				clear();
292 				convert(rhs);
293 				return *this;
294 			}
295 			// prefix operator
operator -() const296 			posit_decoded<nbits, es> operator-() const {
297 				if (iszero()) {
298 					return *this;
299 				}
300 				if (isnar()) {
301 					return *this;
302 				}
303 				posit<nbits, es> negated(0);  // TODO: artificial initialization to pass -Wmaybe-uninitialized
304 				bitblock<nbits> raw_bits = twos_complement(_raw_bits);
305 				negated.set(raw_bits);
306 				bool local_sign;
307 				regime<nbits, es> local_regime;
308 				exponent<nbits, es> local_exponent;
309 				fraction<fbits> local_fraction;
310 				decode(raw_bits, local_sign, local_regime, local_exponent, local_fraction);
311 				// TODO: how to get rid of this decode step?
312 				return negated;
313 			}
314 
315 			// we model a hw pipeline with register assignments, functional block, and conversion
operator +=(const posit_decoded & rhs)316 			posit_decoded<nbits, es>& operator+=(const posit_decoded& rhs) {
317 				if (_trace_add) std::cout << "---------------------- ADD -------------------" << std::endl;
318 				// special case handling of the inputs
319 				if (isnar() || rhs.isnar()) {
320 					setnar();
321 					return *this;
322 				}
323 				if (iszero()) {
324 					*this = rhs;
325 					return *this;
326 				}
327 				if (rhs.iszero()) return *this;
328 
329 				// arithmetic operation
330 				value<abits + 1> sum;
331 				value<fbits> a, b;
332 				// transform the inputs into (sign,scale,fraction) triples
333 				normalize(a);
334 				rhs.normalize(b);
335 				module_add<fbits,abits>(a, b, sum);		// add the two inputs
336 
337 				// special case handling of the result
338 				if (sum.iszero()) {
339 					setzero();
340 				}
341 				else if (sum.isinf()) {
342 					setnar();
343 				}
344 				else {
345 					convert(sum);
346 				}
347 				return *this;
348 			}
operator +=(double rhs)349 			posit_decoded<nbits, es>& operator+=(double rhs) {
350 				return *this += posit<nbits, es>(rhs);
351 			}
operator -=(const posit_decoded & rhs)352 			posit_decoded<nbits, es>& operator-=(const posit_decoded& rhs) {
353 				if (_trace_sub) std::cout << "---------------------- SUB -------------------" << std::endl;
354 				// special case handling of the inputs
355 				if (isnar() || rhs.isnar()) {
356 					setnar();
357 					return *this;
358 				}
359 				if (iszero()) {
360 					*this = -rhs;
361 					return *this;
362 				}
363 				if (rhs.iszero()) return *this;
364 
365 				// arithmetic operation
366 				value<abits + 1> difference;
367 				value<fbits> a, b;
368 				// transform the inputs into (sign,scale,fraction) triples
369 				normalize(a);
370 				rhs.normalize(b);
371 				module_subtract<fbits, abits>(a, b, difference);	// add the two inputs
372 
373 				// special case handling of the result
374 				if (difference.iszero()) {
375 					setzero();
376 				}
377 				else if (difference.isinf()) {
378 					setnar();
379 				}
380 				else {
381 					convert(difference);
382 				}
383 				return *this;
384 			}
operator -=(double rhs)385 			posit_decoded<nbits, es>& operator-=(double rhs) {
386 				return *this -= posit<nbits, es>(rhs);
387 			}
operator *=(const posit_decoded & rhs)388 			posit_decoded<nbits, es>& operator*=(const posit_decoded& rhs) {
389 				static_assert(fhbits > 0, "posit configuration does not support multiplication");
390 				if (_trace_mul) std::cout << "---------------------- MUL -------------------" << std::endl;
391 				// special case handling of the inputs
392 				if (isnar() || rhs.isnar()) {
393 					setnar();
394 					return *this;
395 				}
396 				if (iszero() || rhs.iszero()) {
397 					setzero();
398 					return *this;
399 				}
400 
401 				// arithmetic operation
402 				value<mbits> product;
403 				value<fbits> a, b;
404 				// transform the inputs into (sign,scale,fraction) triples
405 				normalize(a);
406 				rhs.normalize(b);
407 
408 				module_multiply(a, b, product);    // multiply the two inputs
409 
410 				// special case handling on the output
411 				if (product.iszero()) {
412 					setzero();
413 				}
414 				else if (product.isinf()) {
415 					setnar();
416 				}
417 				else {
418 					convert(product);
419 				}
420 				return *this;
421 			}
operator *=(double rhs)422 			posit_decoded<nbits, es>& operator*=(double rhs) {
423 				return *this *= posit<nbits, es>(rhs);
424 			}
operator /=(const posit_decoded & rhs)425 			posit_decoded<nbits, es>& operator/=(const posit_decoded& rhs) {
426 				if (_trace_div) std::cout << "---------------------- DIV -------------------" << std::endl;
427 				// since we are encoding error conditions as NaR (Not a Real), we need to process that condition first
428 				if (rhs.iszero()) {
429 					setnar();
430 					return *this;
431 					//throw divide_by_zero{};    not throwing is a quiet signalling NaR
432 				}
433 				if (rhs.isnar()) {
434 					setnar();
435 					return *this;
436 				}
437 				if (iszero() || isnar()) {
438 					return *this;
439 				}
440 
441 				value<divbits> ratio;
442 				value<fbits> a, b;
443 				// transform the inputs into (sign,scale,fraction) triples
444 				normalize(a);
445 				rhs.normalize(b);
446 
447 				module_divide(a, b, ratio);
448 
449 				// special case handling on the output
450 				if (ratio.iszero()) {
451 					setzero();  // this can't happen as we would project back onto minpos
452 				}
453 				else if (ratio.isinf()) {
454 					setnar();  // this can't happen as we would project back onto maxpos
455 				}
456 				else {
457 					convert<divbits>(ratio);
458 				}
459 
460 				return *this;
461 			}
operator /=(double rhs)462 			posit_decoded<nbits, es>& operator/=(double rhs) {
463 				return *this /= posit<nbits, es>(rhs);
464 			}
operator ++()465 			posit_decoded<nbits, es>& operator++() {
466 				increment_posit();
467 				return *this;
468 			}
operator ++(int)469 			posit_decoded<nbits, es> operator++(int) {
470 				posit_decoded tmp(*this);
471 				operator++();
472 				return tmp;
473 			}
operator --()474 			posit_decoded<nbits, es>& operator--() {
475 				decrement_posit();
476 				return *this;
477 			}
operator --(int)478 			posit_decoded<nbits, es> operator--(int) {
479 				posit_decoded tmp(*this);
480 				operator--();
481 				return tmp;
482 			}
483 
reciprocate() const484 			posit_decoded<nbits, es> reciprocate() const {
485 				if (_trace_reciprocate) std::cout << "-------------------- RECIPROCATE ----------------" << std::endl;
486 				posit_decoded<nbits, es> p;
487 				// special case of NaR (Not a Real)
488 				if (isnar()) {
489 					p.setnar();
490 					return p;
491 				}
492 				if (iszero()) {
493 					p.setnar();
494 					return p;
495 				}
496 				// compute the reciprocal
497 				bool old_sign = _sign;
498 				bitblock<nbits> raw_bits;
499 				if (isPowerOf2()) {
500 					raw_bits = twos_complement(_raw_bits);
501 					raw_bits.set(nbits-1, old_sign);
502 					p.set(raw_bits);
503 				}
504 				else {
505 					constexpr size_t operand_size = fhbits;
506 					bitblock<operand_size> one;
507 					one.set(operand_size - 1, true);
508 					bitblock<operand_size> frac;
509 					copy_into(_fraction.get(), 0, frac);
510 					frac.set(operand_size - 1, true);
511 					constexpr size_t reciprocal_size = 3 * fbits + 4;
512 					bitblock<reciprocal_size> reciprocal;
513 					divide_with_fraction(one, frac, reciprocal);
514 					if (_trace_reciprocate) {
515 						std::cout << "one    " << one << std::endl;
516 						std::cout << "frac   " << frac << std::endl;
517 						std::cout << "recip  " << reciprocal << std::endl;
518 					}
519 
520 					// radix point falls at operand size == reciprocal_size - operand_size - 1
521 					reciprocal <<= operand_size - 1;
522 					if (_trace_reciprocate) std::cout << "frac   " << reciprocal << std::endl;
523 					int new_scale = -scale();
524 					int msb = findMostSignificantBit(reciprocal);
525 					if (msb > 0) {
526 						int shift = reciprocal_size - msb;
527 						reciprocal <<= shift;
528 						new_scale -= (shift-1);
529 						if (_trace_reciprocate) std::cout << "result " << reciprocal << std::endl;
530 					}
531 					//std::bitset<operand_size> tr;
532 					//truncate(reciprocal, tr);
533 					//std::cout << "tr     " << tr << std::endl;
534 					p.convert(_sign, new_scale, reciprocal);
535 				}
536 				return p;
537 			}
538 			// SELECTORS
isnar() const539 			bool isnar() const {
540 				return (_sign && _regime.iszero());
541 			}
iszero() const542 			bool iszero() const {
543 				return (!_sign && _regime.iszero());
544 			}
isone() const545 			bool isone() const { // pattern 010000....
546 				bitblock<nbits> tmp(_raw_bits);
547 				tmp.set(nbits - 2, false);
548 				bool oneBitSet = tmp.none();
549 				return !_sign && oneBitSet;
550 			}
isminusone() const551 			bool isminusone() const { // pattern 110000...
552 				bitblock<nbits> tmp(_raw_bits);
553 				tmp.set(nbits - 1, false);
554 				tmp.set(nbits - 2, false);
555 				bool oneBitSet = tmp.none();
556 				return _sign && oneBitSet;
557 			}
isneg() const558 			bool isneg() const {
559 				return _sign;
560 			}
ispos() const561 			bool ispos() const {
562 				return !_sign;
563 			}
isPowerOf2() const564 			bool isPowerOf2() const {
565 				return _fraction.none();
566 			}
567 
sign_value() const568 			inline int	      sign_value() const {
569 				return (_sign ? -1 : 1);
570 			}
regime_value() const571 			inline double   regime_value() const {
572 				return _regime.value();
573 			}
exponent_value() const574 			inline double exponent_value() const {
575 				return _exponent.value();
576 			}
fraction_value() const577 			inline double fraction_value() const {
578 				return _fraction.value();
579 			}
580 
581 			// how many shifts represent the regime?
582 			// regime = useed ^ k = 2 ^ (k*(2 ^ e))
583 			// scale = useed ^ k * 2^e
get_scale() const584 			int                get_scale() const { return _regime.scale() + _exponent.scale(); }
get_sign() const585 			bool               get_sign() const { return _sign;  }
get_regime() const586 			regime<nbits, es>  get_regime() const {	return _regime;	}
regime_k() const587 			int				   regime_k() const { return _regime.regime_k(); }
get_exponent() const588 			exponent<nbits,es> get_exponent() const { return _exponent;	}
get_fraction() const589 			fraction<fbits>    get_fraction() const { return _fraction;	}
get() const590 			bitblock<nbits>    get() const { return _raw_bits; }
get_decoded() const591 			bitblock<nbits>    get_decoded() const {
592 				bitblock<rbits> r = _regime.get();
593 				size_t nrRegimeBits = _regime.nrBits();
594 				bitblock<es> e = _exponent.get();
595 				size_t nrExponentBits = _exponent.nrBits();
596 				bitblock<fbits> f = _fraction.get();
597 				size_t nrFractionBits = _fraction.nrBits();
598 
599 				bitblock<nbits> _Bits;
600 				_Bits.set(nbits - 1, _sign);
601 				int msb = nbits - 2;
602 				for (size_t i = 0; i < nrRegimeBits; i++) {
603 					_Bits.set(std::size_t(msb--), r[nbits - 2 - i]);
604 				}
605 				if (msb < 0)
606 							return _Bits;
607 				for (size_t i = 0; i < nrExponentBits && msb >= 0; i++) {
608 					_Bits.set(std::size_t(msb--), e[es - 1 - i]);
609 				}
610 				if (msb < 0) return _Bits;
611 				for (size_t i = 0; i < nrFractionBits && msb >= 0; i++) {
612 					_Bits.set(std::size_t(msb--), f[fbits - 1 - i]);
613 				}
614 				return _Bits;
615 			}
get_quadrant() const616 			std::string        get_quadrant() const {
617 				posit<nbits, es> pOne(1), pMinusOne(-1);
618 				if (_sign) {
619 					// west
620 					if (*this > pMinusOne) {
621 						return "SW";
622 					}
623 					else {
624 						return "NW";
625 					}
626 				}
627 				else {
628 					// east
629 					if (*this < pOne) {
630 						return "SE";
631 					}
632 					else {
633 						return "NE";
634 					}
635 				}
636 			}
get_encoding_as_integer() const637 			long long          get_encoding_as_integer() const {
638 				if (nbits > 64) throw "encoding cannot be represented by a 64bit integer";
639 				long long as_integer = 0;
640 				unsigned long long mask = 1;
641 				for (unsigned i = 0; i < nbits; i++) {
642 					if (_raw_bits[i]) as_integer |= mask;
643 					mask <<= 1;
644 				}
645 				return as_integer;
646 			}
647 			// MODIFIERS
clear()648 			inline void clear() {
649 				_sign = false;
650 				_regime.reset();
651 				_exponent.reset();
652 				_fraction.reset();
653 				_raw_bits.reset();
654 			}
setzero()655 			inline void setzero() {
656 				_sign = false;
657 				_regime.setzero();
658 				_exponent.reset();
659 				_fraction.reset();
660 				_raw_bits.reset();
661 			}
setnar()662 			inline void setnar() {
663 				_sign = true;
664 				_regime.setinf();
665 				_exponent.reset();
666 				_fraction.reset();
667 				_raw_bits.reset();
668 				_raw_bits.set(nbits - 1, true);
669 			}
set(const bitblock<nbits> & raw_bits)670 			posit_decoded<nbits, es>& set(const bitblock<nbits>& raw_bits) {
671 				_raw_bits = raw_bits;
672 				// decode to cache the posit number interpretation
673 				decode(raw_bits, _sign, _regime, _exponent, _fraction);
674 				return *this;
675 			}
676 			// Set the raw bits of the posit given an unsigned value starting from the lsb
677 			// handy for enumerating a posit state space
set_raw_bits(uint64_t value)678 			posit_decoded<nbits,es>& set_raw_bits(uint64_t value) {
679 				clear();
680 				bitblock<nbits> raw_bits;
681 				uint64_t mask = 1;
682 				for ( size_t i = 0; i < nbits; i++ ) {
683 					raw_bits.set(i,(value & mask));
684 					mask <<= 1;
685 				}
686 				_raw_bits = raw_bits;
687 				// decode to cache the posit number interpretation
688 				decode(raw_bits, _sign, _regime, _exponent, _fraction);
689 				return *this;
690 			}
691 
parse(std::string & txt)692 			bool parse(std::string& txt) {
693 				bool bSuccess = false;
694 				// check if the txt is of the native posit form: nbits.esXhexvalue
695 				std::regex posit_regex("[\\d]+\\.[012345][xX][\\w]+[p]*");
696 				if (std::regex_match(txt, posit_regex)) {
697 					// found a posit representation
698 					std::string nbitsStr, esStr, bitStr;
699 					auto it = txt.begin();
700 					for (; it != txt.end(); it++) {
701 						if (*it == '.') break;
702 						nbitsStr.append(1, *it);
703 					}
704 					for (it++; it != txt.end(); it++) {
705 						if (*it == 'x' || *it == 'X') break;
706 						esStr.append(1, *it);
707 					}
708 					for (it++; it != txt.end(); it++) {
709 						if (*it == 'p') break;
710 						bitStr.append(1, *it);
711 					}
712 					unsigned long long raw;
713 					std::istringstream ss(bitStr);
714 					ss >> std::hex >> raw;
715 					//std::cout << "[" << nbitsStr << "] [" << esStr << "] [" << bitStr << "] = " << raw << std::endl;
716 					set_raw_bits(raw);  // TODO: this takes the least significant bits, but we want to take the most significant bits
717 					bSuccess = true;
718 				}
719 				else {
720 					// assume it is a float/double/long double representation
721 					std::istringstream ss(txt);
722 					double d;
723 					ss >> d;
724 					*this = d;
725 					bSuccess = true;
726 				}
727 				return bSuccess;
728 			}
729 
730 			// Maybe remove explicit, MTL compiles, but we have lots of double computation then
operator long double() const731 			explicit operator long double() const { return to_long_double(); }
operator double() const732 			explicit operator double() const { return to_double(); }
operator float() const733 			explicit operator float() const { return to_float(); }
operator long long() const734 			explicit operator long long() const { return to_long_long(); }
operator long() const735 			explicit operator long() const { return to_long(); }
operator int() const736 			explicit operator int() const { return to_int(); }
operator unsigned long long() const737 			explicit operator unsigned long long() const { return to_long_long(); }
operator unsigned long() const738 			explicit operator unsigned long() const { return to_long(); }
operator unsigned int() const739 			explicit operator unsigned int() const { return to_int(); }
740 
741 			// currently, size is tied to fbits size of posit config. Is there a need for a case that captures a user-defined sized fraction?
convert_to_scientific_notation() const742 			value<fbits> convert_to_scientific_notation() const {
743 				return value<fbits>(_sign, scale(), get_fraction().get(), iszero(), isnar());
744 			}
to_value() const745 			value<fbits> to_value() const {
746 				return value<fbits>(_sign, scale(), get_fraction().get(), iszero(), isnar());
747 			}
normalize(value<fbits> & v) const748 			void normalize(value<fbits>& v) const {
749 				v.set(_sign, get_scale(), _fraction.get(), iszero(), isnar());
750 			}
751 			template<size_t tgt_fbits>
normalize_to(value<tgt_fbits> & v) const752 			void normalize_to(value<tgt_fbits>& v) const {
753 				bitblock<tgt_fbits> _fr;
754 				bitblock<fbits> _src = _fraction.get();
755 				int tgt, src;
756 				for (tgt = int(tgt_fbits) - 1, src = int(fbits) - 1; tgt >= 0 && src >= 0; tgt--, src--) _fr[tgt] = _src[src];
757 				v.set(_sign, get_scale(), _fr, iszero(), isnar());
758 			}
759 			// collect the posit components into a bitset
collect()760 			bitblock<nbits> collect() {
761 				bitblock<rbits> r = _regime.get();
762 				size_t nrRegimeBits = _regime.nrBits();
763 				bitblock<es> e = _exponent.get();
764 				size_t nrExponentBits = _exponent.nrBits();
765 				bitblock<fbits> f = _fraction.get();
766 				size_t nrFractionBits = _fraction.nrBits();
767 				bitblock<nbits> raw_bits;
768 				// collect
769 				raw_bits.set(nbits - 1, _sign);
770 				int msb = int(nbits) - 2;
771 				for (size_t i = 0; i < nrRegimeBits; i++) {
772 					raw_bits.set(msb--, r[nbits - 2 - i]);
773 				}
774 				if (msb >= 0) {
775 					for (size_t i = 0; i < nrExponentBits; i++) {
776 						raw_bits.set(msb--, e[es - 1 - i]);
777 					}
778 				}
779 				if (msb >= 0) {
780 					for (size_t i = 0; i < nrFractionBits; i++) {
781 						raw_bits.set(msb--, f[fbits - 1 - i]);
782 					}
783 				}
784 				return raw_bits;
785 			}
786 			// given a decoded posit, take its 2's complement
take_2s_complement()787 			void take_2s_complement() {
788 				// transform back through 2's complement
789 				bitblock<rbits> r = _regime.get();
790 				size_t nrRegimeBits = _regime.nrBits();
791 				bitblock<es> e = _exponent.get();
792 				size_t nrExponentBits = _exponent.nrBits();
793 				bitblock<fbits> f = _fraction.get();
794 				size_t nrFractionBits = _fraction.nrBits();
795 				bitblock<nbits> raw_bits;
796 				// collect
797 				raw_bits.set(int(nbits) - 1, _sign);
798 				int msb = int(nbits) - 2;
799 				for (size_t i = 0; i < nrRegimeBits; i++) {
800 					raw_bits.set(msb--, r[nbits - 2 - i]);
801 				}
802 				if (msb >= 0) {
803 					for (size_t i = 0; i < nrExponentBits; i++) {
804 						raw_bits.set(msb--, e[es - 1 - i]);
805 					}
806 				}
807 				if (msb >= 0) {
808 					for (size_t i = 0; i < nrFractionBits; i++) {
809 						raw_bits.set(msb--, f[fbits - 1 - i]);
810 					}
811 				}
812 				// transform
813 				raw_bits = twos_complement(raw_bits);
814 				// distribute
815 				bitblock<nbits - 1> regime_bits;
816 				for (unsigned int i = 0; i < nrRegimeBits; i++) {
817 					regime_bits.set(nbits - 2 - i, raw_bits[nbits - 2 - i]);
818 				}
819 				_regime.set(regime_bits, nrRegimeBits);
820 				if (es > 0 && nrExponentBits > 0) {
821 					bitblock<es> exponent_bits;
822 					for (size_t i = 0; i < nrExponentBits; i++) {
823 						exponent_bits.set(es - 1 - i, raw_bits[nbits - 2 - nrRegimeBits - i]);
824 					}
825 					_exponent.set(exponent_bits, nrExponentBits);
826 				}
827 				if (nrFractionBits > 0) {
828 					bitblock<fbits> fraction_bits;   // was nbits - 2
829 					for (size_t i = 0; i < nrFractionBits; i++) {
830 						// fraction_bits.set(nbits - 3 - i, raw_bits[nbits - 2 - nrRegimeBits - nrExponentBits - i]);
831 						fraction_bits.set(fbits - 1 - i, raw_bits[nbits - 2 - nrRegimeBits - nrExponentBits - i]);
832 					}
833 					_fraction.set(fraction_bits, nrFractionBits);
834 				}
835 			}
836 			// scale returns the shifts to normalize the number =  regime + exponent shifts
scale() const837 			int scale() const {
838 				return _regime.scale() + _exponent.scale();
839 			}
exp() const840 			unsigned int exp() const {
841 				return _exponent.scale();
842 			}
843 			// special case check for projecting values between (0, minpos] to minpos and [maxpos, inf) to maxpos
844 			// Returns true if the scale is too small or too large for this posit config
845 			// DO NOT USE the k value for this, as the k value encodes the useed regions and thus is too coarse to make this decision
846 			// Using the scale directly is the simplest expression of the inward projection test.
check_inward_projection_range(int scale)847 			bool check_inward_projection_range(int scale) {
848 				// calculate the max k factor for this posit config
849 				int posit_size = nbits;
850 				int k = scale < 0 ?	-(posit_size - 2) : (posit_size - 2);
851 				return scale < 0 ? scale < k*(1<<es) : scale > k*(1<<es);
852 			}
853 			// project to the next 'larger' posit: this is 'pushing away' from zero, projecting to the next bigger scale
project_up()854 			void project_up() {
855 				bool carry = _fraction.increment();
856 				if (carry && es > 0)
857 					carry = _exponent.increment();
858 				if (carry)
859 							_regime.increment();
860 			}
861 			// step up to the next posit in a lexicographical order
increment_posit()862 			void increment_posit() {
863 				bitblock<nbits> raw(_raw_bits);
864 				increment_bitset(raw);
865 				_raw_bits = raw;
866 				decode(raw, _sign, _regime, _exponent, _fraction);
867 			}
868 			// step down to the previous posit in a lexicographical order
decrement_posit()869 			void decrement_posit() {
870 				bitblock<nbits> raw(_raw_bits);
871 				decrement_bitset(raw);
872 				_raw_bits = raw;
873 				decode(raw, _sign, _regime, _exponent, _fraction);
874 			}
875 
876 			// Generalized version
877 			template <size_t FBits>
convert(const value<FBits> & v)878 			inline void convert(const value<FBits>& v) {
879 				if (v.iszero()) {
880 					setzero();
881 					return;
882 				}
883 				if (v.isnan() || v.isinf()) {
884 					setnar();
885 					return;
886 				}
887 				convert(v.sign(), v.scale(), v.fraction());
888 			}
889 			// convert assumes that ZERO and NaR cases are handled. Only non-zero and non-NaR values are allowed.
890 			template<size_t input_fbits>
convert(bool sign,int scale,bitblock<input_fbits> input_fraction)891 			void convert(bool sign, int scale, bitblock<input_fbits> input_fraction) {
892 				clear();
893 				if (_trace_conversion) std::cout << "------------------- CONVERT ------------------" << std::endl;
894 				if (_trace_conversion) std::cout << "sign " << (sign ? "-1 " : " 1 ") << "scale " << std::setw(3) << scale << " fraction " << input_fraction << std::endl;
895 
896 				// construct the posit
897 				_sign = sign;
898 				int k = calculate_unconstrained_k<nbits, es>(scale);
899 				// interpolation rule checks
900 				if (check_inward_projection_range(scale)) {    // regime dominated
901 					if (_trace_conversion) std::cout << "inward projection" << std::endl;
902 					// we are projecting to minpos/maxpos
903 					_regime.assign_regime_pattern(k);
904 					// store raw bit representation
905 					_raw_bits = _sign ? twos_complement(collect()) : collect();
906 					_raw_bits.set(nbits - 1, _sign);
907 					// we are done
908 					if (_trace_rounding) std::cout << "projection  rounding ";
909 				}
910 				else {
911 					const size_t pt_len = nbits + 3 + es;
912 					bitblock<pt_len> pt_bits;
913 					bitblock<pt_len> regime;
914 					bitblock<pt_len> exponent;
915 					bitblock<pt_len> fraction;
916 					bitblock<pt_len> sticky_bit;
917 
918 					bool s = sign;
919 					int e = scale;
920 					bool r = (e >= 0);
921 
922 					unsigned run = (r ? 1 + (e >> es) : -(e >> es));
923 					regime.set(0, 1 ^ r);
924 					for (unsigned i = 1; i <= run; i++) regime.set(i, r);
925 
926 					unsigned esval = e % (uint32_t(1) << es);
927 					exponent = convert_to_bitblock<pt_len>(esval);
928 					unsigned nf = (unsigned)std::max<int>(0, (nbits + 1) - (2 + run + es));
929 					// TODO: what needs to be done if nf > fbits?
930 					//assert(nf <= input_fbits);
931 					// copy the most significant nf fraction bits into fraction
932 					unsigned lsb = nf <= input_fbits ? 0 : nf - input_fbits;
933 					for (unsigned i = lsb; i < nf; i++) fraction[i] = input_fraction[input_fbits - nf + i];
934 
935 					bool sb = anyAfter(input_fraction, input_fbits - 1 - nf);
936 
937 					// construct the untruncated posit
938 					// pt    = BitOr[BitShiftLeft[reg, es + nf + 1], BitShiftLeft[esval, nf + 1], BitShiftLeft[fv, 1], sb];
939 					regime <<= es + nf + 1;
940 					exponent <<= nf + 1;
941 					fraction <<= 1;
942 					sticky_bit.set(0, sb);
943 
944 					pt_bits |= regime;
945 					pt_bits |= exponent;
946 					pt_bits |= fraction;
947 					pt_bits |= sticky_bit;
948 
949 					unsigned len = 1 + std::max<unsigned>((nbits + 1), (2 + run + es));
950 					bool blast = pt_bits.test(len - nbits);
951 					bool bafter = pt_bits.test(len - nbits - 1);
952 					bool bsticky = anyAfter(pt_bits, len - nbits - 1 - 1);
953 
954 					bool rb = (blast & bafter) | (bafter & bsticky);
955 
956 					pt_bits <<= pt_len - len;
957 					bitblock<nbits> ptt;
958 					truncate(pt_bits, ptt);
959 
960 					if (rb) increment_bitset(ptt);
961 					if (s) ptt = twos_complement(ptt);
962 					_raw_bits = ptt;
963 					decode(ptt, _sign, _regime, _exponent, _fraction);
964 				}
965 			}
966 
967 		private:
968 			bitblock<nbits>      _raw_bits;	// raw bit representation
969 			bool		     	 _sign;     // decoded posit representation
970 			regime<nbits, es>    _regime;	// decoded posit representation
971 			exponent<nbits, es>  _exponent;	// decoded posit representation
972 			fraction<fbits>      _fraction;	// decoded posit representation
973 
974 			// HELPER methods
975 			// Conversion functions
to_int() const976 			int         to_int() const {
977 				if (iszero()) return 0;
978 				if (isnar()) throw "NaR (Not a Real)";
979 				return int(to_float());
980 			}
to_long() const981 			long        to_long() const {
982 				if (iszero()) return 0;
983 				if (isnar()) throw "NaR (Not a Real)";
984 				return long(to_double());
985 			}
to_long_long() const986 			long long   to_long_long() const {
987 				if (iszero()) return 0;
988 				if (isnar()) throw "NaR (Not a Real)";
989 				return long(to_long_double());
990 			}
to_float() const991 			float       to_float() const {
992 				return (float)to_double();
993 			}
to_double() const994 			double      to_double() const {
995 				if (iszero())	return 0.0;
996 				if (isnar())	return NAN;
997 				return sign_value() * regime_value() * exponent_value() * (1.0 + fraction_value());
998 			}
to_long_double() const999 			long double to_long_double() const {
1000 				if (iszero())  return 0.0;
1001 				if (isnar())   return NAN;
1002 				int s = sign_value();
1003 				double r = regime_value(); // regime value itself will fit in a double
1004 				double e = exponent_value(); // same with exponent
1005 				long double f = (long double)(1.0) + _fraction.value();
1006 				return s * r * e * f;
1007 			}
1008 			template <typename T>
float_assign(const T & rhs)1009 			posit_decoded<nbits, es>& float_assign(const T& rhs) {
1010 				constexpr int dfbits = std::numeric_limits<T>::digits - 1;
1011 				value<dfbits> v((T)rhs);
1012 
1013 				// special case processing
1014 				if (v.iszero()) {
1015 					setzero();
1016 					return *this;
1017 				}
1018 				if (v.isinf() || v.isnan()) {  // posit encode for FP_INFINITE and NaN as NaR (Not a Real)
1019 					setnar();
1020 					return *this;
1021 				}
1022 
1023 				convert(v);
1024 				return *this;
1025 			}
1026 
1027 			// friend functions
1028 			// template parameters need names different from class template parameters (for gcc and clang)
1029 			template<size_t nnbits, size_t ees>
1030 			friend std::ostream& operator<< (std::ostream& ostr, const posit_decoded<nnbits, ees>& p);
1031 			template<size_t nnbits, size_t ees>
1032 			friend std::istream& operator>> (std::istream& istr, posit_decoded<nnbits, ees>& p);
1033 
1034 			// posit - posit logic functions
1035 			template<size_t nnbits, size_t ees>
1036 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, const posit_decoded<nnbits, ees>& rhs);
1037 			template<size_t nnbits, size_t ees>
1038 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, const posit_decoded<nnbits, ees>& rhs);
1039 			template<size_t nnbits, size_t ees>
1040 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, const posit_decoded<nnbits, ees>& rhs);
1041 			template<size_t nnbits, size_t ees>
1042 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, const posit_decoded<nnbits, ees>& rhs);
1043 			template<size_t nnbits, size_t ees>
1044 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, const posit_decoded<nnbits, ees>& rhs);
1045 			template<size_t nnbits, size_t ees>
1046 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, const posit_decoded<nnbits, ees>& rhs);
1047 
1048 		#if POSIT_ENABLE_LITERALS
1049 			// posit - literal logic functions
1050 
1051 			// posit - signed char
1052 			template<size_t nnbits, size_t ees>
1053 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, signed char rhs);
1054 			template<size_t nnbits, size_t ees>
1055 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, signed char rhs);
1056 			template<size_t nnbits, size_t ees>
1057 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, signed char rhs);
1058 			template<size_t nnbits, size_t ees>
1059 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, signed char rhs);
1060 			template<size_t nnbits, size_t ees>
1061 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, signed char rhs);
1062 			template<size_t nnbits, size_t ees>
1063 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, signed char rhs);
1064 
1065 			// posit - char
1066 			template<size_t nnbits, size_t ees>
1067 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, char rhs);
1068 			template<size_t nnbits, size_t ees>
1069 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, char rhs);
1070 			template<size_t nnbits, size_t ees>
1071 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, char rhs);
1072 			template<size_t nnbits, size_t ees>
1073 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, char rhs);
1074 			template<size_t nnbits, size_t ees>
1075 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, char rhs);
1076 			template<size_t nnbits, size_t ees>
1077 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, char rhs);
1078 
1079 			// posit - short
1080 			template<size_t nnbits, size_t ees>
1081 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, short rhs);
1082 			template<size_t nnbits, size_t ees>
1083 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, short rhs);
1084 			template<size_t nnbits, size_t ees>
1085 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, short rhs);
1086 			template<size_t nnbits, size_t ees>
1087 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, short rhs);
1088 			template<size_t nnbits, size_t ees>
1089 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, short rhs);
1090 			template<size_t nnbits, size_t ees>
1091 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, short rhs);
1092 
1093 			// posit - unsigned short
1094 			template<size_t nnbits, size_t ees>
1095 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, unsigned short rhs);
1096 			template<size_t nnbits, size_t ees>
1097 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, unsigned short rhs);
1098 			template<size_t nnbits, size_t ees>
1099 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, unsigned short rhs);
1100 			template<size_t nnbits, size_t ees>
1101 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, unsigned short rhs);
1102 			template<size_t nnbits, size_t ees>
1103 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, unsigned short rhs);
1104 			template<size_t nnbits, size_t ees>
1105 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, unsigned short rhs);
1106 
1107 			// posit - int
1108 			template<size_t nnbits, size_t ees>
1109 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, int rhs);
1110 			template<size_t nnbits, size_t ees>
1111 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, int rhs);
1112 			template<size_t nnbits, size_t ees>
1113 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, int rhs);
1114 			template<size_t nnbits, size_t ees>
1115 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, int rhs);
1116 			template<size_t nnbits, size_t ees>
1117 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, int rhs);
1118 			template<size_t nnbits, size_t ees>
1119 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, int rhs);
1120 
1121 			// posit - unsigned int
1122 			template<size_t nnbits, size_t ees>
1123 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, unsigned int rhs);
1124 			template<size_t nnbits, size_t ees>
1125 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, unsigned int rhs);
1126 			template<size_t nnbits, size_t ees>
1127 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, unsigned int rhs);
1128 			template<size_t nnbits, size_t ees>
1129 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, unsigned int rhs);
1130 			template<size_t nnbits, size_t ees>
1131 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, unsigned int rhs);
1132 			template<size_t nnbits, size_t ees>
1133 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, unsigned int rhs);
1134 
1135 			// posit - long
1136 			template<size_t nnbits, size_t ees>
1137 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, long rhs);
1138 			template<size_t nnbits, size_t ees>
1139 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, long rhs);
1140 			template<size_t nnbits, size_t ees>
1141 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, long rhs);
1142 			template<size_t nnbits, size_t ees>
1143 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, long rhs);
1144 			template<size_t nnbits, size_t ees>
1145 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, long rhs);
1146 			template<size_t nnbits, size_t ees>
1147 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, long rhs);
1148 
1149 			// posit - unsigned long long
1150 			template<size_t nnbits, size_t ees>
1151 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, unsigned long rhs);
1152 			template<size_t nnbits, size_t ees>
1153 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, unsigned long rhs);
1154 			template<size_t nnbits, size_t ees>
1155 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, unsigned long rhs);
1156 			template<size_t nnbits, size_t ees>
1157 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, unsigned long rhs);
1158 			template<size_t nnbits, size_t ees>
1159 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, unsigned long rhs);
1160 			template<size_t nnbits, size_t ees>
1161 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, unsigned long rhs);
1162 
1163 			// posit - long long
1164 			template<size_t nnbits, size_t ees>
1165 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, long long rhs);
1166 			template<size_t nnbits, size_t ees>
1167 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, long long rhs);
1168 			template<size_t nnbits, size_t ees>
1169 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, long long rhs);
1170 			template<size_t nnbits, size_t ees>
1171 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, long long rhs);
1172 			template<size_t nnbits, size_t ees>
1173 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, long long rhs);
1174 			template<size_t nnbits, size_t ees>
1175 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, long long rhs);
1176 
1177 			// posit - unsigned long long
1178 			template<size_t nnbits, size_t ees>
1179 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, unsigned long long rhs);
1180 			template<size_t nnbits, size_t ees>
1181 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, unsigned long long rhs);
1182 			template<size_t nnbits, size_t ees>
1183 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, unsigned long long rhs);
1184 			template<size_t nnbits, size_t ees>
1185 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, unsigned long long rhs);
1186 			template<size_t nnbits, size_t ees>
1187 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, unsigned long long rhs);
1188 			template<size_t nnbits, size_t ees>
1189 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, unsigned long long rhs);
1190 
1191 			// posit - float
1192 			template<size_t nnbits, size_t ees>
1193 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, float rhs);
1194 			template<size_t nnbits, size_t ees>
1195 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, float rhs);
1196 			template<size_t nnbits, size_t ees>
1197 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, float rhs);
1198 			template<size_t nnbits, size_t ees>
1199 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, float rhs);
1200 			template<size_t nnbits, size_t ees>
1201 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, float rhs);
1202 			template<size_t nnbits, size_t ees>
1203 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, float rhs);
1204 
1205 			// posit - double
1206 			template<size_t nnbits, size_t ees>
1207 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, double rhs);
1208 			template<size_t nnbits, size_t ees>
1209 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, double rhs);
1210 			template<size_t nnbits, size_t ees>
1211 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, double rhs);
1212 			template<size_t nnbits, size_t ees>
1213 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, double rhs);
1214 			template<size_t nnbits, size_t ees>
1215 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, double rhs);
1216 			template<size_t nnbits, size_t ees>
1217 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, double rhs);
1218 
1219 			// posit - long double
1220 			template<size_t nnbits, size_t ees>
1221 			friend bool operator==(const posit_decoded<nnbits, ees>& lhs, long double rhs);
1222 			template<size_t nnbits, size_t ees>
1223 			friend bool operator!=(const posit_decoded<nnbits, ees>& lhs, long double rhs);
1224 			template<size_t nnbits, size_t ees>
1225 			friend bool operator< (const posit_decoded<nnbits, ees>& lhs, long double rhs);
1226 			template<size_t nnbits, size_t ees>
1227 			friend bool operator> (const posit_decoded<nnbits, ees>& lhs, long double rhs);
1228 			template<size_t nnbits, size_t ees>
1229 			friend bool operator<=(const posit_decoded<nnbits, ees>& lhs, long double rhs);
1230 			template<size_t nnbits, size_t ees>
1231 			friend bool operator>=(const posit_decoded<nnbits, ees>& lhs, long double rhs);
1232 
1233 			// literal - posit logic functions
1234 
1235 			// signed char - posit
1236 			template<size_t nnbits, size_t ees>
1237 			friend bool operator==(signed char lhs, const posit_decoded<nnbits, ees>& rhs);
1238 			template<size_t nnbits, size_t ees>
1239 			friend bool operator!=(signed char lhs, const posit_decoded<nnbits, ees>& rhs);
1240 			template<size_t nnbits, size_t ees>
1241 			friend bool operator< (signed char lhs, const posit_decoded<nnbits, ees>& rhs);
1242 			template<size_t nnbits, size_t ees>
1243 			friend bool operator> (signed char lhs, const posit_decoded<nnbits, ees>& rhs);
1244 			template<size_t nnbits, size_t ees>
1245 			friend bool operator<=(signed char lhs, const posit_decoded<nnbits, ees>& rhs);
1246 			template<size_t nnbits, size_t ees>
1247 			friend bool operator>=(signed char lhs, const posit_decoded<nnbits, ees>& rhs);
1248 
1249 			// char - posit
1250 			template<size_t nnbits, size_t ees>
1251 			friend bool operator==(char lhs, const posit_decoded<nnbits, ees>& rhs);
1252 			template<size_t nnbits, size_t ees>
1253 			friend bool operator!=(char lhs, const posit_decoded<nnbits, ees>& rhs);
1254 			template<size_t nnbits, size_t ees>
1255 			friend bool operator< (char lhs, const posit_decoded<nnbits, ees>& rhs);
1256 			template<size_t nnbits, size_t ees>
1257 			friend bool operator> (char lhs, const posit_decoded<nnbits, ees>& rhs);
1258 			template<size_t nnbits, size_t ees>
1259 			friend bool operator<=(char lhs, const posit_decoded<nnbits, ees>& rhs);
1260 			template<size_t nnbits, size_t ees>
1261 			friend bool operator>=(char lhs, const posit_decoded<nnbits, ees>& rhs);
1262 
1263 			// short - posit
1264 			template<size_t nnbits, size_t ees>
1265 			friend bool operator==(short lhs, const posit_decoded<nnbits, ees>& rhs);
1266 			template<size_t nnbits, size_t ees>
1267 			friend bool operator!=(short lhs, const posit_decoded<nnbits, ees>& rhs);
1268 			template<size_t nnbits, size_t ees>
1269 			friend bool operator< (short lhs, const posit_decoded<nnbits, ees>& rhs);
1270 			template<size_t nnbits, size_t ees>
1271 			friend bool operator> (short lhs, const posit_decoded<nnbits, ees>& rhs);
1272 			template<size_t nnbits, size_t ees>
1273 			friend bool operator<=(short lhs, const posit_decoded<nnbits, ees>& rhs);
1274 			template<size_t nnbits, size_t ees>
1275 			friend bool operator>=(short lhs, const posit_decoded<nnbits, ees>& rhs);
1276 
1277 			// unsigned short - posit
1278 			template<size_t nnbits, size_t ees>
1279 			friend bool operator==(unsigned short lhs, const posit_decoded<nnbits, ees>& rhs);
1280 			template<size_t nnbits, size_t ees>
1281 			friend bool operator!=(unsigned short lhs, const posit_decoded<nnbits, ees>& rhs);
1282 			template<size_t nnbits, size_t ees>
1283 			friend bool operator< (unsigned short lhs, const posit_decoded<nnbits, ees>& rhs);
1284 			template<size_t nnbits, size_t ees>
1285 			friend bool operator> (unsigned short lhs, const posit_decoded<nnbits, ees>& rhs);
1286 			template<size_t nnbits, size_t ees>
1287 			friend bool operator<=(unsigned short lhs, const posit_decoded<nnbits, ees>& rhs);
1288 			template<size_t nnbits, size_t ees>
1289 			friend bool operator>=(unsigned short lhs, const posit_decoded<nnbits, ees>& rhs);
1290 
1291 			// int - posit
1292 			template<size_t nnbits, size_t ees>
1293 			friend bool operator==(int lhs, const posit_decoded<nnbits, ees>& rhs);
1294 			template<size_t nnbits, size_t ees>
1295 			friend bool operator!=(int lhs, const posit_decoded<nnbits, ees>& rhs);
1296 			template<size_t nnbits, size_t ees>
1297 			friend bool operator< (int lhs, const posit_decoded<nnbits, ees>& rhs);
1298 			template<size_t nnbits, size_t ees>
1299 			friend bool operator> (int lhs, const posit_decoded<nnbits, ees>& rhs);
1300 			template<size_t nnbits, size_t ees>
1301 			friend bool operator<=(int lhs, const posit_decoded<nnbits, ees>& rhs);
1302 			template<size_t nnbits, size_t ees>
1303 			friend bool operator>=(int lhs, const posit_decoded<nnbits, ees>& rhs);
1304 
1305 			// unsigned int - posit
1306 			template<size_t nnbits, size_t ees>
1307 			friend bool operator==(unsigned int lhs, const posit_decoded<nnbits, ees>& rhs);
1308 			template<size_t nnbits, size_t ees>
1309 			friend bool operator!=(unsigned int lhs, const posit_decoded<nnbits, ees>& rhs);
1310 			template<size_t nnbits, size_t ees>
1311 			friend bool operator< (unsigned int lhs, const posit_decoded<nnbits, ees>& rhs);
1312 			template<size_t nnbits, size_t ees>
1313 			friend bool operator> (unsigned int lhs, const posit_decoded<nnbits, ees>& rhs);
1314 			template<size_t nnbits, size_t ees>
1315 			friend bool operator<=(unsigned int lhs, const posit_decoded<nnbits, ees>& rhs);
1316 			template<size_t nnbits, size_t ees>
1317 			friend bool operator>=(unsigned int lhs, const posit_decoded<nnbits, ees>& rhs);
1318 
1319 			// long - posit
1320 			template<size_t nnbits, size_t ees>
1321 			friend bool operator==(long lhs, const posit_decoded<nnbits, ees>& rhs);
1322 			template<size_t nnbits, size_t ees>
1323 			friend bool operator!=(long lhs, const posit_decoded<nnbits, ees>& rhs);
1324 			template<size_t nnbits, size_t ees>
1325 			friend bool operator< (long lhs, const posit_decoded<nnbits, ees>& rhs);
1326 			template<size_t nnbits, size_t ees>
1327 			friend bool operator> (long lhs, const posit_decoded<nnbits, ees>& rhs);
1328 			template<size_t nnbits, size_t ees>
1329 			friend bool operator<=(long lhs, const posit_decoded<nnbits, ees>& rhs);
1330 			template<size_t nnbits, size_t ees>
1331 			friend bool operator>=(long lhs, const posit_decoded<nnbits, ees>& rhs);
1332 
1333 			// unsigned long - posit
1334 			template<size_t nnbits, size_t ees>
1335 			friend bool operator==(unsigned long lhs, const posit_decoded<nnbits, ees>& rhs);
1336 			template<size_t nnbits, size_t ees>
1337 			friend bool operator!=(unsigned long lhs, const posit_decoded<nnbits, ees>& rhs);
1338 			template<size_t nnbits, size_t ees>
1339 			friend bool operator< (unsigned long lhs, const posit_decoded<nnbits, ees>& rhs);
1340 			template<size_t nnbits, size_t ees>
1341 			friend bool operator> (unsigned long lhs, const posit_decoded<nnbits, ees>& rhs);
1342 			template<size_t nnbits, size_t ees>
1343 			friend bool operator<=(unsigned long lhs, const posit_decoded<nnbits, ees>& rhs);
1344 			template<size_t nnbits, size_t ees>
1345 			friend bool operator>=(unsigned long lhs, const posit_decoded<nnbits, ees>& rhs);
1346 
1347 			// long long - posit
1348 			template<size_t nnbits, size_t ees>
1349 			friend bool operator==(long long lhs, const posit_decoded<nnbits, ees>& rhs);
1350 			template<size_t nnbits, size_t ees>
1351 			friend bool operator!=(long long lhs, const posit_decoded<nnbits, ees>& rhs);
1352 			template<size_t nnbits, size_t ees>
1353 			friend bool operator< (long long lhs, const posit_decoded<nnbits, ees>& rhs);
1354 			template<size_t nnbits, size_t ees>
1355 			friend bool operator> (long long lhs, const posit_decoded<nnbits, ees>& rhs);
1356 			template<size_t nnbits, size_t ees>
1357 			friend bool operator<=(long long lhs, const posit_decoded<nnbits, ees>& rhs);
1358 			template<size_t nnbits, size_t ees>
1359 			friend bool operator>=(long long lhs, const posit_decoded<nnbits, ees>& rhs);
1360 
1361 			// unsigned long long - posit
1362 			template<size_t nnbits, size_t ees>
1363 			friend bool operator==(unsigned long long lhs, const posit_decoded<nnbits, ees>& rhs);
1364 			template<size_t nnbits, size_t ees>
1365 			friend bool operator!=(unsigned long long lhs, const posit_decoded<nnbits, ees>& rhs);
1366 			template<size_t nnbits, size_t ees>
1367 			friend bool operator< (unsigned long long lhs, const posit_decoded<nnbits, ees>& rhs);
1368 			template<size_t nnbits, size_t ees>
1369 			friend bool operator> (unsigned long long lhs, const posit_decoded<nnbits, ees>& rhs);
1370 			template<size_t nnbits, size_t ees>
1371 			friend bool operator<=(unsigned long long lhs, const posit_decoded<nnbits, ees>& rhs);
1372 			template<size_t nnbits, size_t ees>
1373 			friend bool operator>=(unsigned long long lhs, const posit_decoded<nnbits, ees>& rhs);
1374 
1375 			// float - posit
1376 			template<size_t nnbits, size_t ees>
1377 			friend bool operator==(float lhs, const posit_decoded<nnbits, ees>& rhs);
1378 			template<size_t nnbits, size_t ees>
1379 			friend bool operator!=(float lhs, const posit_decoded<nnbits, ees>& rhs);
1380 			template<size_t nnbits, size_t ees>
1381 			friend bool operator< (float lhs, const posit_decoded<nnbits, ees>& rhs);
1382 			template<size_t nnbits, size_t ees>
1383 			friend bool operator> (float lhs, const posit_decoded<nnbits, ees>& rhs);
1384 			template<size_t nnbits, size_t ees>
1385 			friend bool operator<=(float lhs, const posit_decoded<nnbits, ees>& rhs);
1386 			template<size_t nnbits, size_t ees>
1387 			friend bool operator>=(float lhs, const posit_decoded<nnbits, ees>& rhs);
1388 
1389 			// double - posit
1390 			template<size_t nnbits, size_t ees>
1391 			friend bool operator==(double lhs, const posit_decoded<nnbits, ees>& rhs);
1392 			template<size_t nnbits, size_t ees>
1393 			friend bool operator!=(double lhs, const posit_decoded<nnbits, ees>& rhs);
1394 			template<size_t nnbits, size_t ees>
1395 			friend bool operator< (double lhs, const posit_decoded<nnbits, ees>& rhs);
1396 			template<size_t nnbits, size_t ees>
1397 			friend bool operator> (double lhs, const posit_decoded<nnbits, ees>& rhs);
1398 			template<size_t nnbits, size_t ees>
1399 			friend bool operator<=(double lhs, const posit_decoded<nnbits, ees>& rhs);
1400 			template<size_t nnbits, size_t ees>
1401 			friend bool operator>=(double lhs, const posit_decoded<nnbits, ees>& rhs);
1402 
1403 			// long double - posit
1404 			template<size_t nnbits, size_t ees>
1405 			friend bool operator==(long double lhs, const posit_decoded<nnbits, ees>& rhs);
1406 			template<size_t nnbits, size_t ees>
1407 			friend bool operator!=(long double lhs, const posit_decoded<nnbits, ees>& rhs);
1408 			template<size_t nnbits, size_t ees>
1409 			friend bool operator< (long double lhs, const posit_decoded<nnbits, ees>& rhs);
1410 			template<size_t nnbits, size_t ees>
1411 			friend bool operator> (long double lhs, const posit_decoded<nnbits, ees>& rhs);
1412 			template<size_t nnbits, size_t ees>
1413 			friend bool operator<=(long double lhs, const posit_decoded<nnbits, ees>& rhs);
1414 			template<size_t nnbits, size_t ees>
1415 			friend bool operator>=(long double lhs, const posit_decoded<nnbits, ees>& rhs);
1416 
1417 		#endif // POSIT_ENABLE_LITERALS
1418 
1419 		};
1420 
1421 		////////////////// convenience/shim functions
1422 
1423 		template<size_t nbits, size_t es>
isnar(const posit_decoded<nbits,es> & p)1424 		inline bool isnar(const posit_decoded<nbits, es>& p) {
1425 			return p.isnar();
1426 		}
1427 
1428 		template<size_t nbits, size_t es>
isfinite(const posit_decoded<nbits,es> & p)1429 		inline bool isfinite(const posit_decoded<nbits, es>& p) {
1430 			return !p.isnar();
1431 		}
1432 
1433 		template<size_t nbits, size_t es>
isinfinite(const posit_decoded<nbits,es> & p)1434 		inline bool isinfinite(const posit_decoded<nbits, es>& p) {
1435 			return p.isnar();
1436 		}
1437 
1438 		////////////////// POSIT operators
1439 
1440 		// stream operators
1441 
1442 		// generate a posit format ASCII format nbits.esxNN...NNp
1443 		template<size_t nbits, size_t es>
operator <<(std::ostream & ostr,const posit_decoded<nbits,es> & p)1444 		inline std::ostream& operator<<(std::ostream& ostr, const posit_decoded<nbits, es>& p) {
1445 			ostr << nbits << '.' << es << 'x' << to_hex(p.get()) << 'p';
1446 			return ostr;
1447 		}
1448 
1449 		// read an ASCII float or posit format: nbits.esxNN...NNp, for example: 32.2x80000000p
1450 		template<size_t nbits, size_t es>
operator >>(std::istream & istr,posit_decoded<nbits,es> & p)1451 		inline std::istream& operator>> (std::istream& istr, posit_decoded<nbits, es>& p) {
1452 			std::string txt;
1453 			istr >> txt;
1454 			if (!p.parse(txt)) {
1455 				std::cerr << "unable to parse -" << txt << "- into a posit value\n";
1456 			}
1457 			return istr;
1458 		}
1459 
1460 		// posit - posit binary logic operators
1461 		template<size_t nbits, size_t es>
operator ==(const posit<nbits,es> & lhs,const posit_decoded<nbits,es> & rhs)1462 		inline bool operator==(const posit<nbits, es>& lhs, const posit_decoded<nbits, es>& rhs) {
1463 			return lhs._raw_bits == rhs._raw_bits;
1464 		}
1465 		template<size_t nbits, size_t es>
operator !=(const posit<nbits,es> & lhs,const posit_decoded<nbits,es> & rhs)1466 		inline bool operator!=(const posit<nbits, es>& lhs, const posit_decoded<nbits, es>& rhs) {
1467 			return !operator==(lhs, rhs);
1468 		}
1469 		template<size_t nbits, size_t es>
operator <(const posit<nbits,es> & lhs,const posit_decoded<nbits,es> & rhs)1470 		inline bool operator< (const posit<nbits, es>& lhs, const posit_decoded<nbits, es>& rhs) {
1471 			return lessThan(lhs._raw_bits, rhs._raw_bits);
1472 		}
1473 		template<size_t nbits, size_t es>
operator >(const posit<nbits,es> & lhs,const posit_decoded<nbits,es> & rhs)1474 		inline bool operator> (const posit<nbits, es>& lhs, const posit_decoded<nbits, es>& rhs) {
1475 			return operator< (rhs, lhs);
1476 		}
1477 		template<size_t nbits, size_t es>
operator <=(const posit<nbits,es> & lhs,const posit_decoded<nbits,es> & rhs)1478 		inline bool operator<=(const posit<nbits, es>& lhs, const posit_decoded<nbits, es>& rhs) {
1479 			return operator< (lhs, rhs) || operator==(lhs, rhs);
1480 		}
1481 		template<size_t nbits, size_t es>
operator >=(const posit<nbits,es> & lhs,const posit_decoded<nbits,es> & rhs)1482 		inline bool operator>=(const posit<nbits, es>& lhs, const posit_decoded<nbits, es>& rhs) {
1483 			return !operator< (lhs, rhs);
1484 		}
1485 
1486 		// posit - posit binary arithmetic operators
1487 		// BINARY ADDITION
1488 		template<size_t nbits, size_t es>
operator +(const posit_decoded<nbits,es> & lhs,const posit_decoded<nbits,es> & rhs)1489 		inline posit<nbits, es> operator+(const posit_decoded<nbits, es>& lhs, const posit_decoded<nbits, es>& rhs) {
1490 			posit<nbits, es> sum = lhs;
1491 			sum += rhs;
1492 			return sum;
1493 		}
1494 		// BINARY SUBTRACTION
1495 		template<size_t nbits, size_t es>
operator -(const posit_decoded<nbits,es> & lhs,const posit_decoded<nbits,es> & rhs)1496 		inline posit<nbits, es> operator-(const posit_decoded<nbits, es>& lhs, const posit_decoded<nbits, es>& rhs) {
1497 			posit<nbits, es> diff = lhs;
1498 			diff -= rhs;
1499 			return diff;
1500 		}
1501 		// BINARY MULTIPLICATION
1502 		template<size_t nbits, size_t es>
operator *(const posit_decoded<nbits,es> & lhs,const posit_decoded<nbits,es> & rhs)1503 		inline posit<nbits, es> operator*(const posit_decoded<nbits, es>& lhs, const posit_decoded<nbits, es>& rhs) {
1504 			posit<nbits, es> mul = lhs;
1505 			mul *= rhs;
1506 			return mul;
1507 		}
1508 		// BINARY DIVISION
1509 		template<size_t nbits, size_t es>
operator /(const posit_decoded<nbits,es> & lhs,const posit_decoded<nbits,es> & rhs)1510 		inline posit<nbits, es> operator/(const posit_decoded<nbits, es>& lhs, const posit_decoded<nbits, es>& rhs) {
1511 			posit<nbits, es> ratio = lhs;
1512 			ratio /= rhs;
1513 			return ratio;
1514 		}
1515 
1516 		#if POSIT_ENABLE_LITERALS
1517 
1518 		// posit - signed char logic operators
1519 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,signed char rhs)1520 		inline bool operator==(const posit_decoded<nbits, es>& lhs, signed char rhs) {
1521 			return lhs == posit<nbits, es>(rhs);
1522 		}
1523 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,signed char rhs)1524 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, signed char rhs) {
1525 			return !operator==(lhs, posit<nbits, es>(rhs));
1526 		}
1527 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,signed char rhs)1528 		inline bool operator< (const posit_decoded<nbits, es>& lhs, signed char rhs) {
1529 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
1530 		}
1531 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,signed char rhs)1532 		inline bool operator> (const posit_decoded<nbits, es>& lhs, signed char rhs) {
1533 			return operator< (posit<nbits, es>(rhs), lhs);
1534 		}
1535 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,signed char rhs)1536 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, signed char rhs) {
1537 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
1538 		}
1539 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,signed char rhs)1540 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, signed char rhs) {
1541 			return !operator<(lhs, posit<nbits, es>(rhs));
1542 		}
1543 
1544 		// signed char - posit logic operators
1545 		template<size_t nbits, size_t es>
operator ==(signed char lhs,const posit_decoded<nbits,es> & rhs)1546 		inline bool operator==(signed char lhs, const posit_decoded<nbits, es>& rhs) {
1547 			return posit<nbits, es>(lhs) == rhs;
1548 		}
1549 		template<size_t nbits, size_t es>
operator !=(signed char lhs,const posit_decoded<nbits,es> & rhs)1550 		inline bool operator!=(signed char lhs, const posit_decoded<nbits, es>& rhs) {
1551 			return !operator==(posit<nbits, es>(lhs), rhs);
1552 		}
1553 		template<size_t nbits, size_t es>
operator <(signed char lhs,const posit_decoded<nbits,es> & rhs)1554 		inline bool operator< (signed char lhs, const posit_decoded<nbits, es>& rhs) {
1555 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
1556 		}
1557 		template<size_t nbits, size_t es>
operator >(signed char lhs,const posit_decoded<nbits,es> & rhs)1558 		inline bool operator> (signed char lhs, const posit_decoded<nbits, es>& rhs) {
1559 			return operator< (posit<nbits, es>(lhs), rhs);
1560 		}
1561 		template<size_t nbits, size_t es>
operator <=(signed char lhs,const posit_decoded<nbits,es> & rhs)1562 		inline bool operator<=(signed char lhs, const posit_decoded<nbits, es>& rhs) {
1563 			return operator< (posit<nbits, es>(lhs), rhs) || operator==(posit<nbits, es>(lhs), rhs);
1564 		}
1565 		template<size_t nbits, size_t es>
operator >=(signed char lhs,const posit_decoded<nbits,es> & rhs)1566 		inline bool operator>=(signed char lhs, const posit_decoded<nbits, es>& rhs) {
1567 			return !operator<(posit<nbits, es>(lhs), rhs);
1568 		}
1569 
1570 		// posit - char logic operators
1571 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,char rhs)1572 		inline bool operator==(const posit_decoded<nbits, es>& lhs, char rhs) {
1573 			return lhs == posit<nbits, es>(rhs);
1574 		}
1575 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,char rhs)1576 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, char rhs) {
1577 			return !operator==(lhs, posit<nbits, es>(rhs));
1578 		}
1579 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,char rhs)1580 		inline bool operator< (const posit_decoded<nbits, es>& lhs, char rhs) {
1581 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
1582 		}
1583 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,char rhs)1584 		inline bool operator> (const posit_decoded<nbits, es>& lhs, char rhs) {
1585 			return operator< (posit<nbits, es>(rhs), lhs);
1586 		}
1587 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,char rhs)1588 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, char rhs) {
1589 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
1590 		}
1591 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,char rhs)1592 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, char rhs) {
1593 			return !operator<(lhs, posit<nbits, es>(rhs));
1594 		}
1595 
1596 		// char - posit logic operators
1597 		template<size_t nbits, size_t es>
operator ==(char lhs,const posit_decoded<nbits,es> & rhs)1598 		inline bool operator==(char lhs, const posit_decoded<nbits, es>& rhs) {
1599 			return posit<nbits, es>(lhs) == rhs;
1600 		}
1601 		template<size_t nbits, size_t es>
operator !=(char lhs,const posit_decoded<nbits,es> & rhs)1602 		inline bool operator!=(char lhs, const posit_decoded<nbits, es>& rhs) {
1603 			return !operator==(posit<nbits, es>(lhs), rhs);
1604 		}
1605 		template<size_t nbits, size_t es>
operator <(char lhs,const posit_decoded<nbits,es> & rhs)1606 		inline bool operator< (char lhs, const posit_decoded<nbits, es>& rhs) {
1607 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
1608 		}
1609 		template<size_t nbits, size_t es>
operator >(char lhs,const posit_decoded<nbits,es> & rhs)1610 		inline bool operator> (char lhs, const posit_decoded<nbits, es>& rhs) {
1611 			return operator< (posit<nbits, es>(lhs), rhs);
1612 		}
1613 		template<size_t nbits, size_t es>
operator <=(char lhs,const posit_decoded<nbits,es> & rhs)1614 		inline bool operator<=(char lhs, const posit_decoded<nbits, es>& rhs) {
1615 			return operator< (posit<nbits, es>(lhs), rhs) || operator==(posit<nbits, es>(lhs), rhs);
1616 		}
1617 		template<size_t nbits, size_t es>
operator >=(char lhs,const posit_decoded<nbits,es> & rhs)1618 		inline bool operator>=(char lhs, const posit_decoded<nbits, es>& rhs) {
1619 			return !operator<(posit<nbits, es>(lhs), rhs);
1620 		}
1621 
1622 		// posit - short logic operators
1623 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,short rhs)1624 		inline bool operator==(const posit_decoded<nbits, es>& lhs, short rhs) {
1625 			return lhs == posit<nbits, es>(rhs);
1626 		}
1627 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,short rhs)1628 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, short rhs) {
1629 			return !operator==(lhs, posit<nbits, es>(rhs));
1630 		}
1631 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,short rhs)1632 		inline bool operator< (const posit_decoded<nbits, es>& lhs, short rhs) {
1633 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
1634 		}
1635 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,short rhs)1636 		inline bool operator> (const posit_decoded<nbits, es>& lhs, short rhs) {
1637 			return operator< (posit<nbits, es>(rhs), lhs);
1638 		}
1639 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,short rhs)1640 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, short rhs) {
1641 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
1642 		}
1643 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,short rhs)1644 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, short rhs) {
1645 			return !operator<(lhs, posit<nbits, es>(rhs));
1646 		}
1647 
1648 		// short - posit logic operators
1649 		template<size_t nbits, size_t es>
operator ==(short lhs,const posit_decoded<nbits,es> & rhs)1650 		inline bool operator==(short lhs, const posit_decoded<nbits, es>& rhs) {
1651 			return posit<nbits, es>(lhs) == rhs;
1652 		}
1653 		template<size_t nbits, size_t es>
operator !=(short lhs,const posit_decoded<nbits,es> & rhs)1654 		inline bool operator!=(short lhs, const posit_decoded<nbits, es>& rhs) {
1655 			return !operator==(posit<nbits, es>(lhs), rhs);
1656 		}
1657 		template<size_t nbits, size_t es>
operator <(short lhs,const posit_decoded<nbits,es> & rhs)1658 		inline bool operator< (short lhs, const posit_decoded<nbits, es>& rhs) {
1659 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
1660 		}
1661 		template<size_t nbits, size_t es>
operator >(short lhs,const posit_decoded<nbits,es> & rhs)1662 		inline bool operator> (short lhs, const posit_decoded<nbits, es>& rhs) {
1663 			return operator< (posit<nbits, es>(lhs), rhs);
1664 		}
1665 		template<size_t nbits, size_t es>
operator <=(short lhs,const posit_decoded<nbits,es> & rhs)1666 		inline bool operator<=(short lhs, const posit_decoded<nbits, es>& rhs) {
1667 			return operator< (posit<nbits, es>(lhs), rhs) || operator==(posit<nbits, es>(lhs), rhs);
1668 		}
1669 		template<size_t nbits, size_t es>
operator >=(short lhs,const posit_decoded<nbits,es> & rhs)1670 		inline bool operator>=(short lhs, const posit_decoded<nbits, es>& rhs) {
1671 			return !operator<(posit<nbits, es>(lhs), rhs);
1672 		}
1673 
1674 		// posit - unsigned short logic operators
1675 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,unsigned short rhs)1676 		inline bool operator==(const posit_decoded<nbits, es>& lhs, unsigned short rhs) {
1677 			return lhs == posit<nbits, es>(rhs);
1678 		}
1679 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,unsigned short rhs)1680 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, unsigned short rhs) {
1681 			return !operator==(lhs, posit<nbits, es>(rhs));
1682 		}
1683 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,unsigned short rhs)1684 		inline bool operator< (const posit_decoded<nbits, es>& lhs, unsigned short rhs) {
1685 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
1686 		}
1687 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,unsigned short rhs)1688 		inline bool operator> (const posit_decoded<nbits, es>& lhs, unsigned short rhs) {
1689 			return operator< (posit<nbits, es>(rhs), lhs);
1690 		}
1691 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,unsigned short rhs)1692 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, unsigned short rhs) {
1693 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
1694 		}
1695 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,unsigned short rhs)1696 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, unsigned short rhs) {
1697 			return !operator<(lhs, posit<nbits, es>(rhs));
1698 		}
1699 
1700 		// unsigned short - posit logic operators
1701 		template<size_t nbits, size_t es>
operator ==(unsigned short lhs,const posit_decoded<nbits,es> & rhs)1702 		inline bool operator==(unsigned short lhs, const posit_decoded<nbits, es>& rhs) {
1703 			return posit<nbits, es>(lhs) == rhs;
1704 		}
1705 		template<size_t nbits, size_t es>
operator !=(unsigned short lhs,const posit_decoded<nbits,es> & rhs)1706 		inline bool operator!=(unsigned short lhs, const posit_decoded<nbits, es>& rhs) {
1707 			return !operator==(posit<nbits, es>(lhs), rhs);
1708 		}
1709 		template<size_t nbits, size_t es>
operator <(unsigned short lhs,const posit_decoded<nbits,es> & rhs)1710 		inline bool operator< (unsigned short lhs, const posit_decoded<nbits, es>& rhs) {
1711 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
1712 		}
1713 		template<size_t nbits, size_t es>
operator >(unsigned short lhs,const posit_decoded<nbits,es> & rhs)1714 		inline bool operator> (unsigned short lhs, const posit_decoded<nbits, es>& rhs) {
1715 			return operator< (posit<nbits, es>(lhs), rhs);
1716 		}
1717 		template<size_t nbits, size_t es>
operator <=(unsigned short lhs,const posit_decoded<nbits,es> & rhs)1718 		inline bool operator<=(unsigned short lhs, const posit_decoded<nbits, es>& rhs) {
1719 			return operator< (posit<nbits, es>(lhs), rhs) || operator==(posit<nbits, es>(lhs), rhs);
1720 		}
1721 		template<size_t nbits, size_t es>
operator >=(unsigned short lhs,const posit_decoded<nbits,es> & rhs)1722 		inline bool operator>=(unsigned short lhs, const posit_decoded<nbits, es>& rhs) {
1723 			return !operator<(posit<nbits, es>(lhs), rhs);
1724 		}
1725 
1726 		// posit - int logic operators
1727 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,int rhs)1728 		inline bool operator==(const posit_decoded<nbits, es>& lhs, int rhs) {
1729 			return lhs == posit<nbits, es>(rhs);
1730 		}
1731 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,int rhs)1732 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, int rhs) {
1733 			return !operator==(lhs, posit<nbits, es>(rhs));
1734 		}
1735 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,int rhs)1736 		inline bool operator< (const posit_decoded<nbits, es>& lhs, int rhs) {
1737 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
1738 		}
1739 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,int rhs)1740 		inline bool operator> (const posit_decoded<nbits, es>& lhs, int rhs) {
1741 			return operator< (posit<nbits, es>(rhs), lhs);
1742 		}
1743 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,int rhs)1744 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, int rhs) {
1745 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
1746 		}
1747 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,int rhs)1748 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, int rhs) {
1749 			return !operator<(lhs, posit<nbits, es>(rhs));
1750 		}
1751 
1752 		// int - posit logic operators
1753 		template<size_t nbits, size_t es>
operator ==(int lhs,const posit_decoded<nbits,es> & rhs)1754 		inline bool operator==(int lhs, const posit_decoded<nbits, es>& rhs) {
1755 			return posit<nbits, es>(lhs) == rhs;
1756 		}
1757 		template<size_t nbits, size_t es>
operator !=(int lhs,const posit_decoded<nbits,es> & rhs)1758 		inline bool operator!=(int lhs, const posit_decoded<nbits, es>& rhs) {
1759 			return !operator==(posit<nbits, es>(lhs), rhs);
1760 		}
1761 		template<size_t nbits, size_t es>
operator <(int lhs,const posit_decoded<nbits,es> & rhs)1762 		inline bool operator< (int lhs, const posit_decoded<nbits, es>& rhs) {
1763 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
1764 		}
1765 		template<size_t nbits, size_t es>
operator >(int lhs,const posit_decoded<nbits,es> & rhs)1766 		inline bool operator> (int lhs, const posit_decoded<nbits, es>& rhs) {
1767 			return operator< (posit<nbits, es>(lhs), rhs);
1768 		}
1769 		template<size_t nbits, size_t es>
operator <=(int lhs,const posit_decoded<nbits,es> & rhs)1770 		inline bool operator<=(int lhs, const posit_decoded<nbits, es>& rhs) {
1771 			return operator< (posit<nbits, es>(lhs), rhs) || operator==(posit<nbits, es>(lhs), rhs);
1772 		}
1773 		template<size_t nbits, size_t es>
operator >=(int lhs,const posit_decoded<nbits,es> & rhs)1774 		inline bool operator>=(int lhs, const posit_decoded<nbits, es>& rhs) {
1775 			return !operator<(posit<nbits, es>(lhs), rhs);
1776 		}
1777 
1778 		// posit - unsigned int logic operators
1779 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,unsigned int rhs)1780 		inline bool operator==(const posit_decoded<nbits, es>& lhs, unsigned int rhs) {
1781 			return lhs == posit<nbits, es>(rhs);
1782 		}
1783 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,unsigned int rhs)1784 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, unsigned int rhs) {
1785 			return !operator==(lhs, posit<nbits, es>(rhs));
1786 		}
1787 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,unsigned int rhs)1788 		inline bool operator< (const posit_decoded<nbits, es>& lhs, unsigned int rhs) {
1789 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
1790 		}
1791 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,unsigned int rhs)1792 		inline bool operator> (const posit_decoded<nbits, es>& lhs, unsigned int rhs) {
1793 			return operator< (posit<nbits, es>(rhs), lhs);
1794 		}
1795 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,unsigned int rhs)1796 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, unsigned int rhs) {
1797 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
1798 		}
1799 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,unsigned int rhs)1800 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, unsigned int rhs) {
1801 			return !operator<(lhs, posit<nbits, es>(rhs));
1802 		}
1803 
1804 		// unsigned int - posit logic operators
1805 		template<size_t nbits, size_t es>
operator ==(unsigned int lhs,const posit_decoded<nbits,es> & rhs)1806 		inline bool operator==(unsigned int lhs, const posit_decoded<nbits, es>& rhs) {
1807 			return posit<nbits, es>(lhs) == rhs;
1808 		}
1809 		template<size_t nbits, size_t es>
operator !=(unsigned int lhs,const posit_decoded<nbits,es> & rhs)1810 		inline bool operator!=(unsigned int lhs, const posit_decoded<nbits, es>& rhs) {
1811 			return !operator==(posit<nbits, es>(lhs), rhs);
1812 		}
1813 		template<size_t nbits, size_t es>
operator <(unsigned int lhs,const posit_decoded<nbits,es> & rhs)1814 		inline bool operator< (unsigned int lhs, const posit_decoded<nbits, es>& rhs) {
1815 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
1816 		}
1817 		template<size_t nbits, size_t es>
operator >(unsigned int lhs,const posit_decoded<nbits,es> & rhs)1818 		inline bool operator> (unsigned int lhs, const posit_decoded<nbits, es>& rhs) {
1819 			return operator< (posit<nbits, es>(lhs), rhs);
1820 		}
1821 		template<size_t nbits, size_t es>
operator <=(unsigned int lhs,const posit_decoded<nbits,es> & rhs)1822 		inline bool operator<=(unsigned int lhs, const posit_decoded<nbits, es>& rhs) {
1823 			return operator< (posit<nbits, es>(lhs), rhs) || operator==(posit<nbits, es>(lhs), rhs);
1824 		}
1825 		template<size_t nbits, size_t es>
operator >=(unsigned int lhs,const posit_decoded<nbits,es> & rhs)1826 		inline bool operator>=(unsigned int lhs, const posit_decoded<nbits, es>& rhs) {
1827 			return !operator<(posit<nbits, es>(lhs), rhs);
1828 		}
1829 
1830 		// posit - long logic operators
1831 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,long rhs)1832 		inline bool operator==(const posit_decoded<nbits, es>& lhs, long rhs) {
1833 			return lhs == posit<nbits, es>(rhs);
1834 		}
1835 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,long rhs)1836 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, long rhs) {
1837 			return !operator==(lhs, posit<nbits, es>(rhs));
1838 		}
1839 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,long rhs)1840 		inline bool operator< (const posit_decoded<nbits, es>& lhs, long rhs) {
1841 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
1842 		}
1843 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,long rhs)1844 		inline bool operator> (const posit_decoded<nbits, es>& lhs, long rhs) {
1845 			return operator< (posit<nbits, es>(rhs), lhs);
1846 		}
1847 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,long rhs)1848 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, long rhs) {
1849 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
1850 		}
1851 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,long rhs)1852 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, long rhs) {
1853 			return !operator<(lhs, posit<nbits, es>(rhs));
1854 		}
1855 
1856 		// long - posit logic operators
1857 		template<size_t nbits, size_t es>
operator ==(long lhs,const posit_decoded<nbits,es> & rhs)1858 		inline bool operator==(long lhs, const posit_decoded<nbits, es>& rhs) {
1859 			return posit<nbits, es>(lhs) == rhs;
1860 		}
1861 		template<size_t nbits, size_t es>
operator !=(long lhs,const posit_decoded<nbits,es> & rhs)1862 		inline bool operator!=(long lhs, const posit_decoded<nbits, es>& rhs) {
1863 			return !operator==(posit<nbits, es>(lhs), rhs);
1864 		}
1865 		template<size_t nbits, size_t es>
operator <(long lhs,const posit_decoded<nbits,es> & rhs)1866 		inline bool operator< (long lhs, const posit_decoded<nbits, es>& rhs) {
1867 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
1868 		}
1869 		template<size_t nbits, size_t es>
operator >(long lhs,const posit_decoded<nbits,es> & rhs)1870 		inline bool operator> (long lhs, const posit_decoded<nbits, es>& rhs) {
1871 			return operator< (posit<nbits, es>(lhs), rhs);
1872 		}
1873 		template<size_t nbits, size_t es>
operator <=(long lhs,const posit_decoded<nbits,es> & rhs)1874 		inline bool operator<=(long lhs, const posit_decoded<nbits, es>& rhs) {
1875 			return operator< (posit<nbits, es>(lhs), rhs) || operator==(posit<nbits, es>(lhs), rhs);
1876 		}
1877 		template<size_t nbits, size_t es>
operator >=(long lhs,const posit_decoded<nbits,es> & rhs)1878 		inline bool operator>=(long lhs, const posit_decoded<nbits, es>& rhs) {
1879 			return !operator<(posit<nbits, es>(lhs), rhs);
1880 		}
1881 
1882 		// posit - unsigned long logic operators
1883 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,unsigned long rhs)1884 		inline bool operator==(const posit_decoded<nbits, es>& lhs, unsigned long rhs) {
1885 			return lhs == posit<nbits, es>(rhs);
1886 		}
1887 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,unsigned long rhs)1888 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, unsigned long rhs) {
1889 			return !operator==(lhs, posit<nbits, es>(rhs));
1890 		}
1891 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,unsigned long rhs)1892 		inline bool operator< (const posit_decoded<nbits, es>& lhs, unsigned long rhs) {
1893 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
1894 		}
1895 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,unsigned long rhs)1896 		inline bool operator> (const posit_decoded<nbits, es>& lhs, unsigned long rhs) {
1897 			return operator< (posit<nbits, es>(rhs), lhs);
1898 		}
1899 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,unsigned long rhs)1900 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, unsigned long rhs) {
1901 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
1902 		}
1903 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,unsigned long rhs)1904 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, unsigned long rhs) {
1905 			return !operator<(lhs, posit<nbits, es>(rhs));
1906 		}
1907 
1908 		// unsigned long - posit logic operators
1909 		template<size_t nbits, size_t es>
operator ==(unsigned long lhs,const posit_decoded<nbits,es> & rhs)1910 		inline bool operator==(unsigned long lhs, const posit_decoded<nbits, es>& rhs) {
1911 			return posit<nbits, es>(lhs) == rhs;
1912 		}
1913 		template<size_t nbits, size_t es>
operator !=(unsigned long lhs,const posit_decoded<nbits,es> & rhs)1914 		inline bool operator!=(unsigned long lhs, const posit_decoded<nbits, es>& rhs) {
1915 			return !operator==(posit<nbits, es>(lhs), rhs);
1916 		}
1917 		template<size_t nbits, size_t es>
operator <(unsigned long lhs,const posit_decoded<nbits,es> & rhs)1918 		inline bool operator< (unsigned long lhs, const posit_decoded<nbits, es>& rhs) {
1919 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
1920 		}
1921 		template<size_t nbits, size_t es>
operator >(unsigned long lhs,const posit_decoded<nbits,es> & rhs)1922 		inline bool operator> (unsigned long lhs, const posit_decoded<nbits, es>& rhs) {
1923 			return operator< (posit<nbits, es>(lhs), rhs);
1924 		}
1925 		template<size_t nbits, size_t es>
operator <=(unsigned long lhs,const posit_decoded<nbits,es> & rhs)1926 		inline bool operator<=(unsigned long lhs, const posit_decoded<nbits, es>& rhs) {
1927 			return operator< (posit<nbits, es>(lhs), rhs) || operator==(posit<nbits, es>(lhs), rhs);
1928 		}
1929 		template<size_t nbits, size_t es>
operator >=(unsigned long lhs,const posit_decoded<nbits,es> & rhs)1930 		inline bool operator>=(unsigned long lhs, const posit_decoded<nbits, es>& rhs) {
1931 			return !operator<(posit<nbits, es>(lhs), rhs);
1932 		}
1933 
1934 		// posit - unsigned long long logic operators
1935 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,unsigned long long rhs)1936 		inline bool operator==(const posit_decoded<nbits, es>& lhs, unsigned long long rhs) {
1937 			return lhs == posit<nbits, es>(rhs);
1938 		}
1939 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,unsigned long long rhs)1940 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, unsigned long long rhs) {
1941 			return !operator==(lhs, posit<nbits, es>(rhs));
1942 		}
1943 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,unsigned long long rhs)1944 		inline bool operator< (const posit_decoded<nbits, es>& lhs, unsigned long long rhs) {
1945 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
1946 		}
1947 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,unsigned long long rhs)1948 		inline bool operator> (const posit_decoded<nbits, es>& lhs, unsigned long long rhs) {
1949 			return operator< (posit<nbits, es>(rhs), lhs);
1950 		}
1951 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,unsigned long long rhs)1952 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, unsigned long long rhs) {
1953 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
1954 		}
1955 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,unsigned long long rhs)1956 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, unsigned long long rhs) {
1957 			return !operator<(lhs, posit<nbits, es>(rhs));
1958 		}
1959 
1960 		// unsigned long long - posit logic operators
1961 		template<size_t nbits, size_t es>
operator ==(unsigned long long lhs,const posit_decoded<nbits,es> & rhs)1962 		inline bool operator==(unsigned long long lhs, const posit_decoded<nbits, es>& rhs) {
1963 			return posit<nbits, es>(lhs) == rhs;
1964 		}
1965 		template<size_t nbits, size_t es>
operator !=(unsigned long long lhs,const posit_decoded<nbits,es> & rhs)1966 		inline bool operator!=(unsigned long long lhs, const posit_decoded<nbits, es>& rhs) {
1967 			return !operator==(posit<nbits, es>(lhs), rhs);
1968 		}
1969 		template<size_t nbits, size_t es>
operator <(unsigned long long lhs,const posit_decoded<nbits,es> & rhs)1970 		inline bool operator< (unsigned long long lhs, const posit_decoded<nbits, es>& rhs) {
1971 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
1972 		}
1973 		template<size_t nbits, size_t es>
operator >(unsigned long long lhs,const posit_decoded<nbits,es> & rhs)1974 		inline bool operator> (unsigned long long lhs, const posit_decoded<nbits, es>& rhs) {
1975 			return operator< (posit<nbits, es>(lhs), rhs);
1976 		}
1977 		template<size_t nbits, size_t es>
operator <=(unsigned long long lhs,const posit_decoded<nbits,es> & rhs)1978 		inline bool operator<=(unsigned long long lhs, const posit_decoded<nbits, es>& rhs) {
1979 			return operator< (posit<nbits, es>(lhs), rhs) || operator==(posit<nbits, es>(lhs), rhs);
1980 		}
1981 		template<size_t nbits, size_t es>
operator >=(unsigned long long lhs,const posit_decoded<nbits,es> & rhs)1982 		inline bool operator>=(unsigned long long lhs, const posit_decoded<nbits, es>& rhs) {
1983 			return !operator<(posit<nbits, es>(lhs), rhs);
1984 		}
1985 
1986 		// posit - long long logic operators
1987 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,long long rhs)1988 		inline bool operator==(const posit_decoded<nbits, es>& lhs, long long rhs) {
1989 			return lhs == posit<nbits, es>(rhs);
1990 		}
1991 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,long long rhs)1992 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, long long rhs) {
1993 			return !operator==(lhs, posit<nbits, es>(rhs));
1994 		}
1995 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,long long rhs)1996 		inline bool operator< (const posit_decoded<nbits, es>& lhs, long long rhs) {
1997 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
1998 		}
1999 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,long long rhs)2000 		inline bool operator> (const posit_decoded<nbits, es>& lhs, long long rhs) {
2001 			return operator< (posit<nbits, es>(rhs), lhs);
2002 		}
2003 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,long long rhs)2004 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, long long rhs) {
2005 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
2006 		}
2007 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,long long rhs)2008 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, long long rhs) {
2009 			return !operator<(lhs, posit<nbits, es>(rhs));
2010 		}
2011 
2012 		// long long - posit logic operators
2013 		template<size_t nbits, size_t es>
operator ==(long long lhs,const posit_decoded<nbits,es> & rhs)2014 		inline bool operator==(long long lhs, const posit_decoded<nbits, es>& rhs) {
2015 			return posit<nbits, es>(lhs) == rhs;
2016 		}
2017 		template<size_t nbits, size_t es>
operator !=(long long lhs,const posit_decoded<nbits,es> & rhs)2018 		inline bool operator!=(long long lhs, const posit_decoded<nbits, es>& rhs) {
2019 			return !operator==(posit<nbits, es>(lhs), rhs);
2020 		}
2021 		template<size_t nbits, size_t es>
operator <(long long lhs,const posit_decoded<nbits,es> & rhs)2022 		inline bool operator< (long long lhs, const posit_decoded<nbits, es>& rhs) {
2023 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
2024 		}
2025 		template<size_t nbits, size_t es>
operator >(long long lhs,const posit_decoded<nbits,es> & rhs)2026 		inline bool operator> (long long lhs, const posit_decoded<nbits, es>& rhs) {
2027 			return operator< (posit<nbits, es>(lhs), rhs);
2028 		}
2029 		template<size_t nbits, size_t es>
operator <=(long long lhs,const posit_decoded<nbits,es> & rhs)2030 		inline bool operator<=(long long lhs, const posit_decoded<nbits, es>& rhs) {
2031 			return operator< (posit<nbits, es>(lhs), rhs) || operator==(posit<nbits, es>(lhs), rhs);
2032 		}
2033 		template<size_t nbits, size_t es>
operator >=(long long lhs,const posit_decoded<nbits,es> & rhs)2034 		inline bool operator>=(long long lhs, const posit_decoded<nbits, es>& rhs) {
2035 			return !operator<(posit<nbits, es>(lhs), rhs);
2036 		}
2037 
2038 		// posit - float logic operators
2039 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,float rhs)2040 		inline bool operator==(const posit_decoded<nbits, es>& lhs, float rhs) {
2041 			return lhs == posit<nbits, es>(rhs);
2042 		}
2043 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,float rhs)2044 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, float rhs) {
2045 			return !operator==(lhs, posit<nbits, es>(rhs));
2046 		}
2047 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,float rhs)2048 		inline bool operator< (const posit_decoded<nbits, es>& lhs, float rhs) {
2049 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
2050 		}
2051 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,float rhs)2052 		inline bool operator> (const posit_decoded<nbits, es>& lhs, float rhs) {
2053 			return operator< (posit<nbits, es>(rhs), lhs);
2054 		}
2055 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,float rhs)2056 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, float rhs) {
2057 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
2058 		}
2059 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,float rhs)2060 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, float rhs) {
2061 			return !operator<(lhs, posit<nbits, es>(rhs));
2062 		}
2063 
2064 		// float  - posit logic operators
2065 		template<size_t nbits, size_t es>
operator ==(float lhs,const posit_decoded<nbits,es> & rhs)2066 		inline bool operator==(float lhs, const posit_decoded<nbits, es>& rhs) {
2067 			return posit<nbits, es>(lhs) == rhs;
2068 		}
2069 		template<size_t nbits, size_t es>
operator !=(float lhs,const posit_decoded<nbits,es> & rhs)2070 		inline bool operator!=(float lhs, const posit_decoded<nbits, es>& rhs) {
2071 			return !operator==(posit<nbits, es>(lhs), rhs);
2072 		}
2073 		template<size_t nbits, size_t es>
operator <(float lhs,const posit_decoded<nbits,es> & rhs)2074 		inline bool operator< (float lhs, const posit_decoded<nbits, es>& rhs) {
2075 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
2076 		}
2077 		template<size_t nbits, size_t es>
operator >(float lhs,const posit_decoded<nbits,es> & rhs)2078 		inline bool operator> (float lhs, const posit_decoded<nbits, es>& rhs) {
2079 			return operator< (posit<nbits, es>(lhs), rhs);
2080 		}
2081 		template<size_t nbits, size_t es>
operator <=(float lhs,const posit_decoded<nbits,es> & rhs)2082 		inline bool operator<=(float lhs, const posit_decoded<nbits, es>& rhs) {
2083 			return operator< (posit<nbits, es>(lhs)), rhs || operator==(posit<nbits, es>(lhs), rhs);
2084 		}
2085 		template<size_t nbits, size_t es>
operator >=(float lhs,const posit_decoded<nbits,es> & rhs)2086 		inline bool operator>=(float lhs, const posit_decoded<nbits, es>& rhs) {
2087 			return !operator<(posit<nbits, es>(lhs), rhs);
2088 		}
2089 
2090 		// posit - double logic operators
2091 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,double rhs)2092 		inline bool operator==(const posit_decoded<nbits, es>& lhs, double rhs) {
2093 			return lhs == posit<nbits, es>(rhs);
2094 		}
2095 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,double rhs)2096 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, double rhs) {
2097 			return !operator==(lhs, posit<nbits, es>(rhs));
2098 		}
2099 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,double rhs)2100 		inline bool operator< (const posit_decoded<nbits, es>& lhs, double rhs) {
2101 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
2102 		}
2103 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,double rhs)2104 		inline bool operator> (const posit_decoded<nbits, es>& lhs, double rhs) {
2105 			return operator< (posit<nbits, es>(rhs), lhs);
2106 		}
2107 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,double rhs)2108 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, double rhs) {
2109 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
2110 		}
2111 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,double rhs)2112 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, double rhs) {
2113 			return !operator<(lhs, posit<nbits, es>(rhs));
2114 		}
2115 
2116 		// double  - posit logic operators
2117 		template<size_t nbits, size_t es>
operator ==(double lhs,const posit_decoded<nbits,es> & rhs)2118 		inline bool operator==(double lhs, const posit_decoded<nbits, es>& rhs) {
2119 			return posit<nbits, es>(lhs) == rhs;
2120 		}
2121 		template<size_t nbits, size_t es>
operator !=(double lhs,const posit_decoded<nbits,es> & rhs)2122 		inline bool operator!=(double lhs, const posit_decoded<nbits, es>& rhs) {
2123 			return !operator==(posit<nbits, es>(lhs), rhs);
2124 		}
2125 		template<size_t nbits, size_t es>
operator <(double lhs,const posit_decoded<nbits,es> & rhs)2126 		inline bool operator< (double lhs, const posit_decoded<nbits, es>& rhs) {
2127 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
2128 		}
2129 		template<size_t nbits, size_t es>
operator >(double lhs,const posit_decoded<nbits,es> & rhs)2130 		inline bool operator> (double lhs, const posit_decoded<nbits, es>& rhs) {
2131 			return operator< (posit<nbits, es>(lhs), rhs);
2132 		}
2133 		template<size_t nbits, size_t es>
operator <=(double lhs,const posit_decoded<nbits,es> & rhs)2134 		inline bool operator<=(double lhs, const posit_decoded<nbits, es>& rhs) {
2135 			return operator< (posit<nbits, es>(lhs)), rhs || operator==(posit<nbits, es>(lhs), rhs);
2136 		}
2137 		template<size_t nbits, size_t es>
operator >=(double lhs,const posit_decoded<nbits,es> & rhs)2138 		inline bool operator>=(double lhs, const posit_decoded<nbits, es>& rhs) {
2139 			return !operator<(posit<nbits, es>(lhs), rhs);
2140 		}
2141 
2142 		// posit - long double logic operators
2143 		template<size_t nbits, size_t es>
operator ==(const posit_decoded<nbits,es> & lhs,long double rhs)2144 		inline bool operator==(const posit_decoded<nbits, es>& lhs, long double rhs) {
2145 			return lhs == posit<nbits, es>(rhs);
2146 		}
2147 		template<size_t nbits, size_t es>
operator !=(const posit_decoded<nbits,es> & lhs,long double rhs)2148 		inline bool operator!=(const posit_decoded<nbits, es>& lhs, long double rhs) {
2149 			return !operator==(lhs, posit<nbits, es>(rhs));
2150 		}
2151 		template<size_t nbits, size_t es>
operator <(const posit_decoded<nbits,es> & lhs,long double rhs)2152 		inline bool operator< (const posit_decoded<nbits, es>& lhs, long double rhs) {
2153 			return lessThan(lhs._raw_bits, posit<nbits, es>(rhs)._raw_bits);
2154 		}
2155 		template<size_t nbits, size_t es>
operator >(const posit_decoded<nbits,es> & lhs,long double rhs)2156 		inline bool operator> (const posit_decoded<nbits, es>& lhs, long double rhs) {
2157 			return operator< (posit<nbits, es>(rhs), lhs);
2158 		}
2159 		template<size_t nbits, size_t es>
operator <=(const posit_decoded<nbits,es> & lhs,long double rhs)2160 		inline bool operator<=(const posit_decoded<nbits, es>& lhs, long double rhs) {
2161 			return operator< (lhs, posit<nbits, es>(rhs)) || operator==(lhs, posit<nbits, es>(rhs));
2162 		}
2163 		template<size_t nbits, size_t es>
operator >=(const posit_decoded<nbits,es> & lhs,long double rhs)2164 		inline bool operator>=(const posit_decoded<nbits, es>& lhs, long double rhs) {
2165 			return !operator<(lhs, posit<nbits, es>(rhs));
2166 		}
2167 
2168 		// long double  - posit logic operators
2169 		template<size_t nbits, size_t es>
operator ==(long double lhs,const posit_decoded<nbits,es> & rhs)2170 		inline bool operator==(long double lhs, const posit_decoded<nbits, es>& rhs) {
2171 			return posit<nbits, es>(lhs) == rhs;
2172 		}
2173 		template<size_t nbits, size_t es>
operator !=(long double lhs,const posit_decoded<nbits,es> & rhs)2174 		inline bool operator!=(long double lhs, const posit_decoded<nbits, es>& rhs) {
2175 			return !operator==(posit<nbits, es>(lhs), rhs);
2176 		}
2177 		template<size_t nbits, size_t es>
operator <(long double lhs,const posit_decoded<nbits,es> & rhs)2178 		inline bool operator< (long double lhs, const posit_decoded<nbits, es>& rhs) {
2179 			return lessThan(posit<nbits, es>(lhs)._raw_bits, rhs._raw_bits);
2180 		}
2181 		template<size_t nbits, size_t es>
operator >(long double lhs,const posit_decoded<nbits,es> & rhs)2182 		inline bool operator> (long double lhs, const posit_decoded<nbits, es>& rhs) {
2183 			return operator< (posit<nbits, es>(lhs), rhs);
2184 		}
2185 		template<size_t nbits, size_t es>
operator <=(long double lhs,const posit_decoded<nbits,es> & rhs)2186 		inline bool operator<=(long double lhs, const posit_decoded<nbits, es>& rhs) {
2187 			return operator< (posit<nbits, es>(lhs)), rhs || operator==(posit<nbits, es>(lhs), rhs);
2188 		}
2189 		template<size_t nbits, size_t es>
operator >=(long double lhs,const posit_decoded<nbits,es> & rhs)2190 		inline bool operator>=(long double lhs, const posit_decoded<nbits, es>& rhs) {
2191 			return !operator<(posit<nbits, es>(lhs), rhs);
2192 		}
2193 
2194 		// BINARY ADDITION
2195 		template<size_t nbits, size_t es>
operator +(const posit_decoded<nbits,es> & lhs,double rhs)2196 		inline posit_decoded<nbits, es> operator+(const posit_decoded<nbits, es>& lhs, double rhs) {
2197 			posit_decoded<nbits, es> sum = lhs;
2198 			sum += rhs;
2199 			return sum;
2200 		}
2201 		template<size_t nbits, size_t es>
operator +(double lhs,const posit_decoded<nbits,es> & rhs)2202 		inline posit_decoded<nbits, es> operator+(double lhs, const posit_decoded<nbits, es>& rhs) {
2203 			posit_decoded<nbits, es> sum = lhs;
2204 			sum += rhs;
2205 			return sum;
2206 		}
2207 
2208 		// BINARY SUBTRACTION
2209 		template<size_t nbits, size_t es>
operator -(double lhs,const posit_decoded<nbits,es> & rhs)2210 		inline posit_decoded<nbits, es> operator-(double lhs, const posit_decoded<nbits, es>& rhs) {
2211 			posit_decoded<nbits, es> sum = lhs;
2212 			sum -= rhs;
2213 			return sum;
2214 		}
2215 		template<size_t nbits, size_t es>
operator -(const posit_decoded<nbits,es> & lhs,double rhs)2216 		inline posit_decoded<nbits, es> operator-(const posit_decoded<nbits, es>& lhs, double rhs) {
2217 			posit_decoded<nbits, es> diff = lhs;
2218 			diff -= rhs;
2219 			return diff;
2220 		}
2221 		// BINARY MULTIPLICATION
2222 		template<size_t nbits, size_t es>
operator *(double lhs,const posit_decoded<nbits,es> & rhs)2223 		inline posit_decoded<nbits, es> operator*(double lhs, const posit_decoded<nbits, es>& rhs) {
2224 			posit_decoded<nbits, es> sum = lhs;
2225 			sum *= rhs;
2226 			return sum;
2227 		}
2228 		template<size_t nbits, size_t es>
operator *(const posit_decoded<nbits,es> & lhs,double rhs)2229 		inline posit_decoded<nbits, es> operator*(const posit_decoded<nbits, es>& lhs, double rhs) {
2230 			posit_decoded<nbits, es> mul = lhs;
2231 			mul *= rhs;
2232 			return mul;
2233 		}
2234 		// BINARY DIVISION
2235 		template<size_t nbits, size_t es>
operator /(double lhs,const posit_decoded<nbits,es> & rhs)2236 		inline posit_decoded<nbits, es> operator/(double lhs, const posit_decoded<nbits, es>& rhs) {
2237 			posit_decoded<nbits, es> sum = lhs;
2238 			sum /= rhs;
2239 			return sum;
2240 		}
2241 		template<size_t nbits, size_t es>
operator /(const posit_decoded<nbits,es> & lhs,double rhs)2242 		inline posit_decoded<nbits, es> operator/(const posit_decoded<nbits, es>& lhs, double rhs) {
2243 			posit_decoded<nbits, es> ratio = lhs;
2244 			ratio /= rhs;
2245 			return ratio;
2246 		}
2247 
2248 		#endif // POSIT_ENABLE_LITERALS
2249 
2250 		// Sign of a posit
2251 		template<size_t nbits, size_t es>
sign(const posit_decoded<nbits,es> & p)2252 		bool sign(const posit_decoded<nbits,es>& p) {
2253 			return p.get_sign();
2254 		}
2255 
2256 		// Magnitude of a posit (equivalent to turning the sign bit off).
2257 		template<size_t nbits, size_t es>
abs(const posit_decoded<nbits,es> & p)2258 		posit_decoded<nbits, es> abs(const posit_decoded<nbits, es>& p) {
2259 			return posit_decoded<nbits, es>(false, p.get_regime(), p.get_exponent(), p.get_fraction());
2260 		}
2261 		template<size_t nbits, size_t es>
fabs(const posit_decoded<nbits,es> & p)2262 		posit_decoded<nbits, es> fabs(const posit_decoded<nbits, es>& p) {
2263 			return posit_decoded<nbits, es>(false, p.get_regime(), p.get_exponent(), p.get_fraction());
2264 		}
2265 
2266 		// Atomic fused operators
2267 
2268 		// FMA: fused multiply-add:  a*b + c
2269 		template<size_t nbits, size_t es>
fma(const posit_decoded<nbits,es> & a,const posit_decoded<nbits,es> & b,const posit_decoded<nbits,es> & c)2270 		value<1 + 2 * (nbits - es)> fma(const posit_decoded<nbits, es>& a, const posit_decoded<nbits, es>& b, const posit_decoded<nbits, es>& c) {
2271 			constexpr size_t fbits = nbits - 3 - es;
2272 			constexpr size_t fhbits = fbits + 1;      // size of fraction + hidden bit
2273 			constexpr size_t mbits = 2 * fhbits;      // size of the multiplier output
2274 			constexpr size_t abits = mbits + 4;       // size of the addend
2275 
2276 
2277 			// first the multiply
2278 			value<mbits> product;
2279 			value<fbits> va, vb, ctmp;
2280 
2281 			if (!a.iszero() && !b.iszero()) {
2282 				// transform the inputs into (sign,scale,fraction) triples
2283 				va.set(a.get_sign(), a.scale(), a.get_fraction().get(), a.iszero(), a.isnar());;
2284 				vb.set(b.get_sign(), b.scale(), b.get_fraction().get(), b.iszero(), b.isnar());;
2285 
2286 				module_multiply(va, vb, product);    // multiply the two inputs
2287 			}
2288 		//	if (c.iszero()) return product;	// product isn't the right size
2289 			// second, the add
2290 			ctmp.set(c.get_sign(), c.scale(), c.get_fraction().get(), c.iszero(), c.isnar());
2291 			value<mbits> vc;
2292 			vc.template right_extend<fbits,mbits>(ctmp);
2293 			value<abits+1> sum;
2294 			module_add<mbits,abits>(product, vc, sum);
2295 
2296 			return sum;
2297 		}
2298 
2299 		// FAM: fused add-multiply: (a + b) * c
2300 		template<size_t nbits, size_t es>
fam(const posit_decoded<nbits,es> & a,const posit_decoded<nbits,es> & b,const posit_decoded<nbits,es> & c)2301 		value<2 * (nbits - 2 - es)> fam(const posit_decoded<nbits, es>& a, const posit_decoded<nbits, es>& b, const posit_decoded<nbits, es>& c) {
2302 			constexpr size_t fbits = nbits - 3 - es;
2303 			constexpr size_t abits = fbits + 4;       // size of the addend
2304 			constexpr size_t fhbits = fbits + 1;      // size of fraction + hidden bit
2305 			constexpr size_t mbits = 2 * fhbits;      // size of the multiplier output
2306 
2307 			// first the add
2308 			value<abits+1> sum;
2309 			value<fbits> va, vb, vc;
2310 
2311 			if (!a.iszero() || !b.iszero()) {
2312 				// transform the inputs into (sign,scale,fraction) triples
2313 				va.set(a.get_sign(), a.scale(), a.get_fraction().get(), a.iszero(), a.isnar());;
2314 				vb.set(b.get_sign(), b.scale(), b.get_fraction().get(), b.iszero(), b.isnar());;
2315 
2316 				module_add(va, vb, sum);    // multiply the two inputs
2317 			}
2318 			// second the multiply
2319 			value<mbits> product;
2320 			if (c.iszero()) return product;
2321 			vc.set(c.get_size(), c.scale(), c.get_fraction().get(), c.iszero(), c.isnar());
2322 			module_multiply(sum, c, product);
2323 			return product;
2324 		}
2325 
2326 		// FMMA: fused multiply-multiply-add: (a * b) +/- (c * d)
2327 		template<size_t nbits, size_t es>
fmma(const posit<nbits,es> & a,const posit_decoded<nbits,es> & b,const posit_decoded<nbits,es> & c,const posit_decoded<nbits,es> & d,bool opIsAdd=true)2328 		value<nbits> fmma(const posit<nbits, es>& a, const posit_decoded<nbits, es>& b, const posit_decoded<nbits, es>& c, const posit_decoded<nbits, es>& d, bool opIsAdd = true)
2329 		{
2330 			// todo: implement
2331 			value<nbits> result;
2332 			return result;
2333 		}
2334 
2335 		// QUIRE OPERATORS
2336 		// Why are they defined here and not in quire.hpp? TODO
2337 
2338 		template<size_t nbits, size_t es>
quire_add(const posit_decoded<nbits,es> & lhs,const posit_decoded<nbits,es> & rhs)2339 		value<nbits - es + 2> quire_add(const posit_decoded<nbits, es>& lhs, const posit_decoded<nbits, es>& rhs) {
2340 			static constexpr size_t fbits = nbits - 3 - es;
2341 			static constexpr size_t abits = fbits + 4;       // size of the addend
2342 			value<abits + 1> sum;
2343 			value<fbits> a, b;
2344 
2345 			if (lhs.iszero() && rhs.iszero()) return sum;
2346 
2347 			// transform the inputs into (sign,scale,fraction) triples
2348 			a.set(lhs.get_sign(), lhs.scale(), lhs.get_fraction().get(), lhs.iszero(), lhs.isnar());;
2349 			b.set(rhs.get_sign(), rhs.scale(), rhs.get_fraction().get(), rhs.iszero(), rhs.isnar());;
2350 
2351 			module_add<fbits, abits>(a, b, sum);		// add the two inputs
2352 
2353 			return sum;
2354 		}
2355 
2356 		template<size_t nbits, size_t es>
quire_mul(const posit_decoded<nbits,es> & lhs,const posit_decoded<nbits,es> & rhs)2357 		value<2*(nbits - 2 - es)> quire_mul(const posit_decoded<nbits, es>& lhs, const posit_decoded<nbits, es>& rhs) {
2358 			static constexpr size_t fbits = nbits - 3 - es;
2359 			static constexpr size_t fhbits = fbits + 1;      // size of fraction + hidden bit
2360 			static constexpr size_t mbits = 2 * fhbits;      // size of the multiplier output
2361 
2362 			value<mbits> product;
2363 			value<fbits> a, b;
2364 
2365 			if (lhs.iszero() || rhs.iszero()) return product;
2366 
2367 			// transform the inputs into (sign,scale,fraction) triples
2368 			a.set(lhs.get_sign(), lhs.scale(), lhs.get_fraction().get(), lhs.iszero(), lhs.isnar());;
2369 			b.set(rhs.get_sign(), rhs.scale(), rhs.get_fraction().get(), rhs.iszero(), rhs.isnar());;
2370 
2371 			module_multiply(a, b, product);    // multiply the two inputs
2372 
2373 			return product;
2374 		}
2375 
2376 	}  // namespace unum
2377 
2378 }  // namespace sw
2379