v / vlib / strconv
Raw file | 255 loc (230 sloc) | 4.83 KB | Latest commit hash e3d98b1b2
1module strconv
2
3import math.bits
4
5// general utilities
6
7// General Utilities
8[if debug_strconv ?]
9fn assert1(t bool, msg string) {
10 if !t {
11 panic(msg)
12 }
13}
14
15[inline]
16fn bool_to_int(b bool) int {
17 if b {
18 return 1
19 }
20 return 0
21}
22
23[inline]
24fn bool_to_u32(b bool) u32 {
25 if b {
26 return u32(1)
27 }
28 return u32(0)
29}
30
31[inline]
32fn bool_to_u64(b bool) u64 {
33 if b {
34 return u64(1)
35 }
36 return u64(0)
37}
38
39fn get_string_special(neg bool, expZero bool, mantZero bool) string {
40 if !mantZero {
41 return 'nan'
42 }
43 if !expZero {
44 if neg {
45 return '-inf'
46 } else {
47 return '+inf'
48 }
49 }
50 if neg {
51 return '-0e+00'
52 }
53 return '0e+00'
54}
55
56/*
5732 bit functions
58*/
59
60fn mul_shift_32(m u32, mul u64, ishift int) u32 {
61 // QTODO
62 // assert ishift > 32
63
64 hi, lo := bits.mul_64(u64(m), mul)
65 shifted_sum := (lo >> u64(ishift)) + (hi << u64(64 - ishift))
66 assert1(shifted_sum <= 2147483647, 'shiftedSum <= math.max_u32')
67 return u32(shifted_sum)
68}
69
70fn mul_pow5_invdiv_pow2(m u32, q u32, j int) u32 {
71 return mul_shift_32(m, pow5_inv_split_32[q], j)
72}
73
74fn mul_pow5_div_pow2(m u32, i u32, j int) u32 {
75 return mul_shift_32(m, pow5_split_32[i], j)
76}
77
78fn pow5_factor_32(i_v u32) u32 {
79 mut v := i_v
80 for n := u32(0); true; n++ {
81 q := v / 5
82 r := v % 5
83 if r != 0 {
84 return n
85 }
86 v = q
87 }
88 return v
89}
90
91// multiple_of_power_of_five_32 reports whether v is divisible by 5^p.
92fn multiple_of_power_of_five_32(v u32, p u32) bool {
93 return pow5_factor_32(v) >= p
94}
95
96// multiple_of_power_of_two_32 reports whether v is divisible by 2^p.
97fn multiple_of_power_of_two_32(v u32, p u32) bool {
98 return u32(bits.trailing_zeros_32(v)) >= p
99}
100
101// log10_pow2 returns floor(log_10(2^e)).
102fn log10_pow2(e int) u32 {
103 // The first value this approximation fails for is 2^1651
104 // which is just greater than 10^297.
105 assert1(e >= 0, 'e >= 0')
106 assert1(e <= 1650, 'e <= 1650')
107 return (u32(e) * 78913) >> 18
108}
109
110// log10_pow5 returns floor(log_10(5^e)).
111fn log10_pow5(e int) u32 {
112 // The first value this approximation fails for is 5^2621
113 // which is just greater than 10^1832.
114 assert1(e >= 0, 'e >= 0')
115 assert1(e <= 2620, 'e <= 2620')
116 return (u32(e) * 732923) >> 20
117}
118
119// pow5_bits returns ceil(log_2(5^e)), or else 1 if e==0.
120fn pow5_bits(e int) int {
121 // This approximation works up to the point that the multiplication
122 // overflows at e = 3529. If the multiplication were done in 64 bits,
123 // it would fail at 5^4004 which is just greater than 2^9297.
124 assert1(e >= 0, 'e >= 0')
125 assert1(e <= 3528, 'e <= 3528')
126 return int(((u32(e) * 1217359) >> 19) + 1)
127}
128
129/*
13064 bit functions
131*/
132
133fn shift_right_128(v Uint128, shift int) u64 {
134 // The shift value is always modulo 64.
135 // In the current implementation of the 64-bit version
136 // of Ryu, the shift value is always < 64.
137 // (It is in the range [2, 59].)
138 // Check this here in case a future change requires larger shift
139 // values. In this case this function needs to be adjusted.
140 assert1(shift < 64, 'shift < 64')
141 return (v.hi << u64(64 - shift)) | (v.lo >> u32(shift))
142}
143
144fn mul_shift_64(m u64, mul Uint128, shift int) u64 {
145 hihi, hilo := bits.mul_64(m, mul.hi)
146 lohi, _ := bits.mul_64(m, mul.lo)
147 mut sum := Uint128{
148 lo: lohi + hilo
149 hi: hihi
150 }
151 if sum.lo < lohi {
152 sum.hi++ // overflow
153 }
154 return shift_right_128(sum, shift - 64)
155}
156
157fn pow5_factor_64(v_i u64) u32 {
158 mut v := v_i
159 for n := u32(0); true; n++ {
160 q := v / 5
161 r := v % 5
162 if r != 0 {
163 return n
164 }
165 v = q
166 }
167 return u32(0)
168}
169
170fn multiple_of_power_of_five_64(v u64, p u32) bool {
171 return pow5_factor_64(v) >= p
172}
173
174fn multiple_of_power_of_two_64(v u64, p u32) bool {
175 return u32(bits.trailing_zeros_64(v)) >= p
176}
177
178// dec_digits return the number of decimal digit of an u64
179pub fn dec_digits(n u64) int {
180 if n <= 9_999_999_999 { // 1-10
181 if n <= 99_999 { // 5
182 if n <= 99 { // 2
183 if n <= 9 { // 1
184 return 1
185 } else {
186 return 2
187 }
188 } else {
189 if n <= 999 { // 3
190 return 3
191 } else {
192 if n <= 9999 { // 4
193 return 4
194 } else {
195 return 5
196 }
197 }
198 }
199 } else {
200 if n <= 9_999_999 { // 7
201 if n <= 999_999 { // 6
202 return 6
203 } else {
204 return 7
205 }
206 } else {
207 if n <= 99_999_999 { // 8
208 return 8
209 } else {
210 if n <= 999_999_999 { // 9
211 return 9
212 }
213 return 10
214 }
215 }
216 }
217 } else {
218 if n <= 999_999_999_999_999 { // 5
219 if n <= 999_999_999_999 { // 2
220 if n <= 99_999_999_999 { // 1
221 return 11
222 } else {
223 return 12
224 }
225 } else {
226 if n <= 9_999_999_999_999 { // 3
227 return 13
228 } else {
229 if n <= 99_999_999_999_999 { // 4
230 return 14
231 } else {
232 return 15
233 }
234 }
235 }
236 } else {
237 if n <= 99_999_999_999_999_999 { // 7
238 if n <= 9_999_999_999_999_999 { // 6
239 return 16
240 } else {
241 return 17
242 }
243 } else {
244 if n <= 999_999_999_999_999_999 { // 8
245 return 18
246 } else {
247 if n <= 9_999_999_999_999_999_999 { // 9
248 return 19
249 }
250 return 20
251 }
252 }
253 }
254 }
255}