gofront 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/package.json +5 -4
- package/src/backend/js/expressions.js +849 -371
- package/src/backend/js/index.js +241 -147
- package/src/backend/js/natives.js +383 -0
- package/src/backend/js/runtime.js +512 -2547
- package/src/backend/js/statements.js +506 -103
- package/src/backend/js/stdlib/index.js +45 -93
- package/src/backend/js/templ.js +32 -45
- package/src/backend/js/type-info.js +177 -13
- package/src/backend/shared/fixed-float.js +20 -0
- package/src/backend/shared/fmt-types.js +63 -171
- package/src/backend/shared/host-unicode.js +36 -0
- package/src/backend/wasm/boundary.js +490 -965
- package/src/backend/wasm/emit-builtins.js +643 -256
- package/src/backend/wasm/emit-exprs.js +124 -57
- package/src/backend/wasm/emit-maps.js +17 -367
- package/src/backend/wasm/emit-stmts.js +325 -75
- package/src/backend/wasm/emit.js +104 -13
- package/src/backend/wasm/globals.js +47 -8
- package/src/backend/wasm/glue.js +2 -4
- package/src/backend/wasm/index.js +36 -530
- package/src/backend/wasm/method-expr.js +12 -1
- package/src/backend/wasm/module-emitter.js +92 -717
- package/src/backend/wasm/monomorph.js +103 -6
- package/src/backend/wasm/natives.js +596 -0
- package/src/backend/wasm/prescan.js +5 -153
- package/src/backend/wasm/prune-funcs.js +89 -0
- package/src/backend/wasm/stdlib/index.js +2 -32
- package/src/backend/wasm/types.js +68 -20
- package/src/backend/wasm/variadic.js +3 -3
- package/src/cli/cli-core.js +5 -1
- package/src/cli/test-runner.js +115 -342
- package/src/compiler.js +108 -130
- package/src/lexer/lexer.js +105 -11
- package/src/lexer/templ-lexer.js +61 -18
- package/src/lexer/tokens.js +1 -0
- package/src/link/stdlib.js +354 -132
- package/src/link/type-names.js +148 -0
- package/src/link/wasm.js +30 -6
- package/src/lower/bounds.js +153 -0
- package/src/lower/captures.js +92 -33
- package/src/lower/embedding.js +32 -3
- package/src/lower/errors-as.js +196 -0
- package/src/lower/fmt-formatters.js +905 -0
- package/src/lower/functions.js +2 -0
- package/src/lower/gen-types.js +274 -0
- package/src/lower/index.js +7 -1
- package/src/lower/json-codecs.js +228 -247
- package/src/lower/ownership.js +25 -7
- package/src/lower/reachability.js +69 -51
- package/src/lower/walk.js +12 -0
- package/src/parser/declarations.js +28 -5
- package/src/parser/expressions.js +86 -16
- package/src/parser/statements.js +1 -0
- package/src/parser/templ.js +44 -5
- package/src/parser/types.js +1 -0
- package/src/resolver.js +1 -2
- package/src/typechecker/assignability.js +124 -11
- package/src/typechecker/const-fold.js +70 -27
- package/src/typechecker/constants.js +32 -6
- package/src/typechecker/expressions.js +326 -98
- package/src/typechecker/index.js +208 -33
- package/src/typechecker/init-order.js +136 -40
- package/src/typechecker/operand-text.js +40 -0
- package/src/typechecker/resolve.js +192 -36
- package/src/typechecker/statements.js +122 -11
- package/src/typechecker/stdlib/excluded.js +9 -5
- package/src/typechecker/stdlib/index.js +25 -9
- package/src/typechecker/termination.js +10 -1
- package/src/typechecker/types.js +203 -573
- package/stdlib/bytes/buffer.go +479 -0
- package/stdlib/bytes/bytes.go +1010 -0
- package/stdlib/bytes/reader.go +161 -0
- package/stdlib/context/context.go +115 -0
- package/stdlib/crypto/rand/rand.go +34 -0
- package/stdlib/crypto/sha256/sha256.go +249 -0
- package/stdlib/encoding/base64/base64.go +331 -0
- package/stdlib/encoding/binary/binary.go +332 -0
- package/stdlib/encoding/hex/hex.go +140 -0
- package/stdlib/encoding/json/json.go +62 -0
- package/stdlib/errors/errors.go +174 -0
- package/stdlib/fmt/errors.go +110 -0
- package/stdlib/fmt/format.go +732 -0
- package/stdlib/fmt/print.go +1232 -0
- package/stdlib/gom/gom.go +293 -0
- package/stdlib/html/html.go +251 -0
- package/stdlib/internal/fmtrt/fmtrt.go +163 -0
- package/stdlib/internal/jsonrt/dec.go +171 -38
- package/stdlib/internal/jsonrt/enc.go +186 -36
- package/stdlib/internal/jsonrt/scanner.go +17 -8
- package/stdlib/io/io.go +157 -1
- package/stdlib/maps/maps.go +131 -0
- package/stdlib/math/bits/bits.go +507 -0
- package/stdlib/math/extra.go +16 -14
- package/stdlib/math/math.go +439 -0
- package/stdlib/math/rand/rand.go +297 -0
- package/stdlib/os/os.go +93 -0
- package/stdlib/path/filepath/filepath.go +47 -0
- package/stdlib/path/path.go +394 -0
- package/stdlib/regexp/regexp.go +231 -0
- package/stdlib/slices/slices.go +526 -0
- package/stdlib/slices/sort.go +209 -0
- package/stdlib/slices/zsort_cmp.go +480 -0
- package/stdlib/slices/zsort_ordered.go +482 -0
- package/stdlib/sort/sort.go +391 -452
- package/stdlib/sort/zsort_func.go +480 -0
- package/stdlib/sort/zsort_iface.go +480 -0
- package/stdlib/strconv/float.go +1699 -0
- package/stdlib/strconv/isprint.go +752 -0
- package/stdlib/strconv/quote.go +235 -50
- package/stdlib/strconv/strconv.go +616 -0
- package/stdlib/strings/builder.go +95 -0
- package/stdlib/strings/reader.go +163 -0
- package/stdlib/strings/replacer.go +102 -0
- package/stdlib/strings/strings.go +807 -0
- package/stdlib/sync/sync.go +268 -0
- package/stdlib/testing/async_js.go +61 -0
- package/stdlib/testing/benchmark.go +297 -0
- package/stdlib/testing/testing.go +523 -0
- package/stdlib/time/duration.go +233 -0
- package/stdlib/time/format.go +745 -0
- package/stdlib/time/parse.go +790 -0
- package/stdlib/time/sleep_js.go +63 -0
- package/stdlib/time/time.go +834 -0
- package/stdlib/unicode/unicode.go +141 -3
- package/stdlib/unicode/utf8/utf8.go +464 -0
- package/src/backend/js/fmt-runtime.js +0 -573
- package/src/backend/js/stdlib/base64.js +0 -12
- package/src/backend/js/stdlib/binary.js +0 -102
- package/src/backend/js/stdlib/bits.js +0 -119
- package/src/backend/js/stdlib/builder.js +0 -98
- package/src/backend/js/stdlib/bytes.js +0 -368
- package/src/backend/js/stdlib/errors.js +0 -45
- package/src/backend/js/stdlib/fmt.js +0 -517
- package/src/backend/js/stdlib/gom.js +0 -155
- package/src/backend/js/stdlib/hex.js +0 -17
- package/src/backend/js/stdlib/html.js +0 -20
- package/src/backend/js/stdlib/io.js +0 -137
- package/src/backend/js/stdlib/json.js +0 -1167
- package/src/backend/js/stdlib/maps.js +0 -37
- package/src/backend/js/stdlib/math.js +0 -85
- package/src/backend/js/stdlib/os.js +0 -13
- package/src/backend/js/stdlib/path.js +0 -48
- package/src/backend/js/stdlib/rand.js +0 -32
- package/src/backend/js/stdlib/regexp.js +0 -54
- package/src/backend/js/stdlib/sha256.js +0 -12
- package/src/backend/js/stdlib/shared.js +0 -17
- package/src/backend/js/stdlib/simd.js +0 -34
- package/src/backend/js/stdlib/slices.js +0 -107
- package/src/backend/js/stdlib/sort.js +0 -30
- package/src/backend/js/stdlib/strconv.js +0 -79
- package/src/backend/js/stdlib/strings.js +0 -301
- package/src/backend/js/stdlib/sync.js +0 -13
- package/src/backend/js/stdlib/testing.js +0 -41
- package/src/backend/js/stdlib/time.js +0 -152
- package/src/backend/js/stdlib/unicode.js +0 -25
- package/src/backend/js/stdlib/utf8.js +0 -26
- package/src/backend/wasm/stdlib/bytes.js +0 -6716
- package/src/backend/wasm/stdlib/core.js +0 -10278
- package/src/backend/wasm/stdlib/io.js +0 -3578
- package/src/backend/wasm/stdlib/packages.js +0 -2402
- package/src/backend/wasm/stdlib/pure.js +0 -720
- package/src/backend/wasm/stdlib/time.js +0 -2229
- package/src/typechecker/stdlib/core.js +0 -1079
- package/src/typechecker/stdlib/extended.js +0 -1210
- package/stdlib/bytes/iter.go +0 -192
- package/stdlib/bytes/search.go +0 -240
- package/stdlib/bytes/split.go +0 -218
- package/stdlib/errors/overlay.go +0 -12
- package/stdlib/maps/iter.go +0 -65
- package/stdlib/slices/extra.go +0 -73
- package/stdlib/slices/iter.go +0 -113
- package/stdlib/strings/extra.go +0 -35
- package/stdlib/strings/iter.go +0 -122
- package/stdlib/sync/extra.go +0 -105
- package/stdlib/unicode/utf8/bytes.go +0 -239
|
@@ -0,0 +1,1699 @@
|
|
|
1
|
+
//go:build gofront
|
|
2
|
+
|
|
3
|
+
//gofront:target both
|
|
4
|
+
|
|
5
|
+
package strconv
|
|
6
|
+
|
|
7
|
+
import "math"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
type decimal struct {
|
|
11
|
+
d [800]byte // digits, big-endian representation
|
|
12
|
+
nd int // number of digits used
|
|
13
|
+
dp int // decimal point
|
|
14
|
+
neg bool // negative flag
|
|
15
|
+
trunc bool // discarded nonzero digits beyond d[:nd]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
func (a *decimal) String() string {
|
|
19
|
+
n := 10 + a.nd
|
|
20
|
+
if a.dp > 0 {
|
|
21
|
+
n += a.dp
|
|
22
|
+
}
|
|
23
|
+
if a.dp < 0 {
|
|
24
|
+
n += -a.dp
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
buf := make([]byte, n)
|
|
28
|
+
w := 0
|
|
29
|
+
switch {
|
|
30
|
+
case a.nd == 0:
|
|
31
|
+
return "0"
|
|
32
|
+
|
|
33
|
+
case a.dp <= 0:
|
|
34
|
+
// zeros fill space between decimal point and digits
|
|
35
|
+
buf[w] = '0'
|
|
36
|
+
w++
|
|
37
|
+
buf[w] = '.'
|
|
38
|
+
w++
|
|
39
|
+
w += digitZero(buf[w : w+-a.dp])
|
|
40
|
+
w += copy(buf[w:], a.d[0:a.nd])
|
|
41
|
+
|
|
42
|
+
case a.dp < a.nd:
|
|
43
|
+
// decimal point in middle of digits
|
|
44
|
+
w += copy(buf[w:], a.d[0:a.dp])
|
|
45
|
+
buf[w] = '.'
|
|
46
|
+
w++
|
|
47
|
+
w += copy(buf[w:], a.d[a.dp:a.nd])
|
|
48
|
+
|
|
49
|
+
default:
|
|
50
|
+
// zeros fill space between digits and decimal point
|
|
51
|
+
w += copy(buf[w:], a.d[0:a.nd])
|
|
52
|
+
w += digitZero(buf[w : w+a.dp-a.nd])
|
|
53
|
+
}
|
|
54
|
+
return string(buf[0:w])
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
func digitZero(dst []byte) int {
|
|
58
|
+
for i := range dst {
|
|
59
|
+
dst[i] = '0'
|
|
60
|
+
}
|
|
61
|
+
return len(dst)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// trim trailing zeros from number.
|
|
65
|
+
// (They are meaningless; the decimal point is tracked
|
|
66
|
+
// independent of the number of digits.)
|
|
67
|
+
func trim(a *decimal) {
|
|
68
|
+
for a.nd > 0 && a.d[a.nd-1] == '0' {
|
|
69
|
+
a.nd--
|
|
70
|
+
}
|
|
71
|
+
if a.nd == 0 {
|
|
72
|
+
a.dp = 0
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Assign v to a.
|
|
77
|
+
func (a *decimal) Assign(v uint64) {
|
|
78
|
+
var buf [24]byte
|
|
79
|
+
|
|
80
|
+
// Write reversed decimal in buf.
|
|
81
|
+
n := 0
|
|
82
|
+
for v > 0 {
|
|
83
|
+
v1 := v / 10
|
|
84
|
+
v -= 10 * v1
|
|
85
|
+
buf[n] = byte(v + '0')
|
|
86
|
+
n++
|
|
87
|
+
v = v1
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Reverse again to produce forward decimal in a.d.
|
|
91
|
+
a.nd = 0
|
|
92
|
+
for n--; n >= 0; n-- {
|
|
93
|
+
a.d[a.nd] = buf[n]
|
|
94
|
+
a.nd++
|
|
95
|
+
}
|
|
96
|
+
a.dp = a.nd
|
|
97
|
+
trim(a)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Maximum shift that we can do in one pass without overflow.
|
|
101
|
+
// A uint has 32 or 64 bits, and we have to be able to accommodate 9<<k.
|
|
102
|
+
const uintSize = 64
|
|
103
|
+
const maxShift = uintSize - 4
|
|
104
|
+
|
|
105
|
+
// Binary shift right (/ 2) by k bits. k <= maxShift to avoid overflow.
|
|
106
|
+
func rightShift(a *decimal, k uint) {
|
|
107
|
+
r := 0 // read pointer
|
|
108
|
+
w := 0 // write pointer
|
|
109
|
+
|
|
110
|
+
// Pick up enough leading digits to cover first shift.
|
|
111
|
+
var n uint64
|
|
112
|
+
for ; n>>k == 0; r++ {
|
|
113
|
+
if r >= a.nd {
|
|
114
|
+
if n == 0 {
|
|
115
|
+
// a == 0; shouldn't get here, but handle anyway.
|
|
116
|
+
a.nd = 0
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
for n>>k == 0 {
|
|
120
|
+
n = n * 10
|
|
121
|
+
r++
|
|
122
|
+
}
|
|
123
|
+
break
|
|
124
|
+
}
|
|
125
|
+
c := uint64(a.d[r])
|
|
126
|
+
n = n*10 + c - '0'
|
|
127
|
+
}
|
|
128
|
+
a.dp -= r - 1
|
|
129
|
+
|
|
130
|
+
mask := uint64(1)<<k - 1
|
|
131
|
+
|
|
132
|
+
// Pick up a digit, put down a digit.
|
|
133
|
+
for ; r < a.nd; r++ {
|
|
134
|
+
c := uint64(a.d[r])
|
|
135
|
+
dig := n >> k
|
|
136
|
+
n &= mask
|
|
137
|
+
a.d[w] = byte(dig + '0')
|
|
138
|
+
w++
|
|
139
|
+
n = n*10 + c - '0'
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Put down extra digits.
|
|
143
|
+
for n > 0 {
|
|
144
|
+
dig := n >> k
|
|
145
|
+
n &= mask
|
|
146
|
+
if w < len(a.d) {
|
|
147
|
+
a.d[w] = byte(dig + '0')
|
|
148
|
+
w++
|
|
149
|
+
} else if dig > 0 {
|
|
150
|
+
a.trunc = true
|
|
151
|
+
}
|
|
152
|
+
n = n * 10
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
a.nd = w
|
|
156
|
+
trim(a)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Cheat sheet for left shift: table indexed by shift count giving
|
|
160
|
+
// number of new digits that will be introduced by that shift.
|
|
161
|
+
//
|
|
162
|
+
// For example, leftcheats[4] = {2, "625"}. That means that
|
|
163
|
+
// if we are shifting by 4 (multiplying by 16), it will add 2 digits
|
|
164
|
+
// when the string prefix is "625" through "999", and one fewer digit
|
|
165
|
+
// if the string prefix is "000" through "624".
|
|
166
|
+
//
|
|
167
|
+
// Credit for this trick goes to Ken.
|
|
168
|
+
|
|
169
|
+
type leftCheat struct {
|
|
170
|
+
delta int // number of new digits
|
|
171
|
+
cutoff string // minus one digit if original < a.
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
var leftcheats = []leftCheat{
|
|
175
|
+
// Leading digits of 1/2^i = 5^i.
|
|
176
|
+
// 5^23 is not an exact 64-bit floating point number,
|
|
177
|
+
// so have to use bc for the math.
|
|
178
|
+
// Go up to 60 to be large enough for 32bit and 64bit platforms.
|
|
179
|
+
/*
|
|
180
|
+
seq 60 | sed 's/^/5^/' | bc |
|
|
181
|
+
awk 'BEGIN{ print "\t{ 0, \"\" }," }
|
|
182
|
+
{
|
|
183
|
+
log2 = log(2)/log(10)
|
|
184
|
+
printf("\t{ %d, \"%s\" },\t// * %d\n",
|
|
185
|
+
int(log2*NR+1), $0, 2**NR)
|
|
186
|
+
}'
|
|
187
|
+
*/
|
|
188
|
+
{0, ""},
|
|
189
|
+
{1, "5"}, // * 2
|
|
190
|
+
{1, "25"}, // * 4
|
|
191
|
+
{1, "125"}, // * 8
|
|
192
|
+
{2, "625"}, // * 16
|
|
193
|
+
{2, "3125"}, // * 32
|
|
194
|
+
{2, "15625"}, // * 64
|
|
195
|
+
{3, "78125"}, // * 128
|
|
196
|
+
{3, "390625"}, // * 256
|
|
197
|
+
{3, "1953125"}, // * 512
|
|
198
|
+
{4, "9765625"}, // * 1024
|
|
199
|
+
{4, "48828125"}, // * 2048
|
|
200
|
+
{4, "244140625"}, // * 4096
|
|
201
|
+
{4, "1220703125"}, // * 8192
|
|
202
|
+
{5, "6103515625"}, // * 16384
|
|
203
|
+
{5, "30517578125"}, // * 32768
|
|
204
|
+
{5, "152587890625"}, // * 65536
|
|
205
|
+
{6, "762939453125"}, // * 131072
|
|
206
|
+
{6, "3814697265625"}, // * 262144
|
|
207
|
+
{6, "19073486328125"}, // * 524288
|
|
208
|
+
{7, "95367431640625"}, // * 1048576
|
|
209
|
+
{7, "476837158203125"}, // * 2097152
|
|
210
|
+
{7, "2384185791015625"}, // * 4194304
|
|
211
|
+
{7, "11920928955078125"}, // * 8388608
|
|
212
|
+
{8, "59604644775390625"}, // * 16777216
|
|
213
|
+
{8, "298023223876953125"}, // * 33554432
|
|
214
|
+
{8, "1490116119384765625"}, // * 67108864
|
|
215
|
+
{9, "7450580596923828125"}, // * 134217728
|
|
216
|
+
{9, "37252902984619140625"}, // * 268435456
|
|
217
|
+
{9, "186264514923095703125"}, // * 536870912
|
|
218
|
+
{10, "931322574615478515625"}, // * 1073741824
|
|
219
|
+
{10, "4656612873077392578125"}, // * 2147483648
|
|
220
|
+
{10, "23283064365386962890625"}, // * 4294967296
|
|
221
|
+
{10, "116415321826934814453125"}, // * 8589934592
|
|
222
|
+
{11, "582076609134674072265625"}, // * 17179869184
|
|
223
|
+
{11, "2910383045673370361328125"}, // * 34359738368
|
|
224
|
+
{11, "14551915228366851806640625"}, // * 68719476736
|
|
225
|
+
{12, "72759576141834259033203125"}, // * 137438953472
|
|
226
|
+
{12, "363797880709171295166015625"}, // * 274877906944
|
|
227
|
+
{12, "1818989403545856475830078125"}, // * 549755813888
|
|
228
|
+
{13, "9094947017729282379150390625"}, // * 1099511627776
|
|
229
|
+
{13, "45474735088646411895751953125"}, // * 2199023255552
|
|
230
|
+
{13, "227373675443232059478759765625"}, // * 4398046511104
|
|
231
|
+
{13, "1136868377216160297393798828125"}, // * 8796093022208
|
|
232
|
+
{14, "5684341886080801486968994140625"}, // * 17592186044416
|
|
233
|
+
{14, "28421709430404007434844970703125"}, // * 35184372088832
|
|
234
|
+
{14, "142108547152020037174224853515625"}, // * 70368744177664
|
|
235
|
+
{15, "710542735760100185871124267578125"}, // * 140737488355328
|
|
236
|
+
{15, "3552713678800500929355621337890625"}, // * 281474976710656
|
|
237
|
+
{15, "17763568394002504646778106689453125"}, // * 562949953421312
|
|
238
|
+
{16, "88817841970012523233890533447265625"}, // * 1125899906842624
|
|
239
|
+
{16, "444089209850062616169452667236328125"}, // * 2251799813685248
|
|
240
|
+
{16, "2220446049250313080847263336181640625"}, // * 4503599627370496
|
|
241
|
+
{16, "11102230246251565404236316680908203125"}, // * 9007199254740992
|
|
242
|
+
{17, "55511151231257827021181583404541015625"}, // * 18014398509481984
|
|
243
|
+
{17, "277555756156289135105907917022705078125"}, // * 36028797018963968
|
|
244
|
+
{17, "1387778780781445675529539585113525390625"}, // * 72057594037927936
|
|
245
|
+
{18, "6938893903907228377647697925567626953125"}, // * 144115188075855872
|
|
246
|
+
{18, "34694469519536141888238489627838134765625"}, // * 288230376151711744
|
|
247
|
+
{18, "173472347597680709441192448139190673828125"}, // * 576460752303423488
|
|
248
|
+
{19, "867361737988403547205962240695953369140625"}, // * 1152921504606846976
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Is the leading prefix of b lexicographically less than s?
|
|
252
|
+
func prefixIsLessThan(b []byte, s string) bool {
|
|
253
|
+
for i := 0; i < len(s); i++ {
|
|
254
|
+
if i >= len(b) {
|
|
255
|
+
return true
|
|
256
|
+
}
|
|
257
|
+
if b[i] != s[i] {
|
|
258
|
+
return b[i] < s[i]
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return false
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Binary shift left (* 2) by k bits. k <= maxShift to avoid overflow.
|
|
265
|
+
func leftShift(a *decimal, k uint) {
|
|
266
|
+
delta := leftcheats[k].delta
|
|
267
|
+
if prefixIsLessThan(a.d[0:a.nd], leftcheats[k].cutoff) {
|
|
268
|
+
delta--
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
r := a.nd // read index
|
|
272
|
+
w := a.nd + delta // write index
|
|
273
|
+
|
|
274
|
+
// Pick up a digit, put down a digit.
|
|
275
|
+
var n uint64
|
|
276
|
+
for r--; r >= 0; r-- {
|
|
277
|
+
n += (uint64(a.d[r]) - '0') << k
|
|
278
|
+
quo := n / 10
|
|
279
|
+
rem := n - 10*quo
|
|
280
|
+
w--
|
|
281
|
+
if w < len(a.d) {
|
|
282
|
+
a.d[w] = byte(rem + '0')
|
|
283
|
+
} else if rem != 0 {
|
|
284
|
+
a.trunc = true
|
|
285
|
+
}
|
|
286
|
+
n = quo
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Put down extra digits.
|
|
290
|
+
for n > 0 {
|
|
291
|
+
quo := n / 10
|
|
292
|
+
rem := n - 10*quo
|
|
293
|
+
w--
|
|
294
|
+
if w < len(a.d) {
|
|
295
|
+
a.d[w] = byte(rem + '0')
|
|
296
|
+
} else if rem != 0 {
|
|
297
|
+
a.trunc = true
|
|
298
|
+
}
|
|
299
|
+
n = quo
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
a.nd += delta
|
|
303
|
+
if a.nd >= len(a.d) {
|
|
304
|
+
a.nd = len(a.d)
|
|
305
|
+
}
|
|
306
|
+
a.dp += delta
|
|
307
|
+
trim(a)
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Binary shift left (k > 0) or right (k < 0).
|
|
311
|
+
func (a *decimal) Shift(k int) {
|
|
312
|
+
switch {
|
|
313
|
+
case a.nd == 0:
|
|
314
|
+
// nothing to do: a == 0
|
|
315
|
+
case k > 0:
|
|
316
|
+
for k > maxShift {
|
|
317
|
+
leftShift(a, maxShift)
|
|
318
|
+
k -= maxShift
|
|
319
|
+
}
|
|
320
|
+
leftShift(a, uint(k))
|
|
321
|
+
case k < 0:
|
|
322
|
+
for k < -maxShift {
|
|
323
|
+
rightShift(a, maxShift)
|
|
324
|
+
k += maxShift
|
|
325
|
+
}
|
|
326
|
+
rightShift(a, uint(-k))
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// If we chop a at nd digits, should we round up?
|
|
331
|
+
func shouldRoundUp(a *decimal, nd int) bool {
|
|
332
|
+
if nd < 0 || nd >= a.nd {
|
|
333
|
+
return false
|
|
334
|
+
}
|
|
335
|
+
if a.d[nd] == '5' && nd+1 == a.nd { // exactly halfway - round to even
|
|
336
|
+
// if we truncated, a little higher than what's recorded - always round up
|
|
337
|
+
if a.trunc {
|
|
338
|
+
return true
|
|
339
|
+
}
|
|
340
|
+
return nd > 0 && (a.d[nd-1]-'0')%2 != 0
|
|
341
|
+
}
|
|
342
|
+
// not halfway - digit tells all
|
|
343
|
+
return a.d[nd] >= '5'
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Round a to nd digits (or fewer).
|
|
347
|
+
// If nd is zero, it means we're rounding
|
|
348
|
+
// just to the left of the digits, as in
|
|
349
|
+
// 0.09 -> 0.1.
|
|
350
|
+
func (a *decimal) Round(nd int) {
|
|
351
|
+
if nd < 0 || nd >= a.nd {
|
|
352
|
+
return
|
|
353
|
+
}
|
|
354
|
+
if shouldRoundUp(a, nd) {
|
|
355
|
+
a.RoundUp(nd)
|
|
356
|
+
} else {
|
|
357
|
+
a.RoundDown(nd)
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Round a down to nd digits (or fewer).
|
|
362
|
+
func (a *decimal) RoundDown(nd int) {
|
|
363
|
+
if nd < 0 || nd >= a.nd {
|
|
364
|
+
return
|
|
365
|
+
}
|
|
366
|
+
a.nd = nd
|
|
367
|
+
trim(a)
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Round a up to nd digits (or fewer).
|
|
371
|
+
func (a *decimal) RoundUp(nd int) {
|
|
372
|
+
if nd < 0 || nd >= a.nd {
|
|
373
|
+
return
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// round up
|
|
377
|
+
for i := nd - 1; i >= 0; i-- {
|
|
378
|
+
c := a.d[i]
|
|
379
|
+
if c < '9' { // can stop after this digit
|
|
380
|
+
a.d[i]++
|
|
381
|
+
a.nd = i + 1
|
|
382
|
+
return
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Number is all 9s.
|
|
387
|
+
// Change to single 1 with adjusted decimal point.
|
|
388
|
+
a.d[0] = '1'
|
|
389
|
+
a.nd = 1
|
|
390
|
+
a.dp++
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Extract integer part, rounded appropriately.
|
|
394
|
+
// No guarantees about overflow.
|
|
395
|
+
func (a *decimal) RoundedInteger() uint64 {
|
|
396
|
+
if a.dp > 20 {
|
|
397
|
+
return 0xFFFFFFFFFFFFFFFF
|
|
398
|
+
}
|
|
399
|
+
var i int
|
|
400
|
+
n := uint64(0)
|
|
401
|
+
for i = 0; i < a.dp && i < a.nd; i++ {
|
|
402
|
+
n = n*10 + uint64(a.d[i]-'0')
|
|
403
|
+
}
|
|
404
|
+
for ; i < a.dp; i++ {
|
|
405
|
+
n *= 10
|
|
406
|
+
}
|
|
407
|
+
if shouldRoundUp(a, a.dp) {
|
|
408
|
+
n++
|
|
409
|
+
}
|
|
410
|
+
return n
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
const (
|
|
415
|
+
upperhex = "0123456789ABCDEF"
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
type floatInfo struct {
|
|
419
|
+
mantbits uint
|
|
420
|
+
expbits uint
|
|
421
|
+
bias int
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const (
|
|
425
|
+
float32MantBits = 23
|
|
426
|
+
float32ExpBits = 8
|
|
427
|
+
float32Bias = -127
|
|
428
|
+
float64MantBits = 52
|
|
429
|
+
float64ExpBits = 11
|
|
430
|
+
float64Bias = -1023
|
|
431
|
+
)
|
|
432
|
+
|
|
433
|
+
func float32info() *floatInfo {
|
|
434
|
+
return &floatInfo{float32MantBits, float32ExpBits, float32Bias}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
func float64info() *floatInfo {
|
|
438
|
+
return &floatInfo{float64MantBits, float64ExpBits, float64Bias}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// FormatFloat converts the floating-point number f to a string,
|
|
442
|
+
// according to the format fmt and precision prec. It rounds the
|
|
443
|
+
// result assuming that the original was obtained from a floating-point
|
|
444
|
+
// value of bitSize bits (32 for float32, 64 for float64).
|
|
445
|
+
//
|
|
446
|
+
// The format fmt is one of
|
|
447
|
+
// - 'b' (-ddddp±ddd, a binary exponent),
|
|
448
|
+
// - 'e' (-d.dddde±dd, a decimal exponent),
|
|
449
|
+
// - 'E' (-d.ddddE±dd, a decimal exponent),
|
|
450
|
+
// - 'f' (-ddd.dddd, no exponent),
|
|
451
|
+
// - 'g' ('e' for large exponents, 'f' otherwise),
|
|
452
|
+
// - 'G' ('E' for large exponents, 'f' otherwise),
|
|
453
|
+
// - 'x' (-0xd.ddddp±ddd, a hexadecimal fraction and binary exponent), or
|
|
454
|
+
// - 'X' (-0Xd.ddddP±ddd, a hexadecimal fraction and binary exponent).
|
|
455
|
+
//
|
|
456
|
+
// The precision prec controls the number of digits (excluding the exponent)
|
|
457
|
+
// printed by the 'e', 'E', 'f', 'g', 'G', 'x', and 'X' formats.
|
|
458
|
+
// For 'e', 'E', 'f', 'x', and 'X', it is the number of digits after the decimal point.
|
|
459
|
+
// For 'g' and 'G' it is the maximum number of significant digits (trailing
|
|
460
|
+
// zeros are removed).
|
|
461
|
+
// The special precision -1 uses the smallest number of digits
|
|
462
|
+
// necessary such that ParseFloat will return f exactly.
|
|
463
|
+
// The exponent is written as a decimal integer;
|
|
464
|
+
// for all formats other than 'b', it will be at least two digits.
|
|
465
|
+
func FormatFloat(f float64, fmt byte, prec, bitSize int) string {
|
|
466
|
+
return string(genericFtoa(make([]byte, 0, max(prec+4, 24)), f, fmt, prec, bitSize))
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// AppendFloat appends the string form of the floating-point number f,
|
|
470
|
+
// as generated by [FormatFloat], to dst and returns the extended buffer.
|
|
471
|
+
func AppendFloat(dst []byte, f float64, fmt byte, prec, bitSize int) []byte {
|
|
472
|
+
return genericFtoa(dst, f, fmt, prec, bitSize)
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
func genericFtoa(dst []byte, val float64, fmt byte, prec, bitSize int) []byte {
|
|
476
|
+
if fmt == 'f' && prec >= 0 && prec <= 60 && bitSize == 64 && val-val == 0 {
|
|
477
|
+
// The host's fixed-point printer, which the Go body declines.
|
|
478
|
+
if s := fixed(math.Abs(val), prec); s != "" {
|
|
479
|
+
if math.Signbit(val) {
|
|
480
|
+
dst = append(dst, '-')
|
|
481
|
+
}
|
|
482
|
+
return append(dst, s...)
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
var bits uint64
|
|
486
|
+
var flt *floatInfo
|
|
487
|
+
switch bitSize {
|
|
488
|
+
case 32:
|
|
489
|
+
bits = uint64(math.Float32bits(float32(val)))
|
|
490
|
+
flt = float32info()
|
|
491
|
+
case 64:
|
|
492
|
+
bits = math.Float64bits(val)
|
|
493
|
+
flt = float64info()
|
|
494
|
+
default:
|
|
495
|
+
panic("strconv: illegal AppendFloat/FormatFloat bitSize")
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
neg := bits>>(flt.expbits+flt.mantbits) != 0
|
|
499
|
+
exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
|
|
500
|
+
mant := bits & (uint64(1)<<flt.mantbits - 1)
|
|
501
|
+
|
|
502
|
+
switch exp {
|
|
503
|
+
case 1<<flt.expbits - 1:
|
|
504
|
+
// Inf, NaN
|
|
505
|
+
var s string
|
|
506
|
+
switch {
|
|
507
|
+
case mant != 0:
|
|
508
|
+
s = "NaN"
|
|
509
|
+
case neg:
|
|
510
|
+
s = "-Inf"
|
|
511
|
+
default:
|
|
512
|
+
s = "+Inf"
|
|
513
|
+
}
|
|
514
|
+
return append(dst, s...)
|
|
515
|
+
|
|
516
|
+
case 0:
|
|
517
|
+
// denormalized
|
|
518
|
+
exp++
|
|
519
|
+
|
|
520
|
+
default:
|
|
521
|
+
// add implicit top bit
|
|
522
|
+
mant |= uint64(1) << flt.mantbits
|
|
523
|
+
}
|
|
524
|
+
exp += flt.bias
|
|
525
|
+
|
|
526
|
+
// Pick off easy binary, hex formats.
|
|
527
|
+
if fmt == 'b' {
|
|
528
|
+
return fmtB(dst, neg, mant, exp, flt)
|
|
529
|
+
}
|
|
530
|
+
if fmt == 'x' || fmt == 'X' {
|
|
531
|
+
return fmtX(dst, prec, fmt, neg, mant, exp, flt)
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
if prec < 0 && bitSize == 64 && mant != 0 {
|
|
535
|
+
// The host's number printer gives the shortest digits.
|
|
536
|
+
digs := shortestDigits(math.Abs(val))
|
|
537
|
+
switch fmt {
|
|
538
|
+
case 'e', 'E':
|
|
539
|
+
prec = digs.nd - 1
|
|
540
|
+
case 'f':
|
|
541
|
+
prec = max(digs.nd-digs.dp, 0)
|
|
542
|
+
case 'g', 'G':
|
|
543
|
+
prec = digs.nd
|
|
544
|
+
}
|
|
545
|
+
return formatDigits(dst, true, neg, digs, prec, fmt)
|
|
546
|
+
}
|
|
547
|
+
return bigFtoa(dst, prec, fmt, neg, mant, exp, flt)
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// fixed formats f, a finite float64 of at least zero, with prec digits after
|
|
551
|
+
// the point as %f does, rounding exact ties to even; "" when the host cannot
|
|
552
|
+
// (f is 1e21 or more). The Go body always declines, and the caller then uses
|
|
553
|
+
// bigFtoa.
|
|
554
|
+
//
|
|
555
|
+
//gofront:native strconv.fixed
|
|
556
|
+
func fixed(f float64, prec int) string {
|
|
557
|
+
return ""
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// shortestDigits returns the fewest digits that read back as f, a finite
|
|
561
|
+
// float64 above zero.
|
|
562
|
+
func shortestDigits(f float64) decimalSlice {
|
|
563
|
+
s := shortest(f)
|
|
564
|
+
buf := make([]byte, 0, 17)
|
|
565
|
+
e := 0
|
|
566
|
+
for i := 0; i < len(s); i++ {
|
|
567
|
+
c := byte(s[i])
|
|
568
|
+
if c == 'e' {
|
|
569
|
+
e, _ = Atoi(s[i+1:])
|
|
570
|
+
break
|
|
571
|
+
}
|
|
572
|
+
if c != '.' {
|
|
573
|
+
buf = append(buf, c)
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return decimalSlice{d: buf, nd: len(buf), dp: e + 1}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// shortest formats f, a finite float64 above zero, as the shortest digits
|
|
580
|
+
// that read back as f, in the form d.ddde+x of a host number printer.
|
|
581
|
+
//
|
|
582
|
+
//gofront:native strconv.shortest
|
|
583
|
+
func shortest(f float64) string {
|
|
584
|
+
bits := math.Float64bits(f)
|
|
585
|
+
flt := float64info()
|
|
586
|
+
exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
|
|
587
|
+
mant := bits & (uint64(1)<<flt.mantbits - 1)
|
|
588
|
+
if exp == 0 {
|
|
589
|
+
exp++
|
|
590
|
+
} else {
|
|
591
|
+
mant |= uint64(1) << flt.mantbits
|
|
592
|
+
}
|
|
593
|
+
exp += flt.bias
|
|
594
|
+
d := new(decimal)
|
|
595
|
+
d.Assign(mant)
|
|
596
|
+
d.Shift(exp - int(flt.mantbits))
|
|
597
|
+
roundShortest(d, mant, exp, flt)
|
|
598
|
+
out := make([]byte, 0, 32)
|
|
599
|
+
out = append(out, d.d[0])
|
|
600
|
+
if d.nd > 1 {
|
|
601
|
+
out = append(out, '.')
|
|
602
|
+
out = append(out, d.d[1:d.nd]...)
|
|
603
|
+
}
|
|
604
|
+
out = append(out, 'e')
|
|
605
|
+
e := d.dp - 1
|
|
606
|
+
if e < 0 {
|
|
607
|
+
out = append(out, '-')
|
|
608
|
+
e = -e
|
|
609
|
+
} else {
|
|
610
|
+
out = append(out, '+')
|
|
611
|
+
}
|
|
612
|
+
out = AppendInt(out, int64(e), 10)
|
|
613
|
+
return string(out)
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// bigFtoa uses multiprecision computations to format a float.
|
|
617
|
+
func bigFtoa(dst []byte, prec int, fmt byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
|
|
618
|
+
d := new(decimal)
|
|
619
|
+
d.Assign(mant)
|
|
620
|
+
d.Shift(exp - int(flt.mantbits))
|
|
621
|
+
var digs decimalSlice
|
|
622
|
+
shortest := prec < 0
|
|
623
|
+
if shortest {
|
|
624
|
+
roundShortest(d, mant, exp, flt)
|
|
625
|
+
digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp}
|
|
626
|
+
// Precision for shortest representation mode.
|
|
627
|
+
switch fmt {
|
|
628
|
+
case 'e', 'E':
|
|
629
|
+
prec = digs.nd - 1
|
|
630
|
+
case 'f':
|
|
631
|
+
prec = max(digs.nd-digs.dp, 0)
|
|
632
|
+
case 'g', 'G':
|
|
633
|
+
prec = digs.nd
|
|
634
|
+
}
|
|
635
|
+
} else {
|
|
636
|
+
// Round appropriately.
|
|
637
|
+
switch fmt {
|
|
638
|
+
case 'e', 'E':
|
|
639
|
+
d.Round(prec + 1)
|
|
640
|
+
case 'f':
|
|
641
|
+
d.Round(d.dp + prec)
|
|
642
|
+
case 'g', 'G':
|
|
643
|
+
if prec == 0 {
|
|
644
|
+
prec = 1
|
|
645
|
+
}
|
|
646
|
+
d.Round(prec)
|
|
647
|
+
}
|
|
648
|
+
digs = decimalSlice{d: d.d[:], nd: d.nd, dp: d.dp}
|
|
649
|
+
}
|
|
650
|
+
return formatDigits(dst, shortest, neg, digs, prec, fmt)
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
func formatDigits(dst []byte, shortest bool, neg bool, digs decimalSlice, prec int, fmt byte) []byte {
|
|
654
|
+
switch fmt {
|
|
655
|
+
case 'e', 'E':
|
|
656
|
+
return fmtE(dst, neg, digs, prec, fmt)
|
|
657
|
+
case 'f':
|
|
658
|
+
return fmtF(dst, neg, digs, prec)
|
|
659
|
+
case 'g', 'G':
|
|
660
|
+
// trailing fractional zeros in 'e' form will be trimmed.
|
|
661
|
+
eprec := prec
|
|
662
|
+
if eprec > digs.nd && digs.nd >= digs.dp {
|
|
663
|
+
eprec = digs.nd
|
|
664
|
+
}
|
|
665
|
+
// %e is used if the exponent from the conversion
|
|
666
|
+
// is less than -4 or greater than or equal to the precision.
|
|
667
|
+
// if precision was the shortest possible, use precision 6 for this decision.
|
|
668
|
+
if shortest {
|
|
669
|
+
eprec = 6
|
|
670
|
+
}
|
|
671
|
+
exp := digs.dp - 1
|
|
672
|
+
if exp < -4 || exp >= eprec {
|
|
673
|
+
if prec > digs.nd {
|
|
674
|
+
prec = digs.nd
|
|
675
|
+
}
|
|
676
|
+
return fmtE(dst, neg, digs, prec-1, fmt+'e'-'g')
|
|
677
|
+
}
|
|
678
|
+
if prec > digs.dp {
|
|
679
|
+
prec = digs.nd
|
|
680
|
+
}
|
|
681
|
+
return fmtF(dst, neg, digs, max(prec-digs.dp, 0))
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// unknown format
|
|
685
|
+
return append(dst, '%', fmt)
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// roundShortest rounds d (= mant * 2^exp) to the shortest number of digits
|
|
689
|
+
// that will let the original floating point value be precisely reconstructed.
|
|
690
|
+
func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) {
|
|
691
|
+
// If mantissa is zero, the number is zero; stop now.
|
|
692
|
+
if mant == 0 {
|
|
693
|
+
d.nd = 0
|
|
694
|
+
return
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
// Compute upper and lower such that any decimal number
|
|
698
|
+
// between upper and lower (possibly inclusive)
|
|
699
|
+
// will round to the original floating point number.
|
|
700
|
+
|
|
701
|
+
// We may see at once that the number is already shortest.
|
|
702
|
+
//
|
|
703
|
+
// Suppose d is not denormal, so that 2^exp <= d < 10^dp.
|
|
704
|
+
// The closest shorter number is at least 10^(dp-nd) away.
|
|
705
|
+
// The lower/upper bounds computed below are at distance
|
|
706
|
+
// at most 2^(exp-mantbits).
|
|
707
|
+
//
|
|
708
|
+
// So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits),
|
|
709
|
+
// or equivalently log2(10)*(dp-nd) > exp-mantbits.
|
|
710
|
+
// It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32).
|
|
711
|
+
minexp := flt.bias + 1 // minimum possible exponent
|
|
712
|
+
if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) {
|
|
713
|
+
// The number is already shortest.
|
|
714
|
+
return
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// d = mant << (exp - mantbits)
|
|
718
|
+
// Next highest floating point number is mant+1 << exp-mantbits.
|
|
719
|
+
// Our upper bound is halfway between, mant*2+1 << exp-mantbits-1.
|
|
720
|
+
upper := new(decimal)
|
|
721
|
+
upper.Assign(mant*2 + 1)
|
|
722
|
+
upper.Shift(exp - int(flt.mantbits) - 1)
|
|
723
|
+
|
|
724
|
+
// d = mant << (exp - mantbits)
|
|
725
|
+
// Next lowest floating point number is mant-1 << exp-mantbits,
|
|
726
|
+
// unless mant-1 drops the significant bit and exp is not the minimum exp,
|
|
727
|
+
// in which case the next lowest is mant*2-1 << exp-mantbits-1.
|
|
728
|
+
// Either way, call it mantlo << explo-mantbits.
|
|
729
|
+
// Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1.
|
|
730
|
+
var mantlo uint64
|
|
731
|
+
var explo int
|
|
732
|
+
if mant > uint64(1)<<flt.mantbits || exp == minexp {
|
|
733
|
+
mantlo = mant - 1
|
|
734
|
+
explo = exp
|
|
735
|
+
} else {
|
|
736
|
+
mantlo = mant*2 - 1
|
|
737
|
+
explo = exp - 1
|
|
738
|
+
}
|
|
739
|
+
lower := new(decimal)
|
|
740
|
+
lower.Assign(mantlo*2 + 1)
|
|
741
|
+
lower.Shift(explo - int(flt.mantbits) - 1)
|
|
742
|
+
|
|
743
|
+
// The upper and lower bounds are possible outputs only if
|
|
744
|
+
// the original mantissa is even, so that IEEE round-to-even
|
|
745
|
+
// would round to the original mantissa and not the neighbors.
|
|
746
|
+
inclusive := mant%2 == 0
|
|
747
|
+
|
|
748
|
+
// As we walk the digits we want to know whether rounding up would fall
|
|
749
|
+
// within the upper bound. This is tracked by upperdelta:
|
|
750
|
+
//
|
|
751
|
+
// If upperdelta == 0, the digits of d and upper are the same so far.
|
|
752
|
+
//
|
|
753
|
+
// If upperdelta == 1, we saw a difference of 1 between d and upper on a
|
|
754
|
+
// previous digit and subsequently only 9s for d and 0s for upper.
|
|
755
|
+
// (Thus rounding up may fall outside the bound, if it is exclusive.)
|
|
756
|
+
//
|
|
757
|
+
// If upperdelta == 2, then the difference is greater than 1
|
|
758
|
+
// and we know that rounding up falls within the bound.
|
|
759
|
+
var upperdelta uint8
|
|
760
|
+
|
|
761
|
+
// Now we can figure out the minimum number of digits required.
|
|
762
|
+
// Walk along until d has distinguished itself from upper and lower.
|
|
763
|
+
for ui := 0; ; ui++ {
|
|
764
|
+
// lower, d, and upper may have the decimal points at different
|
|
765
|
+
// places. In this case upper is the longest, so we iterate from
|
|
766
|
+
// ui==0 and start li and mi at (possibly) -1.
|
|
767
|
+
mi := ui - upper.dp + d.dp
|
|
768
|
+
if mi >= d.nd {
|
|
769
|
+
break
|
|
770
|
+
}
|
|
771
|
+
li := ui - upper.dp + lower.dp
|
|
772
|
+
l := byte('0') // lower digit
|
|
773
|
+
if li >= 0 && li < lower.nd {
|
|
774
|
+
l = lower.d[li]
|
|
775
|
+
}
|
|
776
|
+
m := byte('0') // middle digit
|
|
777
|
+
if mi >= 0 {
|
|
778
|
+
m = d.d[mi]
|
|
779
|
+
}
|
|
780
|
+
u := byte('0') // upper digit
|
|
781
|
+
if ui < upper.nd {
|
|
782
|
+
u = upper.d[ui]
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// Okay to round down (truncate) if lower has a different digit
|
|
786
|
+
// or if lower is inclusive and is exactly the result of rounding
|
|
787
|
+
// down (i.e., and we have reached the final digit of lower).
|
|
788
|
+
okdown := l != m || inclusive && li+1 == lower.nd
|
|
789
|
+
|
|
790
|
+
switch {
|
|
791
|
+
case upperdelta == 0 && m+1 < u:
|
|
792
|
+
// Example:
|
|
793
|
+
// m = 12345xxx
|
|
794
|
+
// u = 12347xxx
|
|
795
|
+
upperdelta = 2
|
|
796
|
+
case upperdelta == 0 && m != u:
|
|
797
|
+
// Example:
|
|
798
|
+
// m = 12345xxx
|
|
799
|
+
// u = 12346xxx
|
|
800
|
+
upperdelta = 1
|
|
801
|
+
case upperdelta == 1 && (m != '9' || u != '0'):
|
|
802
|
+
// Example:
|
|
803
|
+
// m = 1234598x
|
|
804
|
+
// u = 1234600x
|
|
805
|
+
upperdelta = 2
|
|
806
|
+
}
|
|
807
|
+
// Okay to round up if upper has a different digit and either upper
|
|
808
|
+
// is inclusive or upper is bigger than the result of rounding up.
|
|
809
|
+
okup := upperdelta > 0 && (inclusive || upperdelta > 1 || ui+1 < upper.nd)
|
|
810
|
+
|
|
811
|
+
// If it's okay to do either, then round to the nearest one.
|
|
812
|
+
// If it's okay to do only one, do it.
|
|
813
|
+
switch {
|
|
814
|
+
case okdown && okup:
|
|
815
|
+
d.Round(mi + 1)
|
|
816
|
+
return
|
|
817
|
+
case okdown:
|
|
818
|
+
d.RoundDown(mi + 1)
|
|
819
|
+
return
|
|
820
|
+
case okup:
|
|
821
|
+
d.RoundUp(mi + 1)
|
|
822
|
+
return
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
type decimalSlice struct {
|
|
828
|
+
d []byte
|
|
829
|
+
nd, dp int
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// %e: -d.ddddde±dd
|
|
833
|
+
func fmtE(dst []byte, neg bool, d decimalSlice, prec int, fmt byte) []byte {
|
|
834
|
+
// sign
|
|
835
|
+
if neg {
|
|
836
|
+
dst = append(dst, '-')
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// first digit
|
|
840
|
+
ch := byte('0')
|
|
841
|
+
if d.nd != 0 {
|
|
842
|
+
ch = d.d[0]
|
|
843
|
+
}
|
|
844
|
+
dst = append(dst, ch)
|
|
845
|
+
|
|
846
|
+
// .moredigits
|
|
847
|
+
if prec > 0 {
|
|
848
|
+
dst = append(dst, '.')
|
|
849
|
+
i := 1
|
|
850
|
+
m := min(d.nd, prec+1)
|
|
851
|
+
if i < m {
|
|
852
|
+
dst = append(dst, d.d[i:m]...)
|
|
853
|
+
i = m
|
|
854
|
+
}
|
|
855
|
+
for ; i <= prec; i++ {
|
|
856
|
+
dst = append(dst, '0')
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
// e±
|
|
861
|
+
dst = append(dst, fmt)
|
|
862
|
+
exp := d.dp - 1
|
|
863
|
+
if d.nd == 0 { // special case: 0 has exponent 0
|
|
864
|
+
exp = 0
|
|
865
|
+
}
|
|
866
|
+
if exp < 0 {
|
|
867
|
+
ch = '-'
|
|
868
|
+
exp = -exp
|
|
869
|
+
} else {
|
|
870
|
+
ch = '+'
|
|
871
|
+
}
|
|
872
|
+
dst = append(dst, ch)
|
|
873
|
+
|
|
874
|
+
// dd or ddd
|
|
875
|
+
switch {
|
|
876
|
+
case exp < 10:
|
|
877
|
+
dst = append(dst, '0', byte(exp)+'0')
|
|
878
|
+
case exp < 100:
|
|
879
|
+
dst = append(dst, byte(exp/10)+'0', byte(exp%10)+'0')
|
|
880
|
+
default:
|
|
881
|
+
dst = append(dst, byte(exp/100)+'0', byte(exp/10)%10+'0', byte(exp%10)+'0')
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
return dst
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
// %f: -ddddddd.ddddd
|
|
888
|
+
func fmtF(dst []byte, neg bool, d decimalSlice, prec int) []byte {
|
|
889
|
+
// sign
|
|
890
|
+
if neg {
|
|
891
|
+
dst = append(dst, '-')
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
// integer, padded with zeros as needed.
|
|
895
|
+
if d.dp > 0 {
|
|
896
|
+
m := min(d.nd, d.dp)
|
|
897
|
+
dst = append(dst, d.d[:m]...)
|
|
898
|
+
for ; m < d.dp; m++ {
|
|
899
|
+
dst = append(dst, '0')
|
|
900
|
+
}
|
|
901
|
+
} else {
|
|
902
|
+
dst = append(dst, '0')
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
// fraction
|
|
906
|
+
if prec > 0 {
|
|
907
|
+
dst = append(dst, '.')
|
|
908
|
+
for i := 0; i < prec; i++ {
|
|
909
|
+
ch := byte('0')
|
|
910
|
+
if j := d.dp + i; 0 <= j && j < d.nd {
|
|
911
|
+
ch = d.d[j]
|
|
912
|
+
}
|
|
913
|
+
dst = append(dst, ch)
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
return dst
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
// %b: -ddddddddp±ddd
|
|
921
|
+
func fmtB(dst []byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
|
|
922
|
+
// sign
|
|
923
|
+
if neg {
|
|
924
|
+
dst = append(dst, '-')
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
// mantissa
|
|
928
|
+
dst = AppendUint(dst, mant, 10)
|
|
929
|
+
|
|
930
|
+
// p
|
|
931
|
+
dst = append(dst, 'p')
|
|
932
|
+
|
|
933
|
+
// ±exponent
|
|
934
|
+
exp -= int(flt.mantbits)
|
|
935
|
+
if exp >= 0 {
|
|
936
|
+
dst = append(dst, '+')
|
|
937
|
+
}
|
|
938
|
+
dst = AppendInt(dst, int64(exp), 10)
|
|
939
|
+
|
|
940
|
+
return dst
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
// %x: -0x1.yyyyyyyyp±ddd or -0x0p+0. (y is hex digit, d is decimal digit)
|
|
944
|
+
func fmtX(dst []byte, prec int, fmt byte, neg bool, mant uint64, exp int, flt *floatInfo) []byte {
|
|
945
|
+
if mant == 0 {
|
|
946
|
+
exp = 0
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// Shift digits so leading 1 (if any) is at bit 1<<60.
|
|
950
|
+
mant <<= 60 - flt.mantbits
|
|
951
|
+
for mant != 0 && mant&(1<<60) == 0 {
|
|
952
|
+
mant <<= 1
|
|
953
|
+
exp--
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
// Round if requested.
|
|
957
|
+
if prec >= 0 && prec < 15 {
|
|
958
|
+
shift := uint(prec * 4)
|
|
959
|
+
extra := (mant << shift) & (1<<60 - 1)
|
|
960
|
+
mant >>= 60 - shift
|
|
961
|
+
if extra|(mant&1) > 1<<59 {
|
|
962
|
+
mant++
|
|
963
|
+
}
|
|
964
|
+
mant <<= 60 - shift
|
|
965
|
+
if mant&(1<<61) != 0 {
|
|
966
|
+
// Wrapped around.
|
|
967
|
+
mant >>= 1
|
|
968
|
+
exp++
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
hex := lowerhex
|
|
973
|
+
if fmt == 'X' {
|
|
974
|
+
hex = upperhex
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// sign, 0x, leading digit
|
|
978
|
+
if neg {
|
|
979
|
+
dst = append(dst, '-')
|
|
980
|
+
}
|
|
981
|
+
dst = append(dst, '0', fmt, '0'+byte((mant>>60)&1))
|
|
982
|
+
|
|
983
|
+
// .fraction
|
|
984
|
+
mant <<= 4 // remove leading 0 or 1
|
|
985
|
+
if prec < 0 && mant != 0 {
|
|
986
|
+
dst = append(dst, '.')
|
|
987
|
+
for mant != 0 {
|
|
988
|
+
dst = append(dst, hex[(mant>>60)&15])
|
|
989
|
+
mant <<= 4
|
|
990
|
+
}
|
|
991
|
+
} else if prec > 0 {
|
|
992
|
+
dst = append(dst, '.')
|
|
993
|
+
for i := 0; i < prec; i++ {
|
|
994
|
+
dst = append(dst, hex[(mant>>60)&15])
|
|
995
|
+
mant <<= 4
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
// p±
|
|
1000
|
+
ch := byte('P')
|
|
1001
|
+
if fmt == lower(fmt) {
|
|
1002
|
+
ch = 'p'
|
|
1003
|
+
}
|
|
1004
|
+
dst = append(dst, ch)
|
|
1005
|
+
if exp < 0 {
|
|
1006
|
+
ch = '-'
|
|
1007
|
+
exp = -exp
|
|
1008
|
+
} else {
|
|
1009
|
+
ch = '+'
|
|
1010
|
+
}
|
|
1011
|
+
dst = append(dst, ch)
|
|
1012
|
+
|
|
1013
|
+
// dd or ddd or dddd
|
|
1014
|
+
switch {
|
|
1015
|
+
case exp < 100:
|
|
1016
|
+
dst = append(dst, byte(exp/10)+'0', byte(exp%10)+'0')
|
|
1017
|
+
case exp < 1000:
|
|
1018
|
+
dst = append(dst, byte(exp/100)+'0', byte((exp/10)%10)+'0', byte(exp%10)+'0')
|
|
1019
|
+
default:
|
|
1020
|
+
dst = append(dst, byte(exp/1000)+'0', byte(exp/100)%10+'0', byte((exp/10)%10)+'0', byte(exp%10)+'0')
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
return dst
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
|
|
1027
|
+
// decimal to binary floating point conversion.
|
|
1028
|
+
// Algorithm:
|
|
1029
|
+
// 1) Store input in multiprecision decimal.
|
|
1030
|
+
// 2) Multiply/divide decimal by powers of two until in range [0.5, 1)
|
|
1031
|
+
// 3) Multiply by 2^precision and round to get mantissa.
|
|
1032
|
+
|
|
1033
|
+
|
|
1034
|
+
// commonPrefixLenIgnoreCase returns the length of the common
|
|
1035
|
+
// prefix of s and prefix, with the character case of s ignored.
|
|
1036
|
+
// The prefix argument must be all lower-case.
|
|
1037
|
+
func commonPrefixLenIgnoreCase(s, prefix string) int {
|
|
1038
|
+
n := min(len(prefix), len(s))
|
|
1039
|
+
for i := 0; i < n; i++ {
|
|
1040
|
+
c := s[i]
|
|
1041
|
+
if 'A' <= c && c <= 'Z' {
|
|
1042
|
+
c += 'a' - 'A'
|
|
1043
|
+
}
|
|
1044
|
+
if c != prefix[i] {
|
|
1045
|
+
return i
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
return n
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// special returns the floating-point value for the special,
|
|
1052
|
+
// possibly signed floating-point representations inf, infinity,
|
|
1053
|
+
// and NaN. The result is ok if a prefix of s contains one
|
|
1054
|
+
// of these representations and n is the length of that prefix.
|
|
1055
|
+
// The character case is ignored.
|
|
1056
|
+
func special(s string) (f float64, n int, ok bool) {
|
|
1057
|
+
if len(s) == 0 {
|
|
1058
|
+
return 0, 0, false
|
|
1059
|
+
}
|
|
1060
|
+
sign := 1
|
|
1061
|
+
nsign := 0
|
|
1062
|
+
switch s[0] {
|
|
1063
|
+
case '+', '-':
|
|
1064
|
+
if s[0] == '-' {
|
|
1065
|
+
sign = -1
|
|
1066
|
+
}
|
|
1067
|
+
nsign = 1
|
|
1068
|
+
s = s[1:]
|
|
1069
|
+
fallthrough
|
|
1070
|
+
case 'i', 'I':
|
|
1071
|
+
n := commonPrefixLenIgnoreCase(s, "infinity")
|
|
1072
|
+
// Anything longer than "inf" is ok, but if we
|
|
1073
|
+
// don't have "infinity", only consume "inf".
|
|
1074
|
+
if 3 < n && n < 8 {
|
|
1075
|
+
n = 3
|
|
1076
|
+
}
|
|
1077
|
+
if n == 3 || n == 8 {
|
|
1078
|
+
return math.Inf(sign), nsign + n, true
|
|
1079
|
+
}
|
|
1080
|
+
case 'n', 'N':
|
|
1081
|
+
if commonPrefixLenIgnoreCase(s, "nan") == 3 {
|
|
1082
|
+
return math.NaN(), 3, true
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
return 0, 0, false
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
func (b *decimal) set(s string) (ok bool) {
|
|
1089
|
+
i := 0
|
|
1090
|
+
b.neg = false
|
|
1091
|
+
b.trunc = false
|
|
1092
|
+
|
|
1093
|
+
// optional sign
|
|
1094
|
+
if i >= len(s) {
|
|
1095
|
+
return
|
|
1096
|
+
}
|
|
1097
|
+
switch s[i] {
|
|
1098
|
+
case '+':
|
|
1099
|
+
i++
|
|
1100
|
+
case '-':
|
|
1101
|
+
i++
|
|
1102
|
+
b.neg = true
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
// digits
|
|
1106
|
+
sawdot := false
|
|
1107
|
+
sawdigits := false
|
|
1108
|
+
for ; i < len(s); i++ {
|
|
1109
|
+
switch {
|
|
1110
|
+
case s[i] == '_':
|
|
1111
|
+
// readFloat already checked underscores
|
|
1112
|
+
continue
|
|
1113
|
+
case s[i] == '.':
|
|
1114
|
+
if sawdot {
|
|
1115
|
+
return
|
|
1116
|
+
}
|
|
1117
|
+
sawdot = true
|
|
1118
|
+
b.dp = b.nd
|
|
1119
|
+
continue
|
|
1120
|
+
|
|
1121
|
+
case '0' <= s[i] && s[i] <= '9':
|
|
1122
|
+
sawdigits = true
|
|
1123
|
+
if s[i] == '0' && b.nd == 0 { // ignore leading zeros
|
|
1124
|
+
b.dp--
|
|
1125
|
+
continue
|
|
1126
|
+
}
|
|
1127
|
+
if b.nd < len(b.d) {
|
|
1128
|
+
b.d[b.nd] = byte(s[i])
|
|
1129
|
+
b.nd++
|
|
1130
|
+
} else if s[i] != '0' {
|
|
1131
|
+
b.trunc = true
|
|
1132
|
+
}
|
|
1133
|
+
continue
|
|
1134
|
+
}
|
|
1135
|
+
break
|
|
1136
|
+
}
|
|
1137
|
+
if !sawdigits {
|
|
1138
|
+
return
|
|
1139
|
+
}
|
|
1140
|
+
if !sawdot {
|
|
1141
|
+
b.dp = b.nd
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
// optional exponent moves decimal point.
|
|
1145
|
+
// if we read a very large, very long number,
|
|
1146
|
+
// just be sure to move the decimal point by
|
|
1147
|
+
// a lot (say, 100000). it doesn't matter if it's
|
|
1148
|
+
// not the exact number.
|
|
1149
|
+
if i < len(s) && lowerS(s[i]) == 'e' {
|
|
1150
|
+
i++
|
|
1151
|
+
if i >= len(s) {
|
|
1152
|
+
return
|
|
1153
|
+
}
|
|
1154
|
+
esign := 1
|
|
1155
|
+
switch s[i] {
|
|
1156
|
+
case '+':
|
|
1157
|
+
i++
|
|
1158
|
+
case '-':
|
|
1159
|
+
i++
|
|
1160
|
+
esign = -1
|
|
1161
|
+
}
|
|
1162
|
+
if i >= len(s) || s[i] < '0' || s[i] > '9' {
|
|
1163
|
+
return
|
|
1164
|
+
}
|
|
1165
|
+
e := 0
|
|
1166
|
+
for ; i < len(s) && ('0' <= s[i] && s[i] <= '9' || s[i] == '_'); i++ {
|
|
1167
|
+
if s[i] == '_' {
|
|
1168
|
+
// readFloat already checked underscores
|
|
1169
|
+
continue
|
|
1170
|
+
}
|
|
1171
|
+
if e < 10000 {
|
|
1172
|
+
e = e*10 + int(s[i]) - '0'
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
b.dp += e * esign
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
if i != len(s) {
|
|
1179
|
+
return
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
ok = true
|
|
1183
|
+
return
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
// readFloat reads a decimal or hexadecimal mantissa and exponent from a float
|
|
1187
|
+
// string representation in s; the number may be followed by other characters.
|
|
1188
|
+
// readFloat reports the number of bytes consumed (i), and whether the number
|
|
1189
|
+
// is valid (ok).
|
|
1190
|
+
func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex bool, i int, ok bool) {
|
|
1191
|
+
underscores := false
|
|
1192
|
+
|
|
1193
|
+
// optional sign
|
|
1194
|
+
if i >= len(s) {
|
|
1195
|
+
return
|
|
1196
|
+
}
|
|
1197
|
+
switch s[i] {
|
|
1198
|
+
case '+':
|
|
1199
|
+
i++
|
|
1200
|
+
case '-':
|
|
1201
|
+
i++
|
|
1202
|
+
neg = true
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
// digits
|
|
1206
|
+
base := uint64(10)
|
|
1207
|
+
maxMantDigits := 19 // 10^19 fits in uint64
|
|
1208
|
+
expChar := byte('e')
|
|
1209
|
+
if i+2 < len(s) && s[i] == '0' && lowerS(s[i+1]) == 'x' {
|
|
1210
|
+
base = 16
|
|
1211
|
+
maxMantDigits = 16 // 16^16 fits in uint64
|
|
1212
|
+
i += 2
|
|
1213
|
+
expChar = 'p'
|
|
1214
|
+
hex = true
|
|
1215
|
+
}
|
|
1216
|
+
sawdot := false
|
|
1217
|
+
sawdigits := false
|
|
1218
|
+
nd := 0
|
|
1219
|
+
ndMant := 0
|
|
1220
|
+
dp := 0
|
|
1221
|
+
loop:
|
|
1222
|
+
for ; i < len(s); i++ {
|
|
1223
|
+
switch c := s[i]; true {
|
|
1224
|
+
case c == '_':
|
|
1225
|
+
underscores = true
|
|
1226
|
+
continue
|
|
1227
|
+
|
|
1228
|
+
case c == '.':
|
|
1229
|
+
if sawdot {
|
|
1230
|
+
break loop
|
|
1231
|
+
}
|
|
1232
|
+
sawdot = true
|
|
1233
|
+
dp = nd
|
|
1234
|
+
continue
|
|
1235
|
+
|
|
1236
|
+
case '0' <= c && c <= '9':
|
|
1237
|
+
sawdigits = true
|
|
1238
|
+
if c == '0' && nd == 0 { // ignore leading zeros
|
|
1239
|
+
dp--
|
|
1240
|
+
continue
|
|
1241
|
+
}
|
|
1242
|
+
nd++
|
|
1243
|
+
if ndMant < maxMantDigits {
|
|
1244
|
+
mantissa *= base
|
|
1245
|
+
mantissa += uint64(c - '0')
|
|
1246
|
+
ndMant++
|
|
1247
|
+
} else if c != '0' {
|
|
1248
|
+
trunc = true
|
|
1249
|
+
}
|
|
1250
|
+
continue
|
|
1251
|
+
|
|
1252
|
+
case base == 16 && 'a' <= lowerS(c) && lowerS(c) <= 'f':
|
|
1253
|
+
sawdigits = true
|
|
1254
|
+
nd++
|
|
1255
|
+
if ndMant < maxMantDigits {
|
|
1256
|
+
mantissa *= 16
|
|
1257
|
+
mantissa += uint64(lowerS(c) - 'a' + 10)
|
|
1258
|
+
ndMant++
|
|
1259
|
+
} else {
|
|
1260
|
+
trunc = true
|
|
1261
|
+
}
|
|
1262
|
+
continue
|
|
1263
|
+
}
|
|
1264
|
+
break
|
|
1265
|
+
}
|
|
1266
|
+
if !sawdigits {
|
|
1267
|
+
return
|
|
1268
|
+
}
|
|
1269
|
+
if !sawdot {
|
|
1270
|
+
dp = nd
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
if base == 16 {
|
|
1274
|
+
dp *= 4
|
|
1275
|
+
ndMant *= 4
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
// optional exponent moves decimal point.
|
|
1279
|
+
// if we read a very large, very long number,
|
|
1280
|
+
// just be sure to move the decimal point by
|
|
1281
|
+
// a lot (say, 100000). it doesn't matter if it's
|
|
1282
|
+
// not the exact number.
|
|
1283
|
+
if i < len(s) && lowerS(s[i]) == expChar {
|
|
1284
|
+
i++
|
|
1285
|
+
if i >= len(s) {
|
|
1286
|
+
return
|
|
1287
|
+
}
|
|
1288
|
+
esign := 1
|
|
1289
|
+
switch s[i] {
|
|
1290
|
+
case '+':
|
|
1291
|
+
i++
|
|
1292
|
+
case '-':
|
|
1293
|
+
i++
|
|
1294
|
+
esign = -1
|
|
1295
|
+
}
|
|
1296
|
+
if i >= len(s) || s[i] < '0' || s[i] > '9' {
|
|
1297
|
+
return
|
|
1298
|
+
}
|
|
1299
|
+
e := 0
|
|
1300
|
+
for ; i < len(s) && ('0' <= s[i] && s[i] <= '9' || s[i] == '_'); i++ {
|
|
1301
|
+
if s[i] == '_' {
|
|
1302
|
+
underscores = true
|
|
1303
|
+
continue
|
|
1304
|
+
}
|
|
1305
|
+
if e < 10000 {
|
|
1306
|
+
e = e*10 + int(s[i]) - '0'
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
dp += e * esign
|
|
1310
|
+
} else if base == 16 {
|
|
1311
|
+
// Must have exponent.
|
|
1312
|
+
return
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
if mantissa != 0 {
|
|
1316
|
+
exp = dp - ndMant
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
if underscores && !underscoreOK(s[:i]) {
|
|
1320
|
+
return
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
ok = true
|
|
1324
|
+
return
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
// decimal power of ten to binary power of two.
|
|
1328
|
+
var powtab = []int{1, 3, 6, 9, 13, 16, 19, 23, 26}
|
|
1329
|
+
|
|
1330
|
+
func (d *decimal) floatBits(flt *floatInfo) (b uint64, overflow bool) {
|
|
1331
|
+
mant, exp, overflow := d.floatParts(flt)
|
|
1332
|
+
// Assemble bits.
|
|
1333
|
+
bits := mant & (uint64(1)<<flt.mantbits - 1)
|
|
1334
|
+
bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits
|
|
1335
|
+
if d.neg {
|
|
1336
|
+
bits |= uint64(1) << flt.mantbits << flt.expbits
|
|
1337
|
+
}
|
|
1338
|
+
return bits, overflow
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
// floatParts is floatBits before the assembly: the mantissa, the exponent
|
|
1342
|
+
// and whether the value overflows to infinity.
|
|
1343
|
+
func (d *decimal) floatParts(flt *floatInfo) (mant uint64, exp int, overflow bool) {
|
|
1344
|
+
inf := 1<<flt.expbits - 1 + flt.bias
|
|
1345
|
+
|
|
1346
|
+
// Zero is always a special case.
|
|
1347
|
+
if d.nd == 0 {
|
|
1348
|
+
return 0, flt.bias, false
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
// Obvious overflow/underflow.
|
|
1352
|
+
// These bounds are for 64-bit floats.
|
|
1353
|
+
// Will have to change if we want to support 80-bit floats in the future.
|
|
1354
|
+
if d.dp > 310 {
|
|
1355
|
+
return 0, inf, true
|
|
1356
|
+
}
|
|
1357
|
+
if d.dp < -330 {
|
|
1358
|
+
// zero
|
|
1359
|
+
return 0, flt.bias, false
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
// Scale by powers of two until in range [0.5, 1.0)
|
|
1363
|
+
exp = 0
|
|
1364
|
+
for d.dp > 0 {
|
|
1365
|
+
var n int
|
|
1366
|
+
if d.dp >= len(powtab) {
|
|
1367
|
+
n = 27
|
|
1368
|
+
} else {
|
|
1369
|
+
n = powtab[d.dp]
|
|
1370
|
+
}
|
|
1371
|
+
d.Shift(-n)
|
|
1372
|
+
exp += n
|
|
1373
|
+
}
|
|
1374
|
+
for d.dp < 0 || d.dp == 0 && d.d[0] < '5' {
|
|
1375
|
+
var n int
|
|
1376
|
+
if -d.dp >= len(powtab) {
|
|
1377
|
+
n = 27
|
|
1378
|
+
} else {
|
|
1379
|
+
n = powtab[-d.dp]
|
|
1380
|
+
}
|
|
1381
|
+
d.Shift(n)
|
|
1382
|
+
exp -= n
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
// Our range is [0.5,1) but floating point range is [1,2).
|
|
1386
|
+
exp--
|
|
1387
|
+
|
|
1388
|
+
// Minimum representable exponent is flt.bias+1.
|
|
1389
|
+
// If the exponent is smaller, move it up and
|
|
1390
|
+
// adjust d accordingly.
|
|
1391
|
+
if exp < flt.bias+1 {
|
|
1392
|
+
n := flt.bias + 1 - exp
|
|
1393
|
+
d.Shift(-n)
|
|
1394
|
+
exp += n
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
if exp-flt.bias >= 1<<flt.expbits-1 {
|
|
1398
|
+
return 0, inf, true
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
// Extract 1+flt.mantbits bits.
|
|
1402
|
+
d.Shift(int(1 + flt.mantbits))
|
|
1403
|
+
mant = d.RoundedInteger()
|
|
1404
|
+
|
|
1405
|
+
// Rounding might have added a bit; shift down.
|
|
1406
|
+
if mant == uint64(2)<<flt.mantbits {
|
|
1407
|
+
mant >>= 1
|
|
1408
|
+
exp++
|
|
1409
|
+
if exp-flt.bias >= 1<<flt.expbits-1 {
|
|
1410
|
+
return 0, inf, true
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
// Denormalized?
|
|
1415
|
+
if mant&(uint64(1)<<flt.mantbits) == 0 {
|
|
1416
|
+
exp = flt.bias
|
|
1417
|
+
}
|
|
1418
|
+
return mant, exp, false
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
// Exact powers of 10.
|
|
1422
|
+
var float64pow10 = []float64{
|
|
1423
|
+
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
|
|
1424
|
+
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
|
|
1425
|
+
1e20, 1e21, 1e22,
|
|
1426
|
+
}
|
|
1427
|
+
var float32pow10 = []float32{1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10}
|
|
1428
|
+
|
|
1429
|
+
// If possible to convert decimal representation to 64-bit float f exactly,
|
|
1430
|
+
// entirely in floating-point math, do so, avoiding the expense of decimalToFloatBits.
|
|
1431
|
+
// Three common cases:
|
|
1432
|
+
//
|
|
1433
|
+
// value is exact integer
|
|
1434
|
+
// value is exact integer * exact power of ten
|
|
1435
|
+
// value is exact integer / exact power of ten
|
|
1436
|
+
//
|
|
1437
|
+
// These all produce potentially inexact but correctly rounded answers.
|
|
1438
|
+
func atof64exact(mantissa uint64, exp int, neg bool) (f float64, ok bool) {
|
|
1439
|
+
if mantissa>>float64MantBits != 0 {
|
|
1440
|
+
return
|
|
1441
|
+
}
|
|
1442
|
+
f = float64(mantissa)
|
|
1443
|
+
if neg {
|
|
1444
|
+
f = -f
|
|
1445
|
+
}
|
|
1446
|
+
switch {
|
|
1447
|
+
case exp == 0:
|
|
1448
|
+
// an integer.
|
|
1449
|
+
return f, true
|
|
1450
|
+
// Exact integers are <= 10^15.
|
|
1451
|
+
// Exact powers of ten are <= 10^22.
|
|
1452
|
+
case exp > 0 && exp <= 15+22: // int * 10^k
|
|
1453
|
+
// If exponent is big but number of digits is not,
|
|
1454
|
+
// can move a few zeros into the integer part.
|
|
1455
|
+
if exp > 22 {
|
|
1456
|
+
f *= float64pow10[exp-22]
|
|
1457
|
+
exp = 22
|
|
1458
|
+
}
|
|
1459
|
+
if f > 1e15 || f < -1e15 {
|
|
1460
|
+
// the exponent was really too large.
|
|
1461
|
+
return
|
|
1462
|
+
}
|
|
1463
|
+
return f * float64pow10[exp], true
|
|
1464
|
+
case exp < 0 && exp >= -22: // int / 10^k
|
|
1465
|
+
return f / float64pow10[-exp], true
|
|
1466
|
+
}
|
|
1467
|
+
return
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
// If possible to compute mantissa*10^exp to 32-bit float f exactly,
|
|
1471
|
+
// entirely in floating-point math, do so, avoiding the machinery above.
|
|
1472
|
+
func atof32exact(mantissa uint64, exp int, neg bool) (f float32, ok bool) {
|
|
1473
|
+
if mantissa>>float32MantBits != 0 {
|
|
1474
|
+
return
|
|
1475
|
+
}
|
|
1476
|
+
f = float32(mantissa)
|
|
1477
|
+
if neg {
|
|
1478
|
+
f = -f
|
|
1479
|
+
}
|
|
1480
|
+
switch {
|
|
1481
|
+
case exp == 0:
|
|
1482
|
+
return f, true
|
|
1483
|
+
// Exact integers are <= 10^7.
|
|
1484
|
+
// Exact powers of ten are <= 10^10.
|
|
1485
|
+
case exp > 0 && exp <= 7+10: // int * 10^k
|
|
1486
|
+
// If exponent is big but number of digits is not,
|
|
1487
|
+
// can move a few zeros into the integer part.
|
|
1488
|
+
if exp > 10 {
|
|
1489
|
+
f *= float32pow10[exp-10]
|
|
1490
|
+
exp = 10
|
|
1491
|
+
}
|
|
1492
|
+
if f > 1e7 || f < -1e7 {
|
|
1493
|
+
// the exponent was really too large.
|
|
1494
|
+
return
|
|
1495
|
+
}
|
|
1496
|
+
return f * float32pow10[exp], true
|
|
1497
|
+
case exp < 0 && exp >= -10: // int / 10^k
|
|
1498
|
+
return f / float32pow10[-exp], true
|
|
1499
|
+
}
|
|
1500
|
+
return
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
// atofHex converts the hex floating-point string s
|
|
1504
|
+
// to a rounded float32 or float64 value (depending on flt==float32info() or flt==float64info())
|
|
1505
|
+
// and returns it as a float64.
|
|
1506
|
+
// The string s has already been parsed into a mantissa, exponent, and sign (neg==true for negative).
|
|
1507
|
+
// If trunc is true, trailing non-zero bits have been omitted from the mantissa.
|
|
1508
|
+
func atofHex(s string, flt *floatInfo, mantissa uint64, exp int, neg, trunc bool) (float64, error) {
|
|
1509
|
+
maxExp := 1<<flt.expbits + flt.bias - 2
|
|
1510
|
+
minExp := flt.bias + 1
|
|
1511
|
+
exp += int(flt.mantbits) // mantissa now implicitly divided by 2^mantbits.
|
|
1512
|
+
|
|
1513
|
+
// Shift mantissa and exponent to bring representation into float range.
|
|
1514
|
+
// Eventually we want a mantissa with a leading 1-bit followed by mantbits other bits.
|
|
1515
|
+
// For rounding, we need two more, where the bottom bit represents
|
|
1516
|
+
// whether that bit or any later bit was non-zero.
|
|
1517
|
+
// (If the mantissa has already lost non-zero bits, trunc is true,
|
|
1518
|
+
// and we OR in a 1 below after shifting left appropriately.)
|
|
1519
|
+
for mantissa != 0 && mantissa>>(flt.mantbits+2) == 0 {
|
|
1520
|
+
mantissa <<= 1
|
|
1521
|
+
exp--
|
|
1522
|
+
}
|
|
1523
|
+
if trunc {
|
|
1524
|
+
mantissa |= 1
|
|
1525
|
+
}
|
|
1526
|
+
for mantissa>>(1+flt.mantbits+2) != 0 {
|
|
1527
|
+
mantissa = mantissa>>1 | mantissa&1
|
|
1528
|
+
exp++
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
// If exponent is too negative,
|
|
1532
|
+
// denormalize in hopes of making it representable.
|
|
1533
|
+
// (The -2 is for the rounding bits.)
|
|
1534
|
+
for mantissa > 1 && exp < minExp-2 {
|
|
1535
|
+
mantissa = mantissa>>1 | mantissa&1
|
|
1536
|
+
exp++
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
// Round using two bottom bits.
|
|
1540
|
+
round := mantissa & 3
|
|
1541
|
+
mantissa >>= 2
|
|
1542
|
+
round |= mantissa & 1 // round to even (round up if mantissa is odd)
|
|
1543
|
+
exp += 2
|
|
1544
|
+
if round == 3 {
|
|
1545
|
+
mantissa++
|
|
1546
|
+
if mantissa == uint64(1)<<(1+flt.mantbits) {
|
|
1547
|
+
mantissa >>= 1
|
|
1548
|
+
exp++
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
if mantissa>>flt.mantbits == 0 { // Denormal or zero.
|
|
1553
|
+
exp = flt.bias
|
|
1554
|
+
}
|
|
1555
|
+
var err error
|
|
1556
|
+
if exp > maxExp { // infinity and range error
|
|
1557
|
+
mantissa = uint64(1) << flt.mantbits
|
|
1558
|
+
exp = maxExp + 1
|
|
1559
|
+
err = ErrRange
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
bits := mantissa & (uint64(1)<<flt.mantbits - 1)
|
|
1563
|
+
bits |= uint64((exp-flt.bias)&(1<<flt.expbits-1)) << flt.mantbits
|
|
1564
|
+
if neg {
|
|
1565
|
+
bits |= uint64(1) << flt.mantbits << flt.expbits
|
|
1566
|
+
}
|
|
1567
|
+
if flt.mantbits == float32MantBits {
|
|
1568
|
+
return float64(math.Float32frombits(uint32(bits))), err
|
|
1569
|
+
}
|
|
1570
|
+
return math.Float64frombits(bits), err
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
const fnParseFloat = "ParseFloat"
|
|
1574
|
+
|
|
1575
|
+
func atof32(s string) (f float32, n int, err error) {
|
|
1576
|
+
if val, n, ok := special(s); ok {
|
|
1577
|
+
return float32(val), n, nil
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
mantissa, exp, neg, trunc, hex, n, ok := readFloat(s)
|
|
1581
|
+
if !ok {
|
|
1582
|
+
return 0, n, ErrSyntax
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
if hex {
|
|
1586
|
+
f, err := atofHex(s[:n], float32info(), mantissa, exp, neg, trunc)
|
|
1587
|
+
return float32(f), n, err
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
// Try pure floating-point arithmetic conversion.
|
|
1591
|
+
if !trunc {
|
|
1592
|
+
if f, ok := atof32exact(mantissa, exp, neg); ok {
|
|
1593
|
+
return f, n, nil
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
// Slow fallback.
|
|
1598
|
+
var d decimal
|
|
1599
|
+
if !d.set(s[:n]) {
|
|
1600
|
+
return 0, n, ErrSyntax
|
|
1601
|
+
}
|
|
1602
|
+
b, ovf := d.floatBits(float32info())
|
|
1603
|
+
f = math.Float32frombits(uint32(b))
|
|
1604
|
+
if ovf {
|
|
1605
|
+
err = ErrRange
|
|
1606
|
+
}
|
|
1607
|
+
return f, n, err
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
func atof64(s string) (f float64, n int, err error) {
|
|
1611
|
+
if val, n, ok := special(s); ok {
|
|
1612
|
+
return val, n, nil
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
mantissa, exp, neg, trunc, hex, n, ok := readFloat(s)
|
|
1616
|
+
if !ok {
|
|
1617
|
+
return 0, n, ErrSyntax
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
if hex {
|
|
1621
|
+
f, err := atofHex(s[:n], float64info(), mantissa, exp, neg, trunc)
|
|
1622
|
+
return f, n, err
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
// Try pure floating-point arithmetic conversion.
|
|
1626
|
+
if !trunc {
|
|
1627
|
+
if f, ok := atof64exact(mantissa, exp, neg); ok {
|
|
1628
|
+
return f, n, nil
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
// The host's correctly rounded conversion.
|
|
1633
|
+
f = parseDecimal(s[:n])
|
|
1634
|
+
if math.IsInf(f, 0) {
|
|
1635
|
+
err = ErrRange
|
|
1636
|
+
}
|
|
1637
|
+
return f, n, err
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
// parseDecimal is the float64 nearest to s, a decimal number already
|
|
1641
|
+
// checked for its syntax (underscores allowed).
|
|
1642
|
+
//
|
|
1643
|
+
//gofront:native strconv.parseDecimal
|
|
1644
|
+
func parseDecimal(s string) float64 {
|
|
1645
|
+
var d decimal
|
|
1646
|
+
d.set(s)
|
|
1647
|
+
b, _ := d.floatBits(float64info())
|
|
1648
|
+
return math.Float64frombits(b)
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
// ParseFloat converts the string s to a floating-point number
|
|
1652
|
+
// with the precision specified by bitSize: 32 for float32, or 64 for float64.
|
|
1653
|
+
// When bitSize=32, the result still has type float64, but it will be
|
|
1654
|
+
// convertible to float32 without changing its value.
|
|
1655
|
+
//
|
|
1656
|
+
// ParseFloat accepts decimal and hexadecimal floating-point numbers
|
|
1657
|
+
// as defined by the Go syntax for [floating-point literals].
|
|
1658
|
+
// If s is well-formed and near a valid floating-point number,
|
|
1659
|
+
// ParseFloat returns the nearest floating-point number rounded
|
|
1660
|
+
// using IEEE754 unbiased rounding.
|
|
1661
|
+
// (Parsing a hexadecimal floating-point value only rounds when
|
|
1662
|
+
// there are more bits in the hexadecimal representation than
|
|
1663
|
+
// will fit in the mantissa.)
|
|
1664
|
+
//
|
|
1665
|
+
// The errors that ParseFloat returns have concrete type *NumError
|
|
1666
|
+
// and include err.Num = s.
|
|
1667
|
+
//
|
|
1668
|
+
// If s is not syntactically well-formed, ParseFloat returns err.Err = ErrSyntax.
|
|
1669
|
+
//
|
|
1670
|
+
// If s is syntactically well-formed but is more than 1/2 ULP
|
|
1671
|
+
// away from the largest floating point number of the given size,
|
|
1672
|
+
// ParseFloat returns f = ±Inf, err.Err = ErrRange.
|
|
1673
|
+
//
|
|
1674
|
+
// ParseFloat recognizes the string "NaN", and the (possibly signed) strings "Inf" and "Infinity"
|
|
1675
|
+
// as their respective special floating point values. It ignores case when matching.
|
|
1676
|
+
//
|
|
1677
|
+
// [floating-point literals]: https://go.dev/ref/spec#Floating-point_literals
|
|
1678
|
+
func ParseFloat(s string, bitSize int) (float64, error) {
|
|
1679
|
+
f, n, err := parseFloatPrefix(s, bitSize)
|
|
1680
|
+
if n != len(s) {
|
|
1681
|
+
err = ErrSyntax
|
|
1682
|
+
f = 0
|
|
1683
|
+
}
|
|
1684
|
+
if err != nil {
|
|
1685
|
+
if err == ErrSyntax {
|
|
1686
|
+
return f, syntaxError("ParseFloat", s)
|
|
1687
|
+
}
|
|
1688
|
+
return f, rangeError("ParseFloat", s)
|
|
1689
|
+
}
|
|
1690
|
+
return f, nil
|
|
1691
|
+
}
|
|
1692
|
+
|
|
1693
|
+
func parseFloatPrefix(s string, bitSize int) (float64, int, error) {
|
|
1694
|
+
if bitSize == 32 {
|
|
1695
|
+
f, n, err := atof32(s)
|
|
1696
|
+
return float64(f), n, err
|
|
1697
|
+
}
|
|
1698
|
+
return atof64(s)
|
|
1699
|
+
}
|