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