blob: 7147bce6c6b22098f3ecaab493eac5b22c0683ca [file] [log] [blame]
Nigel Taod587c9e2020-03-29 22:10:49 +11001// Copyright 2020 The Wuffs Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// +build ignore
16
17package main
18
Nigel Tao53da68f2020-07-05 13:52:06 +100019// print-mpb-powers-of-10.go prints the medium-precision (64 bit mantissa)
20// binary (base 2) wuffs_base__private_implementation__powers_of_10 tables.
Nigel Taod587c9e2020-03-29 22:10:49 +110021//
Nigel Tao53da68f2020-07-05 13:52:06 +100022// Usage: go run print-mpb-powers-of-10.go -detail
Nigel Taod587c9e2020-03-29 22:10:49 +110023
24import (
25 "flag"
26 "fmt"
27 "math/big"
28 "os"
29)
30
31var (
Nigel Tao53da68f2020-07-05 13:52:06 +100032 detail = flag.Bool("detail", false, "whether to print detailed comments")
Nigel Taod587c9e2020-03-29 22:10:49 +110033)
34
35func main() {
36 if err := main1(); err != nil {
37 os.Stderr.WriteString(err.Error() + "\n")
38 os.Exit(1)
39 }
40}
41
42func main1() error {
43 flag.Parse()
44
Nigel Tao53da68f2020-07-05 13:52:06 +100045 const count = 1 + ((+310 - -326) / 1)
Nigel Taod587c9e2020-03-29 22:10:49 +110046 fmt.Printf("static const uint32_t "+
Nigel Tao53da68f2020-07-05 13:52:06 +100047 "wuffs_base__private_implementation__powers_of_10[%d] = {\n", 3*count)
48 for e := -326; e <= +310; e++ {
Nigel Taod587c9e2020-03-29 22:10:49 +110049 if err := do(e); err != nil {
50 return err
51 }
52 }
53 fmt.Printf("};\n\n")
54
Nigel Taod587c9e2020-03-29 22:10:49 +110055 return nil
56}
57
58var (
59 one = big.NewInt(1)
60 ten = big.NewInt(10)
61 two64 = big.NewInt(0).Lsh(one, 64)
62)
63
Nigel Tao53da68f2020-07-05 13:52:06 +100064// N is large enough so that (1<<N) is bigger than 1e310.
Nigel Taod587c9e2020-03-29 22:10:49 +110065const N = 2048
66
67func do(e int) error {
68 z := big.NewInt(0).Lsh(one, N)
69 if e >= 0 {
70 exp := big.NewInt(0).Exp(ten, big.NewInt(int64(+e)), nil)
71 z.Mul(z, exp)
72 } else {
73 exp := big.NewInt(0).Exp(ten, big.NewInt(int64(-e)), nil)
74 z.Div(z, exp)
75 }
76
77 roundUp := false
78 n := int32(-N)
79 for z.Cmp(two64) >= 0 {
80 roundUp = z.Bit(0) > 0
81 z.Rsh(z, 1)
82 n++
83 }
84 if roundUp {
85 z.Add(z, one)
86 }
87 hex := fmt.Sprintf("%X", z)
88 if len(hex) != 16 {
89 return fmt.Errorf("invalid hexadecimal representation %q", hex)
90 }
91
Nigel Tao53da68f2020-07-05 13:52:06 +100092 fmt.Printf(" 0x%s, 0x%s, 0x%08X, // 1e%-04d",
93 hex[8:], hex[:8], uint32(n), e)
94 if *detail {
95 fmt.Printf("≈ (0x%s ", e, hex)
Nigel Taod587c9e2020-03-29 22:10:49 +110096 if n >= 0 {
97 fmt.Printf("<< %4d)", +n)
98 } else {
99 fmt.Printf(">> %4d)", -n)
100 }
101 }
102
103 fmt.Println()
104 return nil
105}