BigFloat BigFloat::usub(const BigFloat &x,size_t p) const{ // Perform subtraction ignoring the sign of the two operands. // "this" must be greater than or equal to x. Otherwise, the behavior // is undefined. // Magnitude int64_t magA = exp + L; int64_t magB = x.exp + x.L; int64_t top = std::max(magA,magB); int64_t bot = std::min(exp,x.exp); // Truncate precision int64_t TL = top - bot; if (p == 0){ // Default value. No trunction. p = (size_t)TL; }else{ // Increase precision p += YCL_BIGFLOAT_EXTRA_PRECISION; } if (TL > (int64_t)p){ bot = top - p; TL = p; } // Compute basic fields. BigFloat z; z.sign = sign; z.exp = bot; z.L = (uint32_t)TL; // Allocate mantissa z.T = std::unique_ptr<uint32_t[]>(new uint32_t[z.L]); // Subtract int32_t carry = 0; for (size_t c = 0; bot < top; bot++, c++){ int32_t word = (int32_t)word_at(bot) - (int32_t)x.word_at(bot) - carry; carry = 0; if (word < 0){ word += 1000000000; carry = 1; } z.T[c] = word; } // Strip leading zeros while (z.L > 0 && z.T[z.L - 1] == 0) z.L--; if (z.L == 0){ z.exp = 0; z.sign = true; z.T.reset(); } return z; }
int BigFloat::ucmp(const BigFloat &x) const{ // Compare function that ignores the sign. // This is needed to determine which direction subtractions will go. // Magnitude int64_t magA = exp + L; int64_t magB = x.exp + x.L; if (magA > magB) return 1; if (magA < magB) return -1; // Compare int64_t mag = magA; while (mag >= exp || mag >= x.exp){ uint32_t wordA = word_at(mag); uint32_t wordB = x.word_at(mag); if (wordA < wordB) return -1; if (wordA > wordB) return 1; mag--; } return 0; }
BigFloat BigFloat::uadd(const BigFloat &x,size_t p) const{ // Perform addition ignoring the sign of the two operands. // Magnitude int64_t magA = exp + L; int64_t magB = x.exp + x.L; int64_t top = std::max(magA,magB); int64_t bot = std::min(exp,x.exp); // Target length int64_t TL = top - bot; if (p == 0){ // Default value. No trunction. p = (size_t)TL; }else{ // Increase precision p += YCL_BIGFLOAT_EXTRA_PRECISION; } // Perform precision truncation. if (TL > (int64_t)p){ bot = top - p; TL = p; } // Compute basic fields. BigFloat z; z.sign = sign; z.exp = bot; z.L = (uint32_t)TL; // Allocate mantissa z.T = std::unique_ptr<uint32_t[]>(new uint32_t[z.L + 1]); // Add uint32_t carry = 0; for (size_t c = 0; bot < top; bot++, c++){ uint32_t word = word_at(bot) + x.word_at(bot) + carry; carry = 0; if (word >= 1000000000){ word -= 1000000000; carry = 1; } z.T[c] = word; } // Carry out if (carry != 0){ z.T[z.L++] = 1; } return z; }