diff options
Diffstat (limited to 'src/utils/SkFloatToDecimal.cpp')
-rw-r--r-- | src/utils/SkFloatToDecimal.cpp | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/utils/SkFloatToDecimal.cpp b/src/utils/SkFloatToDecimal.cpp index 273175a897..f2a155398b 100644 --- a/src/utils/SkFloatToDecimal.cpp +++ b/src/utils/SkFloatToDecimal.cpp @@ -13,6 +13,22 @@ #include "SkTypes.h" +// returns `value * pow(base, e)`, assuming `e` is positive. +static double pow_by_squaring(double value, double base, int e) { + // https://en.wikipedia.org/wiki/Exponentiation_by_squaring + SkASSERT(e > 0); + while (true) { + if (e & 1) { + value *= base; + } + e >>= 1; + if (0 == e) { + return value; + } + base *= base; + } +} + // Return pow(10.0, e), optimized for common cases. static double pow10(int e) { switch (e) { @@ -34,14 +50,10 @@ static double pow10(int e) { case 15: return 1e+15; default: if (e > 15) { - double value = 1e+15; - while (e-- > 15) { value *= 10.0; } - return value; + return pow_by_squaring(1e+15, 10.0, e - 15); } else { SkASSERT(e < 0); - double value = 1.0; - while (e++ < 0) { value /= 10.0; } - return value; + return pow_by_squaring(1.0, 0.1, -e); } } } |