Source file
src/strconv/pow10gen.go
1
2
3
4
5
6
7 package main
8
9 import (
10 "bytes"
11 "fmt"
12 "go/format"
13 "log"
14 "math/big"
15 "os"
16 )
17
18 const (
19 minExp = -348
20 maxExp = 347
21 )
22
23 func main() {
24 log.SetPrefix("pow10gen: ")
25 log.SetFlags(0)
26
27 var (
28 one = big.NewInt(1)
29 ten = big.NewInt(10)
30
31 b1p64 = new(big.Int).Lsh(one, 64)
32 b1p128 = new(big.Int).Lsh(one, 128)
33
34 r2 = big.NewRat(2, 1)
35 r1p128 = new(big.Rat).SetInt(b1p128)
36 )
37
38 var out bytes.Buffer
39 fmt.Fprintf(&out, top, minExp, maxExp)
40 for e := int64(minExp); e <= maxExp; e++ {
41 var r *big.Rat
42 if e >= 0 {
43 r = new(big.Rat).SetInt(new(big.Int).Exp(ten, big.NewInt(e), nil))
44 } else {
45 r = new(big.Rat).SetFrac(one, new(big.Int).Exp(ten, big.NewInt(-e), nil))
46 }
47 be := 0
48 for r.Cmp(r1p128) < 0 {
49 r.Mul(r, r2)
50 be++
51 }
52 for r.Cmp(r1p128) >= 0 {
53 r.Quo(r, r2)
54 be--
55 }
56 d := new(big.Int).Div(r.Num(), r.Denom())
57 hi, lo := new(big.Int).DivMod(d, b1p64, new(big.Int))
58 fmt.Fprintf(&out, "\t{%#016x, %#016x}, // 1e%d * 2**%d\n", hi.Uint64(), lo.Uint64(), e, be)
59 }
60 fmt.Fprintf(&out, "}\n")
61
62 src, err := format.Source(out.Bytes())
63 if err != nil {
64 log.Fatal(err)
65 }
66
67 if err := os.WriteFile("pow10tab.go", src, 0666); err != nil {
68 log.Fatal(err)
69 }
70 }
71
72 var top = `// Copyright 2025 The Go Authors. All rights reserved.
73 // Use of this source code is governed by a BSD-style
74 // license that can be found in the LICENSE file.
75
76 // Code generated by: go run pow10gen.go. DO NOT EDIT.
77 //
78 //go:generate go run pow10gen.go
79
80 package strconv
81
82 const (
83 pow10Min = %d
84 pow10Max = %d
85 )
86
87
88 // pow10Tab holds 128-bit mantissas of powers of 10.
89 // The values are scaled so the high bit is always set; there is no "implicit leading 1 bit".
90 var pow10Tab = [...]uint128{
91 `
92
View as plain text