blob: 2d428fe088e3c13205b74d8ced32fc9d77a5b268 [file] [log] [blame]
// 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{
`