Frexp10 is an analogue of math.Frexp for decimal powers. It scales f by an approximate power of ten 10^-exp, and returns exp10, so that f*10^exp10 has the same value as the old f, up to an ulp, as well as the index of 10^-exp in the powersOfTen table.
()
| 334 | // that f*10^exp10 has the same value as the old f, up to an ulp, |
| 335 | // as well as the index of 10^-exp in the powersOfTen table. |
| 336 | func (f *extFloat) frexp10() (exp10, index int) { |
| 337 | // The constants expMin and expMax constrain the final value of the |
| 338 | // binary exponent of f. We want a small integral part in the result |
| 339 | // because finding digits of an integer requires divisions, whereas |
| 340 | // digits of the fractional part can be found by repeatedly multiplying |
| 341 | // by 10. |
| 342 | const expMin = -60 |
| 343 | const expMax = -32 |
| 344 | // Find power of ten such that x * 10^n has a binary exponent |
| 345 | // between expMin and expMax. |
| 346 | approxExp10 := ((expMin+expMax)/2 - f.exp) * 28 / 93 // log(10)/log(2) is close to 93/28. |
| 347 | i := (approxExp10 - firstPowerOfTen) / stepPowerOfTen |
| 348 | Loop: |
| 349 | for { |
| 350 | exp := f.exp + powersOfTen[i].exp + 64 |
| 351 | switch { |
| 352 | case exp < expMin: |
| 353 | i++ |
| 354 | case exp > expMax: |
| 355 | i-- |
| 356 | default: |
| 357 | break Loop |
| 358 | } |
| 359 | } |
| 360 | // Apply the desired decimal shift on f. It will have exponent |
| 361 | // in the desired range. This is multiplication by 10^-exp10. |
| 362 | f.Multiply(powersOfTen[i]) |
| 363 | |
| 364 | return -(firstPowerOfTen + i*stepPowerOfTen), i |
| 365 | } |
| 366 | |
| 367 | // frexp10Many applies a common shift by a power of ten to a, b, c. |
| 368 | func frexp10Many(a, b, c *extFloat) (exp10 int) { |
no test coverage detected