// Copyright 2025 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build ignore package main import ( "bytes" "fmt" "go/format" "log" "math/big" "os" ) const ( minExp = -348 maxExp = 347 ) func main() { log.SetPrefix("pow10gen: ") log.SetFlags(0) var ( one = big.NewInt(1) ten = big.NewInt(10) b1p64 = new(big.Int).Lsh(one, 64) b1p128 = new(big.Int).Lsh(one, 128) r2 = big.NewRat(2, 1) r1p128 = new(big.Rat).SetInt(b1p128) ) var out bytes.Buffer fmt.Fprintf(&out, top, minExp, maxExp) for e := int64(minExp); e <= maxExp; e++ { var r *big.Rat if e >= 0 { r = new(big.Rat).SetInt(new(big.Int).Exp(ten, big.NewInt(e), nil)) } else { r = new(big.Rat).SetFrac(one, new(big.Int).Exp(ten, big.NewInt(-e), nil)) } be := 0 for r.Cmp(r1p128) < 0 { r.Mul(r, r2) be++ } for r.Cmp(r1p128) >= 0 { r.Quo(r, r2) be-- } d := new(big.Int).Div(r.Num(), r.Denom()) hi, lo := new(big.Int).DivMod(d, b1p64, new(big.Int)) fmt.Fprintf(&out, "\t{%#016x, %#016x}, // 1e%d * 2**%d\n", hi.Uint64(), lo.Uint64(), e, be) } fmt.Fprintf(&out, "}\n") src, err := format.Source(out.Bytes()) if err != nil { log.Fatal(err) } if err := os.WriteFile("pow10tab.go", src, 0666); err != nil { log.Fatal(err) } } var top = `// Copyright 2025 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Code generated by: go run pow10gen.go. DO NOT EDIT. // //go:generate go run pow10gen.go package strconv const ( pow10Min = %d pow10Max = %d ) // pow10Tab holds 128-bit mantissas of powers of 10. // The values are scaled so the high bit is always set; there is no "implicit leading 1 bit". var pow10Tab = [...]uint128{ `