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 uhi := hi.Uint64()
59 ulo := lo.Uint64()
60 if !r.IsInt() {
61 ulo++
62 if ulo == 0 {
63 uhi++
64 }
65 }
66 if ulo != 0 {
67 uhi++
68 ulo = -ulo
69 }
70 fmt.Fprintf(&out, "\t{%#016x, %#016x}, // 1e%d * 2**%d\n", uhi, ulo, e, be)
71 }
72 fmt.Fprintf(&out, "}\n")
73
74 src, err := format.Source(out.Bytes())
75 if err != nil {
76 log.Fatal(err)
77 }
78
79 if err := os.WriteFile("pow10tab.go", src, 0666); err != nil {
80 log.Fatal(err)
81 }
82 }
83
84 var top = `// Copyright 2025 The Go Authors. All rights reserved.
85 // Use of this source code is governed by a BSD-style
86 // license that can be found in the LICENSE file.
87
88 // Code generated by: go run pow10gen.go. DO NOT EDIT.
89 //
90 //go:generate go run pow10gen.go
91
92 package strconv
93
94 const (
95 pow10Min = %d
96 pow10Max = %d
97 )
98
99
100 // pow10Tab holds 128-bit mantissas of powers of 10.
101 // The values are scaled so the high bit is always set.
102 var pow10Tab = [...]pmHiLo{
103 `
104
View as plain text