( num: bigint, den: bigint, scale: number, precision: number )
| 299 | * Internal function used for arbitrary precision division. |
| 300 | */ |
| 301 | const divideWithPrecision = ( |
| 302 | num: bigint, |
| 303 | den: bigint, |
| 304 | scale: number, |
| 305 | precision: number |
| 306 | ): BigDecimal => { |
| 307 | const numNegative = num < bigint0 |
| 308 | const denNegative = den < bigint0 |
| 309 | const negateResult = numNegative !== denNegative |
| 310 | |
| 311 | num = numNegative ? -num : num |
| 312 | den = denNegative ? -den : den |
| 313 | |
| 314 | // Shift digits until numerator is larger than denominator (set scale appropriately). |
| 315 | while (num < den) { |
| 316 | num *= bigint10 |
| 317 | scale++ |
| 318 | } |
| 319 | |
| 320 | // First division. |
| 321 | let quotient = num / den |
| 322 | let remainder = num % den |
| 323 | |
| 324 | if (remainder === bigint0) { |
| 325 | // No remainder, return immediately. |
| 326 | return make(negateResult ? -quotient : quotient, scale) |
| 327 | } |
| 328 | |
| 329 | // The quotient is guaranteed to be non-negative at this point. No need to consider sign. |
| 330 | let count = `${quotient}`.length |
| 331 | |
| 332 | // Shift the remainder by 1 decimal; The quotient will be 1 digit upon next division. |
| 333 | remainder *= bigint10 |
| 334 | while (remainder !== bigint0 && count < precision) { |
| 335 | const q = remainder / den |
| 336 | const r = remainder % den |
| 337 | quotient = quotient * bigint10 + q |
| 338 | remainder = r * bigint10 |
| 339 | |
| 340 | count++ |
| 341 | scale++ |
| 342 | } |
| 343 | |
| 344 | if (remainder !== bigint0) { |
| 345 | // Round final number with remainder. |
| 346 | quotient += roundTerminal(remainder / den) |
| 347 | } |
| 348 | |
| 349 | return make(negateResult ? -quotient : quotient, scale) |
| 350 | } |
| 351 | |
| 352 | /** |
| 353 | * Internal function used for rounding. |
no test coverage detected