Source file src/strconv/math.go
1 // Copyright 2025 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package strconv 6 7 import "math/bits" 8 9 // A uint128 is a 128-bit uint. 10 // The fields are exported to make them visible to package strconv_test. 11 type uint128 struct { 12 Hi uint64 13 Lo uint64 14 } 15 16 // umul128 returns the 128-bit product x*y. 17 func umul128(x, y uint64) uint128 { 18 hi, lo := bits.Mul64(x, y) 19 return uint128{hi, lo} 20 } 21 22 // umul192 returns the 192-bit product x*y in three uint64s. 23 func umul192(x uint64, y uint128) (hi, mid, lo uint64) { 24 mid1, lo := bits.Mul64(x, y.Lo) 25 hi, mid2 := bits.Mul64(x, y.Hi) 26 mid, carry := bits.Add64(mid1, mid2, 0) 27 return hi + carry, mid, lo 28 } 29 30 // pow10 returns the 128-bit mantissa and binary exponent of 10**e 31 // If e is out of range, pow10 returns ok=false. 32 func pow10(e int) (mant uint128, exp int, ok bool) { 33 if e < pow10Min || e > pow10Max { 34 return 35 } 36 return pow10Tab[e-pow10Min], mulLog2_10(e), true 37 } 38 39 // mulLog10_2 returns math.Floor(x * log(2)/log(10)) for an integer x in 40 // the range -1600 <= x && x <= +1600. 41 // 42 // The range restriction lets us work in faster integer arithmetic instead of 43 // slower floating point arithmetic. Correctness is verified by unit tests. 44 func mulLog10_2(x int) int { 45 // log(2)/log(10) ≈ 0.30102999566 ≈ 78913 / 2^18 46 return (x * 78913) >> 18 47 } 48 49 // mulLog2_10 returns math.Floor(x * log(10)/log(2)) for an integer x in 50 // the range -500 <= x && x <= +500. 51 // 52 // The range restriction lets us work in faster integer arithmetic instead of 53 // slower floating point arithmetic. Correctness is verified by unit tests. 54 func mulLog2_10(x int) int { 55 // log(10)/log(2) ≈ 3.32192809489 ≈ 108853 / 2^15 56 return (x * 108853) >> 15 57 } 58