blob: 6a55fe55f92dac29a832c956a7b70dfc57bf5214 [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
19// print-mpb-powers-of-10.go prints the
20// wuffs_base__private_implementation__medium_prec_bin__powers_of_10 tables.
21//
22// Usage: go run print-mpb-powers-of-10.go -comments
23
24import (
25 "flag"
26 "fmt"
27 "math/big"
28 "os"
29)
30
31var (
32 comments = flag.Bool("comments", false, "whether to print comments")
33)
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
45 const bigCount = 1 + ((+340 - -348) / 8)
46 fmt.Printf("static const uint32_t "+
47 "wuffs_base__private_implementation__big_powers_of_10[%d] = {\n", 3*bigCount)
48 for e := -348; e <= +340; e += 8 {
49 if err := do(e); err != nil {
50 return err
51 }
52 }
53 fmt.Printf("};\n\n")
54
55 fmt.Printf("static const uint32_t " +
56 "wuffs_base__private_implementation__small_powers_of_10[24] = {\n")
57 for e := 0; e <= 7; e += 1 {
58 if err := do(e); err != nil {
59 return err
60 }
61 }
62 fmt.Printf("};\n")
63
64 return nil
65}
66
67var (
68 one = big.NewInt(1)
69 ten = big.NewInt(10)
70 two64 = big.NewInt(0).Lsh(one, 64)
71)
72
73// N is large enough so that (1<<N) is bigger than 1e348.
74const N = 2048
75
76func do(e int) error {
77 z := big.NewInt(0).Lsh(one, N)
78 if e >= 0 {
79 exp := big.NewInt(0).Exp(ten, big.NewInt(int64(+e)), nil)
80 z.Mul(z, exp)
81 } else {
82 exp := big.NewInt(0).Exp(ten, big.NewInt(int64(-e)), nil)
83 z.Div(z, exp)
84 }
85
86 roundUp := false
87 n := int32(-N)
88 for z.Cmp(two64) >= 0 {
89 roundUp = z.Bit(0) > 0
90 z.Rsh(z, 1)
91 n++
92 }
93 if roundUp {
94 z.Add(z, one)
95 }
96 hex := fmt.Sprintf("%X", z)
97 if len(hex) != 16 {
98 return fmt.Errorf("invalid hexadecimal representation %q", hex)
99 }
100
101 fmt.Printf(" 0x%s, 0x%s, 0x%08X,", hex[8:], hex[:8], uint32(n))
102 if *comments {
103 fmt.Printf(" // 1e%-04d ≈ (0x%s ", e, hex)
104 if n >= 0 {
105 fmt.Printf("<< %4d)", +n)
106 } else {
107 fmt.Printf(">> %4d)", -n)
108 }
109 }
110
111 fmt.Println()
112 return nil
113}