sc_unsigned.cpp

来自「基于4个mips核的noc设计」· C++ 代码 · 共 1,853 行 · 第 1/3 页

CPP
1,853
字号
// Cases to consider when computing u + v:// 1. u - 0 = u // 2. 0 - v = -v// 3. if sgn(u) != sgn(v)//    3.1 u - (-v) = u + v = sgn(u) * (u + v)//    3.2 (-u) - v = -(u + v) ==> sgn(u) * (u + v)// 4. if sgn(u) == sgn(v)//    4.1 u - v = +(u - v) = sgn(u) * (u - v) //    4.2 (-u) - (-v) = -(u - v) = sgn(u) * (u - v)//// Specialization of above cases for computing --u or u--: // 1. 0 - 1 = -1// 3. (-u) - 1 = -(u + 1) = sgn(u) * (u + 1)// 4. u - 1 = u - 1 = sgn(u) * (u - 1)// The operators in this section are included from sc_nbcommon.cpp.// ----------------------------------------------------------------------------//  SECTION: MULTIPLICATION operators: *, *=// ----------------------------------------------------------------------------// Cases to consider when computing u * v:// 1. u * 0 = 0 * v = 0// 2. 1 * v = v and -1 * v = -v// 3. u * 1 = u and u * -1 = -u// 4. u * v = u * vsc_unsignedoperator*(const sc_unsigned& u, const sc_unsigned& v){   small_type s = mul_signs(u.sgn, v.sgn);  if (s == SC_ZERO) // case 1    return sc_unsigned();  // cases 2-4  return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit,                             v.nbits, v.ndigits, v.digit);}sc_unsignedoperator*(const sc_unsigned& u, uint64 v){  small_type s = mul_signs(u.sgn, get_sign(v));  if (s == SC_ZERO) // case 1    return sc_unsigned();  CONVERT_INT64_2(v);  // cases 2-4  return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit,                              BITS_PER_UINT64, DIGITS_PER_UINT64, vd);  }sc_unsignedoperator*(uint64 u, const sc_unsigned& v){  small_type s = mul_signs(v.sgn, get_sign(u));  if (s == SC_ZERO) // case 1    return sc_unsigned();  CONVERT_INT64_2(u);  // cases 2-4  return mul_unsigned_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,                              v.nbits, v.ndigits, v.digit);  }sc_unsignedoperator*(const sc_unsigned& u, unsigned long v){  small_type s = mul_signs(u.sgn, get_sign(v));  if (s == SC_ZERO) // case 1    return sc_unsigned();  CONVERT_LONG_2(v);  // else cases 2-4  return mul_unsigned_friend(s, u.nbits, u.ndigits, u.digit,                              BITS_PER_ULONG, DIGITS_PER_ULONG, vd);  }sc_unsignedoperator*(unsigned long u, const sc_unsigned& v){  small_type s = mul_signs(v.sgn, get_sign(u));  if (s == SC_ZERO) // case 1    return sc_unsigned();  CONVERT_LONG_2(u);  // cases 2-4  return mul_unsigned_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,                              v.nbits, v.ndigits, v.digit);  }// The rest of the operators in this section are included from// sc_nbcommon.cpp.// ----------------------------------------------------------------------------//  SECTION: DIVISION operators: /, /=// ----------------------------------------------------------------------------// Cases to consider when finding the quotient q = floor(u/v):// Note that u = q * v + r for r < q.// 1. 0 / 0 or u / 0 => error// 2. 0 / v => 0 = 0 * v + 0// 3. u / v && u = v => u = 1 * u + 0  - u or v can be 1 or -1// 4. u / v && u < v => u = 0 * v + u  - u can be 1 or -1// 5. u / v && u > v => u = q * v + r  - v can be 1 or -1sc_unsignedoperator/(const sc_unsigned& u, const sc_unsigned& v){  small_type s = mul_signs(u.sgn, v.sgn);  if (s == SC_ZERO) {    div_by_zero(v.sgn); // case 1    return sc_unsigned();  // case 2  }  // other cases  return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit,                             v.nbits, v.ndigits, v.digit);}sc_unsignedoperator/(const sc_unsigned& u, uint64 v){  small_type s = mul_signs(u.sgn, get_sign(v));  if (s == SC_ZERO) {    div_by_zero(v);  // case 1    return sc_unsigned();  // case 2  }  CONVERT_INT64_2(v);  // other cases  return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit,                              BITS_PER_UINT64, DIGITS_PER_UINT64, vd);  }sc_unsignedoperator/(uint64 u, const sc_unsigned& v){  small_type s = mul_signs(v.sgn, get_sign(u));  if (s == SC_ZERO) {    div_by_zero(v.sgn);  // case 1    return sc_unsigned();  // case 2  }  CONVERT_INT64_2(u);  // other cases  return div_unsigned_friend(s, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,                              v.nbits, v.ndigits, v.digit);  }sc_unsignedoperator/(const sc_unsigned& u, unsigned long v){  small_type s = mul_signs(u.sgn, get_sign(v));  if (s == SC_ZERO) {    div_by_zero(v);  // case 1    return sc_unsigned();  // case 2  }  CONVERT_LONG_2(v);  // other cases  return div_unsigned_friend(s, u.nbits, u.ndigits, u.digit,                              BITS_PER_ULONG, DIGITS_PER_ULONG, vd);  }sc_unsignedoperator/(unsigned long u, const sc_unsigned& v){  small_type s = mul_signs(v.sgn, get_sign(u));  if (s == SC_ZERO) {    div_by_zero(v.sgn);  // case 1    return sc_unsigned();  // case 2  }  CONVERT_LONG_2(u);  // other cases  return div_unsigned_friend(s, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,                              v.nbits, v.ndigits, v.digit);  }// The rest of the operators in this section are included from// sc_nbcommon.cpp.// ----------------------------------------------------------------------------//  SECTION: MOD operators: %, %=.// ----------------------------------------------------------------------------// Cases to consider when finding the remainder r = u % v:// Note that u = q * v + r for r < q.// 1. 0 % 0 or u % 0 => error// 2. 0 % v => 0 = 0 * v + 0// 3. u % v && u = v => u = 1 * u + 0  - u or v can be 1 or -1// 4. u % v && u < v => u = 0 * v + u  - u can be 1 or -1// 5. u % v && u > v => u = q * v + r  - v can be 1 or -1sc_unsignedoperator%(const sc_unsigned& u, const sc_unsigned& v){  if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) {    div_by_zero(v.sgn);  // case 1    return sc_unsigned();  // case 2  }  // other cases  return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,                             v.nbits, v.ndigits, v.digit);}sc_unsignedoperator%(const sc_unsigned& u, uint64 v){  if ((u.sgn == SC_ZERO) || (v == 0)) {    div_by_zero(v);  // case 1    return sc_unsigned();  // case 2  }  CONVERT_INT64_2(v);  // other cases  return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,                             BITS_PER_UINT64, DIGITS_PER_UINT64, vd);}sc_unsignedoperator%(uint64 u, const sc_unsigned& v){  if ((u == 0) || (v.sgn == SC_ZERO)) {    div_by_zero(v.sgn);  // case 1    return sc_unsigned();  // case 2  }  CONVERT_INT64(u);  // other cases  return mod_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,                             v.nbits, v.ndigits, v.digit);}sc_unsignedoperator%(const sc_unsigned& u, unsigned long v){  if ((u.sgn == SC_ZERO) || (v == 0)) {    div_by_zero(v);  // case 1    return sc_unsigned();  // case 2  }  CONVERT_LONG_2(v);  // other cases  return mod_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,                             BITS_PER_ULONG, DIGITS_PER_ULONG, vd);}sc_unsignedoperator%(unsigned long u, const sc_unsigned& v){  if ((u == 0) || (v.sgn == SC_ZERO)) {    div_by_zero(v.sgn);  // case 1    return sc_unsigned();  // case 2  }  CONVERT_LONG(u);  // other cases  return mod_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,                             v.nbits, v.ndigits, v.digit);}// The rest of the operators in this section are included from// sc_nbcommon.cpp.// ----------------------------------------------------------------------------//  SECTION: Bitwise AND operators: &, &=// ----------------------------------------------------------------------------// Cases to consider when computing u & v:// 1. u & 0 = 0 & v = 0// 2. u & v => sgn = +// 3. (-u) & (-v) => sgn = -// 4. u & (-v) => sgn = +// 5. (-u) & v => sgn = +sc_unsignedoperator&(const sc_unsigned& u, const sc_unsigned& v){  if ((u.sgn == SC_ZERO) || (v.sgn == SC_ZERO)) // case 1    return sc_unsigned();  // other cases  return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,                             v.sgn, v.nbits, v.ndigits, v.digit);}sc_unsignedoperator&(const sc_unsigned& u, uint64 v){  if ((u.sgn == SC_ZERO) || (v == 0)) // case 1    return sc_unsigned();  CONVERT_INT64(v);  // other cases  return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,                             vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);  }sc_unsignedoperator&(uint64 u, const sc_unsigned& v){  if ((u == 0) || (v.sgn == SC_ZERO)) // case 1    return sc_unsigned();  CONVERT_INT64(u);  // other cases  return and_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,                             v.sgn, v.nbits, v.ndigits, v.digit);}sc_unsignedoperator&(const sc_unsigned& u, unsigned long v){  if ((u.sgn == SC_ZERO) || (v == 0)) // case 1    return sc_unsigned();  CONVERT_LONG(v);  // other cases  return and_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,                             vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);}sc_unsignedoperator&(unsigned long u, const sc_unsigned& v){  if ((u == 0) || (v.sgn == SC_ZERO)) // case 1    return sc_unsigned();  CONVERT_LONG(u);  // other cases  return and_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,                             v.sgn, v.nbits, v.ndigits, v.digit);}// The rest of the operators in this section are included from// sc_nbcommon.cpp.// ----------------------------------------------------------------------------//  SECTION: Bitwise OR operators: |, |=// ----------------------------------------------------------------------------// Cases to consider when computing u | v:// 1. u | 0 = u// 2. 0 | v = v// 3. u | v => sgn = +// 4. (-u) | (-v) => sgn = -// 5. u | (-v) => sgn = -// 6. (-u) | v => sgn = -sc_unsignedoperator|(const sc_unsigned& u, const sc_unsigned& v){  if (v.sgn == SC_ZERO)  // case 1    return sc_unsigned(u);  if (u.sgn == SC_ZERO)  // case 2    return sc_unsigned(v);  // other cases  return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,                            v.sgn, v.nbits, v.ndigits, v.digit);}sc_unsignedoperator|(const sc_unsigned& u, uint64 v){  if (v == 0)  // case 1    return sc_unsigned(u);  CONVERT_INT64(v);  if (u.sgn == SC_ZERO)  // case 2    return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);  // other cases  return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,                            vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);}sc_unsignedoperator|(uint64 u, const sc_unsigned& v){  if (u == 0)    return sc_unsigned(v);  CONVERT_INT64(u);  if (v.sgn == SC_ZERO)    return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);  // other cases  return or_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,                            v.sgn, v.nbits, v.ndigits, v.digit);}sc_unsignedoperator|(const sc_unsigned& u, unsigned long v){  if (v == 0)  // case 1    return sc_unsigned(u);  CONVERT_LONG(v);  if (u.sgn == SC_ZERO)  // case 2    return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);  // other cases  return or_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,                            vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);}sc_unsignedoperator|(unsigned long u, const sc_unsigned& v){  if (u == 0)    return sc_unsigned(v);  CONVERT_LONG(u);  if (v.sgn == SC_ZERO)    return sc_unsigned(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud, false);  // other cases  return or_unsigned_friend(us, BITS_PER_ULONG, DIGITS_PER_ULONG, ud,                            v.sgn, v.nbits, v.ndigits, v.digit);}// The rest of the operators in this section are included from// sc_nbcommon.cpp.// ----------------------------------------------------------------------------//  SECTION: Bitwise XOR operators: ^, ^=// ----------------------------------------------------------------------------// Cases to consider when computing u ^ v:// Note that  u ^ v = (~u & v) | (u & ~v).// 1. u ^ 0 = u// 2. 0 ^ v = v// 3. u ^ v => sgn = +// 4. (-u) ^ (-v) => sgn = -// 5. u ^ (-v) => sgn = -// 6. (-u) ^ v => sgn = +sc_unsignedoperator^(const sc_unsigned& u, const sc_unsigned& v){  if (v.sgn == SC_ZERO)  // case 1    return sc_unsigned(u);  if (u.sgn == SC_ZERO)  // case 2    return sc_unsigned(v);  // other cases  return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,                             v.sgn, v.nbits, v.ndigits, v.digit);}sc_unsignedoperator^(const sc_unsigned& u, uint64 v){  if (v == 0)  // case 1    return sc_unsigned(u);  CONVERT_INT64(v);  if (u.sgn == SC_ZERO)  // case 2    return sc_unsigned(vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd, false);  // other cases  return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,                             vs, BITS_PER_UINT64, DIGITS_PER_UINT64, vd);}sc_unsignedoperator^(uint64 u, const sc_unsigned& v){  if (u == 0)    return sc_unsigned(v);  CONVERT_INT64(u);  if (v.sgn == SC_ZERO)    return sc_unsigned(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud, false);  // other cases  return xor_unsigned_friend(us, BITS_PER_UINT64, DIGITS_PER_UINT64, ud,                             v.sgn, v.nbits, v.ndigits, v.digit);}sc_unsignedoperator^(const sc_unsigned& u, unsigned long v){  if (v == 0)  // case 1    return sc_unsigned(u);  CONVERT_LONG(v);  if (u.sgn == SC_ZERO)  // case 2    return sc_unsigned(vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd, false);  // other cases  return xor_unsigned_friend(u.sgn, u.nbits, u.ndigits, u.digit,                             vs, BITS_PER_ULONG, DIGITS_PER_ULONG, vd);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?