aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/strconv
diff options
context:
space:
mode:
authorIndrajith K L2022-12-03 17:00:20 +0530
committerIndrajith K L2022-12-03 17:00:20 +0530
commitf5c4671bfbad96bf346bd7e9a21fc4317b4959df (patch)
tree2764fc62da58f2ba8da7ed341643fc359873142f /v_windows/v/vlib/strconv
downloadcli-tools-windows-f5c4671bfbad96bf346bd7e9a21fc4317b4959df.tar.gz
cli-tools-windows-f5c4671bfbad96bf346bd7e9a21fc4317b4959df.tar.bz2
cli-tools-windows-f5c4671bfbad96bf346bd7e9a21fc4317b4959df.zip
Adds most of the toolsHEADmaster
Diffstat (limited to 'v_windows/v/vlib/strconv')
-rw-r--r--v_windows/v/vlib/strconv/atof.v441
-rw-r--r--v_windows/v/vlib/strconv/atof_test.v75
-rw-r--r--v_windows/v/vlib/strconv/atofq.v348
-rw-r--r--v_windows/v/vlib/strconv/atoi.v261
-rw-r--r--v_windows/v/vlib/strconv/atoi_test.v84
-rw-r--r--v_windows/v/vlib/strconv/f32_f64_to_string_test.v171
-rw-r--r--v_windows/v/vlib/strconv/f32_str.v377
-rw-r--r--v_windows/v/vlib/strconv/f64_str.v418
-rw-r--r--v_windows/v/vlib/strconv/format.md250
-rw-r--r--v_windows/v/vlib/strconv/format.v113
-rw-r--r--v_windows/v/vlib/strconv/format_mem.v498
-rw-r--r--v_windows/v/vlib/strconv/format_test.v110
-rw-r--r--v_windows/v/vlib/strconv/ftoa.v39
-rw-r--r--v_windows/v/vlib/strconv/number_to_base.v61
-rw-r--r--v_windows/v/vlib/strconv/number_to_base_test.v38
-rw-r--r--v_windows/v/vlib/strconv/structs.v55
-rw-r--r--v_windows/v/vlib/strconv/tables.v738
-rw-r--r--v_windows/v/vlib/strconv/utilities.v556
-rw-r--r--v_windows/v/vlib/strconv/vprintf.v726
19 files changed, 5359 insertions, 0 deletions
diff --git a/v_windows/v/vlib/strconv/atof.v b/v_windows/v/vlib/strconv/atof.v
new file mode 100644
index 0000000..dd994bd
--- /dev/null
+++ b/v_windows/v/vlib/strconv/atof.v
@@ -0,0 +1,441 @@
+module strconv
+
+/*
+atof util
+
+Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
+Use of this source code is governed by an MIT license
+that can be found in the LICENSE file.
+
+This file contains utilities for convert a string in a f64 variable
+IEEE 754 standard is used
+
+Know limitation:
+- limited to 18 significant digits
+
+The code is inspired by:
+Grzegorz Kraszewski krashan@teleinfo.pb.edu.pl
+URL: http://krashan.ppa.pl/articles/stringtofloat/
+Original license: MIT
+
+96 bit operation utilities
+Note: when u128 will be available these function can be refactored
+*/
+
+// right logical shift 96 bit
+fn lsr96(s2 u32, s1 u32, s0 u32) (u32, u32, u32) {
+ mut r0 := u32(0)
+ mut r1 := u32(0)
+ mut r2 := u32(0)
+ r0 = (s0 >> 1) | ((s1 & u32(1)) << 31)
+ r1 = (s1 >> 1) | ((s2 & u32(1)) << 31)
+ r2 = s2 >> 1
+ return r2, r1, r0
+}
+
+// left logical shift 96 bit
+fn lsl96(s2 u32, s1 u32, s0 u32) (u32, u32, u32) {
+ mut r0 := u32(0)
+ mut r1 := u32(0)
+ mut r2 := u32(0)
+ r2 = (s2 << 1) | ((s1 & (u32(1) << 31)) >> 31)
+ r1 = (s1 << 1) | ((s0 & (u32(1) << 31)) >> 31)
+ r0 = s0 << 1
+ return r2, r1, r0
+}
+
+// sum on 96 bit
+fn add96(s2 u32, s1 u32, s0 u32, d2 u32, d1 u32, d0 u32) (u32, u32, u32) {
+ mut w := u64(0)
+ mut r0 := u32(0)
+ mut r1 := u32(0)
+ mut r2 := u32(0)
+ w = u64(s0) + u64(d0)
+ r0 = u32(w)
+ w >>= 32
+ w += u64(s1) + u64(d1)
+ r1 = u32(w)
+ w >>= 32
+ w += u64(s2) + u64(d2)
+ r2 = u32(w)
+ return r2, r1, r0
+}
+
+// subtraction on 96 bit
+fn sub96(s2 u32, s1 u32, s0 u32, d2 u32, d1 u32, d0 u32) (u32, u32, u32) {
+ mut w := u64(0)
+ mut r0 := u32(0)
+ mut r1 := u32(0)
+ mut r2 := u32(0)
+ w = u64(s0) - u64(d0)
+ r0 = u32(w)
+ w >>= 32
+ w += u64(s1) - u64(d1)
+ r1 = u32(w)
+ w >>= 32
+ w += u64(s2) - u64(d2)
+ r2 = u32(w)
+ return r2, r1, r0
+}
+
+/*
+Constants
+*/
+
+pub const (
+ //
+ // f32 constants
+ //
+ single_plus_zero = u32(0x0000_0000)
+ single_minus_zero = u32(0x8000_0000)
+ single_plus_infinity = u32(0x7F80_0000)
+ single_minus_infinity = u32(0xFF80_0000)
+ //
+ // f64 constants
+ //
+ digits = 18
+ double_plus_zero = u64(0x0000000000000000)
+ double_minus_zero = u64(0x8000000000000000)
+ double_plus_infinity = u64(0x7FF0000000000000)
+ double_minus_infinity = u64(0xFFF0000000000000)
+ //
+ // Possible parser return values.
+ //
+ parser_ok = 0 // parser finished OK
+ parser_pzero = 1 // no digits or number is smaller than +-2^-1022
+ parser_mzero = 2 // number is negative, module smaller
+ parser_pinf = 3 // number is higher than +HUGE_VAL
+ parser_minf = 4 // number is lower than -HUGE_VAL
+ //
+ // char constants
+ // Note: Modify these if working with non-ASCII encoding
+ //
+ c_dpoint = `.`
+ c_plus = `+`
+ c_minus = `-`
+ c_zero = `0`
+ c_nine = `9`
+ c_ten = u32(10)
+)
+
+/*
+Utility
+*/
+
+// NOTE: Modify these if working with non-ASCII encoding
+fn is_digit(x byte) bool {
+ return (x >= strconv.c_zero && x <= strconv.c_nine) == true
+}
+
+fn is_space(x byte) bool {
+ return (x == `\t` || x == `\n` || x == `\v` || x == `\f` || x == `\r` || x == ` `)
+}
+
+fn is_exp(x byte) bool {
+ return (x == `E` || x == `e`) == true
+}
+
+/*
+Support struct
+*/
+
+/*
+String parser
+NOTE: #TOFIX need one char after the last char of the number
+*/
+
+fn parser(s string) (int, PrepNumber) {
+ mut digx := 0
+ mut result := strconv.parser_ok
+ mut expneg := false
+ mut expexp := 0
+ mut i := 0
+ mut pn := PrepNumber{}
+
+ // skip spaces
+ for i < s.len && s[i].is_space() {
+ i++
+ }
+
+ // check negatives
+ if s[i] == `-` {
+ pn.negative = true
+ i++
+ }
+
+ // positive sign ignore it
+ if s[i] == `+` {
+ i++
+ }
+
+ // read mantissa
+ for i < s.len && s[i].is_digit() {
+ // println("$i => ${s[i]}")
+ if digx < strconv.digits {
+ pn.mantissa *= 10
+ pn.mantissa += u64(s[i] - strconv.c_zero)
+ digx++
+ } else if pn.exponent < 2147483647 {
+ pn.exponent++
+ }
+ i++
+ }
+
+ // read mantissa decimals
+ if (i < s.len) && (s[i] == `.`) {
+ i++
+ for i < s.len && s[i].is_digit() {
+ if digx < strconv.digits {
+ pn.mantissa *= 10
+ pn.mantissa += u64(s[i] - strconv.c_zero)
+ pn.exponent--
+ digx++
+ }
+ i++
+ }
+ }
+
+ // read exponent
+ if (i < s.len) && ((s[i] == `e`) || (s[i] == `E`)) {
+ i++
+ if i < s.len {
+ // esponent sign
+ if s[i] == strconv.c_plus {
+ i++
+ } else if s[i] == strconv.c_minus {
+ expneg = true
+ i++
+ }
+
+ for i < s.len && s[i].is_digit() {
+ if expexp < 214748364 {
+ expexp *= 10
+ expexp += int(s[i] - strconv.c_zero)
+ }
+ i++
+ }
+ }
+ }
+
+ if expneg {
+ expexp = -expexp
+ }
+ pn.exponent += expexp
+ if pn.mantissa == 0 {
+ if pn.negative {
+ result = strconv.parser_mzero
+ } else {
+ result = strconv.parser_pzero
+ }
+ } else if pn.exponent > 309 {
+ if pn.negative {
+ result = strconv.parser_minf
+ } else {
+ result = strconv.parser_pinf
+ }
+ } else if pn.exponent < -328 {
+ if pn.negative {
+ result = strconv.parser_mzero
+ } else {
+ result = strconv.parser_pzero
+ }
+ }
+ return result, pn
+}
+
+/*
+Converter to the bit form of the f64 number
+*/
+
+// converter return a u64 with the bit image of the f64 number
+fn converter(mut pn PrepNumber) u64 {
+ mut binexp := 92
+ mut s2 := u32(0) // 96-bit precision integer
+ mut s1 := u32(0)
+ mut s0 := u32(0)
+ mut q2 := u32(0) // 96-bit precision integer
+ mut q1 := u32(0)
+ mut q0 := u32(0)
+ mut r2 := u32(0) // 96-bit precision integer
+ mut r1 := u32(0)
+ mut r0 := u32(0)
+ mask28 := u32(u64(0xF) << 28)
+ mut result := u64(0)
+ // working on 3 u32 to have 96 bit precision
+ s0 = u32(pn.mantissa & u64(0x00000000FFFFFFFF))
+ s1 = u32(pn.mantissa >> 32)
+ s2 = u32(0)
+ // so we take the decimal exponent off
+ for pn.exponent > 0 {
+ q2, q1, q0 = lsl96(s2, s1, s0) // q = s * 2
+ r2, r1, r0 = lsl96(q2, q1, q0) // r = s * 4 <=> q * 2
+ s2, s1, s0 = lsl96(r2, r1, r0) // s = s * 8 <=> r * 2
+ s2, s1, s0 = add96(s2, s1, s0, q2, q1, q0) // s = (s * 8) + (s * 2) <=> s*10
+ pn.exponent--
+ for (s2 & mask28) != 0 {
+ q2, q1, q0 = lsr96(s2, s1, s0)
+ binexp++
+ s2 = q2
+ s1 = q1
+ s0 = q0
+ }
+ }
+ for pn.exponent < 0 {
+ for !((s2 & (u32(1) << 31)) != 0) {
+ q2, q1, q0 = lsl96(s2, s1, s0)
+ binexp--
+ s2 = q2
+ s1 = q1
+ s0 = q0
+ }
+ q2 = s2 / strconv.c_ten
+ r1 = s2 % strconv.c_ten
+ r2 = (s1 >> 8) | (r1 << 24)
+ q1 = r2 / strconv.c_ten
+ r1 = r2 % strconv.c_ten
+ r2 = ((s1 & u32(0xFF)) << 16) | (s0 >> 16) | (r1 << 24)
+ r0 = r2 / strconv.c_ten
+ r1 = r2 % strconv.c_ten
+ q1 = (q1 << 8) | ((r0 & u32(0x00FF0000)) >> 16)
+ q0 = r0 << 16
+ r2 = (s0 & u32(0xFFFF)) | (r1 << 16)
+ q0 |= r2 / strconv.c_ten
+ s2 = q2
+ s1 = q1
+ s0 = q0
+ pn.exponent++
+ }
+ // C.printf("mantissa before normalization: %08x%08x%08x binexp: %d \n", s2,s1,s0,binexp)
+ // normalization, the 28 bit in s2 must the leftest one in the variable
+ if s2 != 0 || s1 != 0 || s0 != 0 {
+ for (s2 & mask28) == 0 {
+ q2, q1, q0 = lsl96(s2, s1, s0)
+ binexp--
+ s2 = q2
+ s1 = q1
+ s0 = q0
+ }
+ }
+ // rounding if needed
+ /*
+ * "round half to even" algorithm
+ * Example for f32, just a reminder
+ *
+ * If bit 54 is 0, round down
+ * If bit 54 is 1
+ * If any bit beyond bit 54 is 1, round up
+ * If all bits beyond bit 54 are 0 (meaning the number is halfway between two floating-point numbers)
+ * If bit 53 is 0, round down
+ * If bit 53 is 1, round up
+ */
+ /*
+ test case 1 complete
+ s2=0x1FFFFFFF
+ s1=0xFFFFFF80
+ s0=0x0
+ */
+
+ /*
+ test case 1 check_round_bit
+ s2=0x18888888
+ s1=0x88888880
+ s0=0x0
+ */
+
+ /*
+ test case check_round_bit + normalization
+ s2=0x18888888
+ s1=0x88888F80
+ s0=0x0
+ */
+
+ // C.printf("mantissa before rounding: %08x%08x%08x binexp: %d \n", s2,s1,s0,binexp)
+ // s1 => 0xFFFFFFxx only F are rapresented
+ nbit := 7
+ check_round_bit := u32(1) << u32(nbit)
+ check_round_mask := u32(0xFFFFFFFF) << u32(nbit)
+ if (s1 & check_round_bit) != 0 {
+ // C.printf("need round!! cehck mask: %08x\n", s1 & ~check_round_mask )
+ if (s1 & ~check_round_mask) != 0 {
+ // C.printf("Add 1!\n")
+ s2, s1, s0 = add96(s2, s1, s0, 0, check_round_bit, 0)
+ } else {
+ // C.printf("All 0!\n")
+ if (s1 & (check_round_bit << u32(1))) != 0 {
+ // C.printf("Add 1 form -1 bit control!\n")
+ s2, s1, s0 = add96(s2, s1, s0, 0, check_round_bit, 0)
+ }
+ }
+ s1 = s1 & check_round_mask
+ s0 = u32(0)
+ // recheck normalization
+ if s2 & (mask28 << u32(1)) != 0 {
+ // C.printf("Renormalize!!")
+ q2, q1, q0 = lsr96(s2, s1, s0)
+ binexp--
+ s2 = q2
+ s1 = q1
+ s0 = q0
+ }
+ }
+ // tmp := ( u64(s2 & ~mask28) << 24) | ((u64(s1) + u64(128)) >> 8)
+ // C.printf("mantissa after rounding : %08x%08x%08x binexp: %d \n", s2,s1,s0,binexp)
+ // C.printf("Tmp result: %016x\n",tmp)
+ // end rounding
+ // offset the binary exponent IEEE 754
+ binexp += 1023
+ if binexp > 2046 {
+ if pn.negative {
+ result = strconv.double_minus_infinity
+ } else {
+ result = strconv.double_plus_infinity
+ }
+ } else if binexp < 1 {
+ if pn.negative {
+ result = strconv.double_minus_zero
+ } else {
+ result = strconv.double_plus_zero
+ }
+ } else if s2 != 0 {
+ mut q := u64(0)
+ binexs2 := u64(binexp) << 52
+ q = (u64(s2 & ~mask28) << 24) | ((u64(s1) + u64(128)) >> 8) | binexs2
+ if pn.negative {
+ q |= (u64(1) << 63)
+ }
+ result = q
+ }
+ return result
+}
+
+/*
+Public functions
+*/
+
+// atof64 return a f64 from a string doing a parsing operation
+pub fn atof64(s string) f64 {
+ mut pn := PrepNumber{}
+ mut res_parsing := 0
+ mut res := Float64u{}
+
+ res_parsing, pn = parser(s)
+ match res_parsing {
+ strconv.parser_ok {
+ res.u = converter(mut pn)
+ }
+ strconv.parser_pzero {
+ res.u = strconv.double_plus_zero
+ }
+ strconv.parser_mzero {
+ res.u = strconv.double_minus_zero
+ }
+ strconv.parser_pinf {
+ res.u = strconv.double_plus_infinity
+ }
+ strconv.parser_minf {
+ res.u = strconv.double_minus_infinity
+ }
+ else {}
+ }
+ return unsafe { res.f }
+}
diff --git a/v_windows/v/vlib/strconv/atof_test.v b/v_windows/v/vlib/strconv/atof_test.v
new file mode 100644
index 0000000..ca286c8
--- /dev/null
+++ b/v_windows/v/vlib/strconv/atof_test.v
@@ -0,0 +1,75 @@
+import strconv
+
+/**********************************************************************
+*
+* String to float Test
+*
+**********************************************************************/
+
+fn test_atof() {
+ //
+ // test set
+ //
+
+ // float64
+ src_num := [
+ f64(0.3),
+ -0.3,
+ 0.004,
+ -0.004,
+ 0.0,
+ -0.0,
+ 31234567890123,
+ ]
+
+ // strings
+ src_num_str := [
+ '0.3',
+ '-0.3',
+ '0.004',
+ '-0.004',
+ '0.0',
+ '-0.0',
+ '31234567890123',
+ ]
+
+ // check conversion case 1 string <=> string
+ for c, x in src_num {
+ // slow atof
+ assert strconv.atof64(src_num_str[c]).strlong() == x.strlong()
+
+ // quick atof
+ mut s1 := (strconv.atof_quick(src_num_str[c]).str())
+ mut s2 := (x.str())
+ delta := s1.f64() - s2.f64()
+ // println("$s1 $s2 $delta")
+ assert delta < f64(1e-16)
+
+ // test C.atof
+ n1 := x.strsci(18)
+ n2 := f64(C.atof(&char(src_num_str[c].str))).strsci(18)
+ // println("$n1 $n2")
+ assert n1 == n2
+ }
+
+ // check conversion case 2 string <==> f64
+ // we don't test atof_quick beacuse we already know the rounding error
+ for c, x in src_num_str {
+ b := src_num[c].strlong()
+ a1 := strconv.atof64(x).strlong()
+ assert a1 == b
+ }
+
+ // special cases
+ mut f1 := f64(0.0)
+ mut ptr := unsafe { &u64(&f1) }
+ ptr = unsafe { &u64(&f1) }
+
+ // double_plus_zero
+ f1 = 0.0
+ assert *ptr == u64(0x0000000000000000)
+ // double_minus_zero
+ f1 = -0.0
+ assert *ptr == u64(0x8000000000000000)
+ println('DONE!')
+}
diff --git a/v_windows/v/vlib/strconv/atofq.v b/v_windows/v/vlib/strconv/atofq.v
new file mode 100644
index 0000000..07bb7b3
--- /dev/null
+++ b/v_windows/v/vlib/strconv/atofq.v
@@ -0,0 +1,348 @@
+module strconv
+
+/*
+atof util
+
+Copyright (c) 2019 Dario Deledda. All rights reserved.
+Use of this source code is governed by an MIT license
+that can be found in the LICENSE file.
+
+This file contains utilities for convert a string in a f64 variable in a very quick way
+IEEE 754 standard is used
+
+Know limitation:
+- round to 0 approximation
+- loos of precision with big exponents
+*/
+
+// atof_quick return a f64 number from a string in a quick way
+pub fn atof_quick(s string) f64 {
+ mut f := Float64u{} // result
+ mut sign := f64(1.0) // result sign
+ mut i := 0 // index
+ // skip white spaces
+ for i < s.len && s[i] == ` ` {
+ i++
+ }
+ // check sign
+ if i < s.len {
+ if s[i] == `-` {
+ sign = -1.0
+ i++
+ } else if s[i] == `+` {
+ i++
+ }
+ }
+ // infinite
+ if s[i] == `i` && i + 2 < s.len && s[i + 1] == `n` && s[i + 2] == `f` {
+ if sign > 0.0 {
+ f.u = double_plus_infinity
+ } else {
+ f.u = double_minus_infinity
+ }
+ return unsafe { f.f }
+ }
+ // skip zeros
+ for i < s.len && s[i] == `0` {
+ i++
+ // we have a zero, manage it
+ if i >= s.len {
+ if sign > 0.0 {
+ f.u = double_plus_zero
+ } else {
+ f.u = double_minus_zero
+ }
+ return unsafe { f.f }
+ }
+ }
+ // integer part
+ for i < s.len && (s[i] >= `0` && s[i] <= `9`) {
+ f.f *= f64(10.0)
+ f.f += f64(s[i] - `0`)
+ i++
+ }
+ // decimal point
+ if i < s.len && s[i] == `.` {
+ i++
+ mut frac_mul := f64(0.1)
+ for i < s.len && (s[i] >= `0` && s[i] <= `9`) {
+ f.f += f64(s[i] - `0`) * frac_mul
+ frac_mul *= f64(0.1)
+ i++
+ }
+ }
+ // exponent management
+ if i < s.len && (s[i] == `e` || s[i] == `E`) {
+ i++
+ mut exp := 0
+ mut exp_sign := 1
+ // negative exponent
+ if i < s.len {
+ if s[i] == `-` {
+ exp_sign = -1
+ i++
+ } else if s[i] == `+` {
+ i++
+ }
+ }
+ // skip zeros
+ for i < s.len && s[i] == `0` {
+ i++
+ }
+ for i < s.len && (s[i] >= `0` && s[i] <= `9`) {
+ exp *= 10
+ exp += int(s[i] - `0`)
+ i++
+ }
+ if exp_sign == 1 {
+ if exp > strconv.pos_exp.len {
+ if sign > 0 {
+ f.u = double_plus_infinity
+ } else {
+ f.u = double_minus_infinity
+ }
+ return unsafe { f.f }
+ }
+ tmp_mul := Float64u{
+ u: strconv.pos_exp[exp]
+ }
+ // C.printf("exp: %d [0x%016llx] %f,",exp,pos_exp[exp],tmp_mul)
+ f.f = unsafe { f.f * tmp_mul.f }
+ } else {
+ if exp > strconv.neg_exp.len {
+ if sign > 0 {
+ f.u = double_plus_zero
+ } else {
+ f.u = double_minus_zero
+ }
+ return unsafe { f.f }
+ }
+ tmp_mul := Float64u{
+ u: strconv.neg_exp[exp]
+ }
+
+ // C.printf("exp: %d [0x%016llx] %f,",exp,pos_exp[exp],tmp_mul)
+ f.f = unsafe { f.f * tmp_mul.f }
+ }
+ }
+ unsafe {
+ f.f = f.f * sign
+ return f.f
+ }
+}
+
+const (
+ // positive exp of 10 binary form
+ pos_exp = [u64(0x3ff0000000000000), u64(0x4024000000000000), u64(0x4059000000000000),
+ u64(0x408f400000000000), u64(0x40c3880000000000), u64(0x40f86a0000000000),
+ u64(0x412e848000000000), u64(0x416312d000000000), u64(0x4197d78400000000),
+ u64(0x41cdcd6500000000), u64(0x4202a05f20000000), u64(0x42374876e8000000),
+ u64(0x426d1a94a2000000), u64(0x42a2309ce5400000), u64(0x42d6bcc41e900000),
+ u64(0x430c6bf526340000), u64(0x4341c37937e08000), u64(0x4376345785d8a000),
+ u64(0x43abc16d674ec800), u64(0x43e158e460913d00), u64(0x4415af1d78b58c40),
+ u64(0x444b1ae4d6e2ef50), u64(0x4480f0cf064dd592), u64(0x44b52d02c7e14af6),
+ u64(0x44ea784379d99db4), u64(0x45208b2a2c280291), u64(0x4554adf4b7320335),
+ u64(0x4589d971e4fe8402), u64(0x45c027e72f1f1281), u64(0x45f431e0fae6d721),
+ u64(0x46293e5939a08cea), u64(0x465f8def8808b024), u64(0x4693b8b5b5056e17),
+ u64(0x46c8a6e32246c99c), u64(0x46fed09bead87c03), u64(0x4733426172c74d82),
+ u64(0x476812f9cf7920e3), u64(0x479e17b84357691b), u64(0x47d2ced32a16a1b1),
+ u64(0x48078287f49c4a1d), u64(0x483d6329f1c35ca5), u64(0x48725dfa371a19e7),
+ u64(0x48a6f578c4e0a061), u64(0x48dcb2d6f618c879), u64(0x4911efc659cf7d4c),
+ u64(0x49466bb7f0435c9e), u64(0x497c06a5ec5433c6), u64(0x49b18427b3b4a05c),
+ u64(0x49e5e531a0a1c873), u64(0x4a1b5e7e08ca3a8f), u64(0x4a511b0ec57e649a),
+ u64(0x4a8561d276ddfdc0), u64(0x4ababa4714957d30), u64(0x4af0b46c6cdd6e3e),
+ u64(0x4b24e1878814c9ce), u64(0x4b5a19e96a19fc41), u64(0x4b905031e2503da9),
+ u64(0x4bc4643e5ae44d13), u64(0x4bf97d4df19d6057), u64(0x4c2fdca16e04b86d),
+ u64(0x4c63e9e4e4c2f344), u64(0x4c98e45e1df3b015), u64(0x4ccf1d75a5709c1b),
+ u64(0x4d03726987666191), u64(0x4d384f03e93ff9f5), u64(0x4d6e62c4e38ff872),
+ u64(0x4da2fdbb0e39fb47), u64(0x4dd7bd29d1c87a19), u64(0x4e0dac74463a989f),
+ u64(0x4e428bc8abe49f64), u64(0x4e772ebad6ddc73d), u64(0x4eacfa698c95390c),
+ u64(0x4ee21c81f7dd43a7), u64(0x4f16a3a275d49491), u64(0x4f4c4c8b1349b9b5),
+ u64(0x4f81afd6ec0e1411), u64(0x4fb61bcca7119916), u64(0x4feba2bfd0d5ff5b),
+ u64(0x502145b7e285bf99), u64(0x50559725db272f7f), u64(0x508afcef51f0fb5f),
+ u64(0x50c0de1593369d1b), u64(0x50f5159af8044462), u64(0x512a5b01b605557b),
+ u64(0x516078e111c3556d), u64(0x5194971956342ac8), u64(0x51c9bcdfabc1357a),
+ u64(0x5200160bcb58c16c), u64(0x52341b8ebe2ef1c7), u64(0x526922726dbaae39),
+ u64(0x529f6b0f092959c7), u64(0x52d3a2e965b9d81d), u64(0x53088ba3bf284e24),
+ u64(0x533eae8caef261ad), u64(0x53732d17ed577d0c), u64(0x53a7f85de8ad5c4f),
+ u64(0x53ddf67562d8b363), u64(0x5412ba095dc7701e), u64(0x5447688bb5394c25),
+ u64(0x547d42aea2879f2e), u64(0x54b249ad2594c37d), u64(0x54e6dc186ef9f45c),
+ u64(0x551c931e8ab87173), u64(0x5551dbf316b346e8), u64(0x558652efdc6018a2),
+ u64(0x55bbe7abd3781eca), u64(0x55f170cb642b133f), u64(0x5625ccfe3d35d80e),
+ u64(0x565b403dcc834e12), u64(0x569108269fd210cb), u64(0x56c54a3047c694fe),
+ u64(0x56fa9cbc59b83a3d), u64(0x5730a1f5b8132466), u64(0x5764ca732617ed80),
+ u64(0x5799fd0fef9de8e0), u64(0x57d03e29f5c2b18c), u64(0x58044db473335def),
+ u64(0x583961219000356b), u64(0x586fb969f40042c5), u64(0x58a3d3e2388029bb),
+ u64(0x58d8c8dac6a0342a), u64(0x590efb1178484135), u64(0x59435ceaeb2d28c1),
+ u64(0x59783425a5f872f1), u64(0x59ae412f0f768fad), u64(0x59e2e8bd69aa19cc),
+ u64(0x5a17a2ecc414a03f), u64(0x5a4d8ba7f519c84f), u64(0x5a827748f9301d32),
+ u64(0x5ab7151b377c247e), u64(0x5aecda62055b2d9e), u64(0x5b22087d4358fc82),
+ u64(0x5b568a9c942f3ba3), u64(0x5b8c2d43b93b0a8c), u64(0x5bc19c4a53c4e697),
+ u64(0x5bf6035ce8b6203d), u64(0x5c2b843422e3a84d), u64(0x5c6132a095ce4930),
+ u64(0x5c957f48bb41db7c), u64(0x5ccadf1aea12525b), u64(0x5d00cb70d24b7379),
+ u64(0x5d34fe4d06de5057), u64(0x5d6a3de04895e46d), u64(0x5da066ac2d5daec4),
+ u64(0x5dd4805738b51a75), u64(0x5e09a06d06e26112), u64(0x5e400444244d7cab),
+ u64(0x5e7405552d60dbd6), u64(0x5ea906aa78b912cc), u64(0x5edf485516e7577f),
+ u64(0x5f138d352e5096af), u64(0x5f48708279e4bc5b), u64(0x5f7e8ca3185deb72),
+ u64(0x5fb317e5ef3ab327), u64(0x5fe7dddf6b095ff1), u64(0x601dd55745cbb7ed),
+ u64(0x6052a5568b9f52f4), u64(0x60874eac2e8727b1), u64(0x60bd22573a28f19d),
+ u64(0x60f2357684599702), u64(0x6126c2d4256ffcc3), u64(0x615c73892ecbfbf4),
+ u64(0x6191c835bd3f7d78), u64(0x61c63a432c8f5cd6), u64(0x61fbc8d3f7b3340c),
+ u64(0x62315d847ad00087), u64(0x6265b4e5998400a9), u64(0x629b221effe500d4),
+ u64(0x62d0f5535fef2084), u64(0x630532a837eae8a5), u64(0x633a7f5245e5a2cf),
+ u64(0x63708f936baf85c1), u64(0x63a4b378469b6732), u64(0x63d9e056584240fe),
+ u64(0x64102c35f729689f), u64(0x6444374374f3c2c6), u64(0x647945145230b378),
+ u64(0x64af965966bce056), u64(0x64e3bdf7e0360c36), u64(0x6518ad75d8438f43),
+ u64(0x654ed8d34e547314), u64(0x6583478410f4c7ec), u64(0x65b819651531f9e8),
+ u64(0x65ee1fbe5a7e7861), u64(0x6622d3d6f88f0b3d), u64(0x665788ccb6b2ce0c),
+ u64(0x668d6affe45f818f), u64(0x66c262dfeebbb0f9), u64(0x66f6fb97ea6a9d38),
+ u64(0x672cba7de5054486), u64(0x6761f48eaf234ad4), u64(0x679671b25aec1d89),
+ u64(0x67cc0e1ef1a724eb), u64(0x680188d357087713), u64(0x6835eb082cca94d7),
+ u64(0x686b65ca37fd3a0d), u64(0x68a11f9e62fe4448), u64(0x68d56785fbbdd55a),
+ u64(0x690ac1677aad4ab1), u64(0x6940b8e0acac4eaf), u64(0x6974e718d7d7625a),
+ u64(0x69aa20df0dcd3af1), u64(0x69e0548b68a044d6), u64(0x6a1469ae42c8560c),
+ u64(0x6a498419d37a6b8f), u64(0x6a7fe52048590673), u64(0x6ab3ef342d37a408),
+ u64(0x6ae8eb0138858d0a), u64(0x6b1f25c186a6f04c), u64(0x6b537798f4285630),
+ u64(0x6b88557f31326bbb), u64(0x6bbe6adefd7f06aa), u64(0x6bf302cb5e6f642a),
+ u64(0x6c27c37e360b3d35), u64(0x6c5db45dc38e0c82), u64(0x6c9290ba9a38c7d1),
+ u64(0x6cc734e940c6f9c6), u64(0x6cfd022390f8b837), u64(0x6d3221563a9b7323),
+ u64(0x6d66a9abc9424feb), u64(0x6d9c5416bb92e3e6), u64(0x6dd1b48e353bce70),
+ u64(0x6e0621b1c28ac20c), u64(0x6e3baa1e332d728f), u64(0x6e714a52dffc6799),
+ u64(0x6ea59ce797fb817f), u64(0x6edb04217dfa61df), u64(0x6f10e294eebc7d2c),
+ u64(0x6f451b3a2a6b9c76), u64(0x6f7a6208b5068394), u64(0x6fb07d457124123d),
+ u64(0x6fe49c96cd6d16cc), u64(0x7019c3bc80c85c7f), u64(0x70501a55d07d39cf),
+ u64(0x708420eb449c8843), u64(0x70b9292615c3aa54), u64(0x70ef736f9b3494e9),
+ u64(0x7123a825c100dd11), u64(0x7158922f31411456), u64(0x718eb6bafd91596b),
+ u64(0x71c33234de7ad7e3), u64(0x71f7fec216198ddc), u64(0x722dfe729b9ff153),
+ u64(0x7262bf07a143f6d4), u64(0x72976ec98994f489), u64(0x72cd4a7bebfa31ab),
+ u64(0x73024e8d737c5f0b), u64(0x7336e230d05b76cd), u64(0x736c9abd04725481),
+ u64(0x73a1e0b622c774d0), u64(0x73d658e3ab795204), u64(0x740bef1c9657a686),
+ u64(0x74417571ddf6c814), u64(0x7475d2ce55747a18), u64(0x74ab4781ead1989e),
+ u64(0x74e10cb132c2ff63), u64(0x75154fdd7f73bf3c), u64(0x754aa3d4df50af0b),
+ u64(0x7580a6650b926d67), u64(0x75b4cffe4e7708c0), u64(0x75ea03fde214caf1),
+ u64(0x7620427ead4cfed6), u64(0x7654531e58a03e8c), u64(0x768967e5eec84e2f),
+ u64(0x76bfc1df6a7a61bb), u64(0x76f3d92ba28c7d15), u64(0x7728cf768b2f9c5a),
+ u64(0x775f03542dfb8370), u64(0x779362149cbd3226), u64(0x77c83a99c3ec7eb0),
+ u64(0x77fe494034e79e5c), u64(0x7832edc82110c2f9), u64(0x7867a93a2954f3b8),
+ u64(0x789d9388b3aa30a5), u64(0x78d27c35704a5e67), u64(0x79071b42cc5cf601),
+ u64(0x793ce2137f743382), u64(0x79720d4c2fa8a031), u64(0x79a6909f3b92c83d),
+ u64(0x79dc34c70a777a4d), u64(0x7a11a0fc668aac70), u64(0x7a46093b802d578c),
+ u64(0x7a7b8b8a6038ad6f), u64(0x7ab137367c236c65), u64(0x7ae585041b2c477f),
+ u64(0x7b1ae64521f7595e), u64(0x7b50cfeb353a97db), u64(0x7b8503e602893dd2),
+ u64(0x7bba44df832b8d46), u64(0x7bf06b0bb1fb384c), u64(0x7c2485ce9e7a065f),
+ u64(0x7c59a742461887f6), u64(0x7c9008896bcf54fa), u64(0x7cc40aabc6c32a38),
+ u64(0x7cf90d56b873f4c7), u64(0x7d2f50ac6690f1f8), u64(0x7d63926bc01a973b),
+ u64(0x7d987706b0213d0a), u64(0x7dce94c85c298c4c), u64(0x7e031cfd3999f7b0),
+ u64(0x7e37e43c8800759c), u64(0x7e6ddd4baa009303), u64(0x7ea2aa4f4a405be2),
+ u64(0x7ed754e31cd072da), u64(0x7f0d2a1be4048f90), u64(0x7f423a516e82d9ba),
+ u64(0x7f76c8e5ca239029), u64(0x7fac7b1f3cac7433), u64(0x7fe1ccf385ebc8a0)]
+ // negative exp of 10 binary form
+ neg_exp = [u64(0x3ff0000000000000), u64(0x3fb999999999999a), u64(0x3f847ae147ae147b),
+ u64(0x3f50624dd2f1a9fc), u64(0x3f1a36e2eb1c432d), u64(0x3ee4f8b588e368f1),
+ u64(0x3eb0c6f7a0b5ed8d), u64(0x3e7ad7f29abcaf48), u64(0x3e45798ee2308c3a),
+ u64(0x3e112e0be826d695), u64(0x3ddb7cdfd9d7bdbb), u64(0x3da5fd7fe1796495),
+ u64(0x3d719799812dea11), u64(0x3d3c25c268497682), u64(0x3d06849b86a12b9b),
+ u64(0x3cd203af9ee75616), u64(0x3c9cd2b297d889bc), u64(0x3c670ef54646d497),
+ u64(0x3c32725dd1d243ac), u64(0x3bfd83c94fb6d2ac), u64(0x3bc79ca10c924223),
+ u64(0x3b92e3b40a0e9b4f), u64(0x3b5e392010175ee6), u64(0x3b282db34012b251),
+ u64(0x3af357c299a88ea7), u64(0x3abef2d0f5da7dd9), u64(0x3a88c240c4aecb14),
+ u64(0x3a53ce9a36f23c10), u64(0x3a1fb0f6be506019), u64(0x39e95a5efea6b347),
+ u64(0x39b4484bfeebc2a0), u64(0x398039d665896880), u64(0x3949f623d5a8a733),
+ u64(0x3914c4e977ba1f5c), u64(0x38e09d8792fb4c49), u64(0x38aa95a5b7f87a0f),
+ u64(0x38754484932d2e72), u64(0x3841039d428a8b8f), u64(0x380b38fb9daa78e4),
+ u64(0x37d5c72fb1552d83), u64(0x37a16c262777579c), u64(0x376be03d0bf225c7),
+ u64(0x37364cfda3281e39), u64(0x3701d7314f534b61), u64(0x36cc8b8218854567),
+ u64(0x3696d601ad376ab9), u64(0x366244ce242c5561), u64(0x362d3ae36d13bbce),
+ u64(0x35f7624f8a762fd8), u64(0x35c2b50c6ec4f313), u64(0x358dee7a4ad4b81f),
+ u64(0x3557f1fb6f10934c), u64(0x352327fc58da0f70), u64(0x34eea6608e29b24d),
+ u64(0x34b8851a0b548ea4), u64(0x34839dae6f76d883), u64(0x344f62b0b257c0d2),
+ u64(0x34191bc08eac9a41), u64(0x33e41633a556e1ce), u64(0x33b011c2eaabe7d8),
+ u64(0x3379b604aaaca626), u64(0x3344919d5556eb52), u64(0x3310747ddddf22a8),
+ u64(0x32da53fc9631d10d), u64(0x32a50ffd44f4a73d), u64(0x3270d9976a5d5297),
+ u64(0x323af5bf109550f2), u64(0x32059165a6ddda5b), u64(0x31d1411e1f17e1e3),
+ u64(0x319b9b6364f30304), u64(0x316615e91d8f359d), u64(0x3131ab20e472914a),
+ u64(0x30fc45016d841baa), u64(0x30c69d9abe034955), u64(0x309217aefe690777),
+ u64(0x305cf2b1970e7258), u64(0x3027288e1271f513), u64(0x2ff286d80ec190dc),
+ u64(0x2fbda48ce468e7c7), u64(0x2f87b6d71d20b96c), u64(0x2f52f8ac174d6123),
+ u64(0x2f1e5aacf2156838), u64(0x2ee8488a5b445360), u64(0x2eb36d3b7c36a91a),
+ u64(0x2e7f152bf9f10e90), u64(0x2e48ddbcc7f40ba6), u64(0x2e13e497065cd61f),
+ u64(0x2ddfd424d6faf031), u64(0x2da97683df2f268d), u64(0x2d745ecfe5bf520b),
+ u64(0x2d404bd984990e6f), u64(0x2d0a12f5a0f4e3e5), u64(0x2cd4dbf7b3f71cb7),
+ u64(0x2ca0aff95cc5b092), u64(0x2c6ab328946f80ea), u64(0x2c355c2076bf9a55),
+ u64(0x2c0116805effaeaa), u64(0x2bcb5733cb32b111), u64(0x2b95df5ca28ef40d),
+ u64(0x2b617f7d4ed8c33e), u64(0x2b2bff2ee48e0530), u64(0x2af665bf1d3e6a8d),
+ u64(0x2ac1eaff4a98553d), u64(0x2a8cab3210f3bb95), u64(0x2a56ef5b40c2fc77),
+ u64(0x2a225915cd68c9f9), u64(0x29ed5b561574765b), u64(0x29b77c44ddf6c516),
+ u64(0x2982c9d0b1923745), u64(0x294e0fb44f50586e), u64(0x29180c903f7379f2),
+ u64(0x28e33d4032c2c7f5), u64(0x28aec866b79e0cba), u64(0x2878a0522c7e7095),
+ u64(0x2843b374f06526de), u64(0x280f8587e7083e30), u64(0x27d9379fec069826),
+ u64(0x27a42c7ff0054685), u64(0x277023998cd10537), u64(0x2739d28f47b4d525),
+ u64(0x2704a8729fc3ddb7), u64(0x26d086c219697e2c), u64(0x269a71368f0f3047),
+ u64(0x2665275ed8d8f36c), u64(0x2630ec4be0ad8f89), u64(0x25fb13ac9aaf4c0f),
+ u64(0x25c5a956e225d672), u64(0x2591544581b7dec2), u64(0x255bba08cf8c979d),
+ u64(0x25262e6d72d6dfb0), u64(0x24f1bebdf578b2f4), u64(0x24bc6463225ab7ec),
+ u64(0x2486b6b5b5155ff0), u64(0x24522bc490dde65a), u64(0x241d12d41afca3c3),
+ u64(0x23e7424348ca1c9c), u64(0x23b29b69070816e3), u64(0x237dc574d80cf16b),
+ u64(0x2347d12a4670c123), u64(0x23130dbb6b8d674f), u64(0x22de7c5f127bd87e),
+ u64(0x22a8637f41fcad32), u64(0x227382cc34ca2428), u64(0x223f37ad21436d0c),
+ u64(0x2208f9574dcf8a70), u64(0x21d3faac3e3fa1f3), u64(0x219ff779fd329cb9),
+ u64(0x216992c7fdc216fa), u64(0x2134756ccb01abfb), u64(0x21005df0a267bcc9),
+ u64(0x20ca2fe76a3f9475), u64(0x2094f31f8832dd2a), u64(0x2060c27fa028b0ef),
+ u64(0x202ad0cc33744e4b), u64(0x1ff573d68f903ea2), u64(0x1fc1297872d9cbb5),
+ u64(0x1f8b758d848fac55), u64(0x1f55f7a46a0c89dd), u64(0x1f2192e9ee706e4b),
+ u64(0x1eec1e43171a4a11), u64(0x1eb67e9c127b6e74), u64(0x1e81fee341fc585d),
+ u64(0x1e4ccb0536608d61), u64(0x1e1708d0f84d3de7), u64(0x1de26d73f9d764b9),
+ u64(0x1dad7becc2f23ac2), u64(0x1d779657025b6235), u64(0x1d42deac01e2b4f7),
+ u64(0x1d0e3113363787f2), u64(0x1cd8274291c6065b), u64(0x1ca3529ba7d19eaf),
+ u64(0x1c6eea92a61c3118), u64(0x1c38bba884e35a7a), u64(0x1c03c9539d82aec8),
+ u64(0x1bcfa885c8d117a6), u64(0x1b99539e3a40dfb8), u64(0x1b6442e4fb671960),
+ u64(0x1b303583fc527ab3), u64(0x1af9ef3993b72ab8), u64(0x1ac4bf6142f8eefa),
+ u64(0x1a90991a9bfa58c8), u64(0x1a5a8e90f9908e0d), u64(0x1a253eda614071a4),
+ u64(0x19f0ff151a99f483), u64(0x19bb31bb5dc320d2), u64(0x1985c162b168e70e),
+ u64(0x1951678227871f3e), u64(0x191bd8d03f3e9864), u64(0x18e6470cff6546b6),
+ u64(0x18b1d270cc51055f), u64(0x187c83e7ad4e6efe), u64(0x1846cfec8aa52598),
+ u64(0x18123ff06eea847a), u64(0x17dd331a4b10d3f6), u64(0x17a75c1508da432b),
+ u64(0x1772b010d3e1cf56), u64(0x173de6815302e556), u64(0x1707eb9aa8cf1dde),
+ u64(0x16d322e220a5b17e), u64(0x169e9e369aa2b597), u64(0x16687e92154ef7ac),
+ u64(0x16339874ddd8c623), u64(0x15ff5a549627a36c), u64(0x15c91510781fb5f0),
+ u64(0x159410d9f9b2f7f3), u64(0x15600d7b2e28c65c), u64(0x1529af2b7d0e0a2d),
+ u64(0x14f48c22ca71a1bd), u64(0x14c0701bd527b498), u64(0x148a4cf9550c5426),
+ u64(0x14550a6110d6a9b8), u64(0x1420d51a73deee2d), u64(0x13eaee90b964b047),
+ u64(0x13b58ba6fab6f36c), u64(0x13813c85955f2923), u64(0x134b9408eefea839),
+ u64(0x1316100725988694), u64(0x12e1a66c1e139edd), u64(0x12ac3d79c9b8fe2e),
+ u64(0x12769794a160cb58), u64(0x124212dd4de70913), u64(0x120ceafbafd80e85),
+ u64(0x11d72262f3133ed1), u64(0x11a281e8c275cbda), u64(0x116d9ca79d89462a),
+ u64(0x1137b08617a104ee), u64(0x1102f39e794d9d8b), u64(0x10ce5297287c2f45),
+ u64(0x1098421286c9bf6b), u64(0x1063680ed23aff89), u64(0x102f0ce4839198db),
+ u64(0x0ff8d71d360e13e2), u64(0x0fc3df4a91a4dcb5), u64(0x0f8fcbaa82a16121),
+ u64(0x0f596fbb9bb44db4), u64(0x0f245962e2f6a490), u64(0x0ef047824f2bb6da),
+ u64(0x0eba0c03b1df8af6), u64(0x0e84d6695b193bf8), u64(0x0e50ab877c142ffa),
+ u64(0x0e1aac0bf9b9e65c), u64(0x0de5566ffafb1eb0), u64(0x0db111f32f2f4bc0),
+ u64(0x0d7b4feb7eb212cd), u64(0x0d45d98932280f0a), u64(0x0d117ad428200c08),
+ u64(0x0cdbf7b9d9cce00d), u64(0x0ca65fc7e170b33e), u64(0x0c71e6398126f5cb),
+ u64(0x0c3ca38f350b22df), u64(0x0c06e93f5da2824c), u64(0x0bd25432b14ecea3),
+ u64(0x0b9d53844ee47dd1), u64(0x0b677603725064a8), u64(0x0b32c4cf8ea6b6ec),
+ u64(0x0afe07b27dd78b14), u64(0x0ac8062864ac6f43), u64(0x0a9338205089f29c),
+ u64(0x0a5ec033b40fea93), u64(0x0a2899c2f6732210), u64(0x09f3ae3591f5b4d9),
+ u64(0x09bf7d228322baf5), u64(0x098930e868e89591), u64(0x0954272053ed4474),
+ u64(0x09201f4d0ff10390), u64(0x08e9cbae7fe805b3), u64(0x08b4a2f1ffecd15c),
+ u64(0x0880825b3323dab0), u64(0x084a6a2b85062ab3), u64(0x081521bc6a6b555c),
+ u64(0x07e0e7c9eebc444a), u64(0x07ab0c764ac6d3a9), u64(0x0775a391d56bdc87),
+ u64(0x07414fa7ddefe3a0), u64(0x070bb2a62fe638ff), u64(0x06d62884f31e93ff),
+ u64(0x06a1ba03f5b21000), u64(0x066c5cd322b67fff), u64(0x0636b0a8e891ffff),
+ u64(0x060226ed86db3333), u64(0x05cd0b15a491eb84), u64(0x05973c115074bc6a),
+ u64(0x05629674405d6388), u64(0x052dbd86cd6238d9), u64(0x04f7cad23de82d7b),
+ u64(0x04c308a831868ac9), u64(0x048e74404f3daadb), u64(0x04585d003f6488af),
+ u64(0x04237d99cc506d59), u64(0x03ef2f5c7a1a488e), u64(0x03b8f2b061aea072),
+ u64(0x0383f559e7bee6c1), u64(0x034feef63f97d79c), u64(0x03198bf832dfdfb0),
+ u64(0x02e46ff9c24cb2f3), u64(0x02b059949b708f29), u64(0x027a28edc580e50e),
+ u64(0x0244ed8b04671da5), u64(0x0210be08d0527e1d), u64(0x01dac9a7b3b7302f),
+ u64(0x01a56e1fc2f8f359), u64(0x017124e63593f5e1), u64(0x013b6e3d22865634),
+ u64(0x0105f1ca820511c3), u64(0x00d18e3b9b374169), u64(0x009c16c5c5253575),
+ u64(0x0066789e3750f791), u64(0x0031fa182c40c60d), u64(0x000730d67819e8d2),
+ u64(0x0000b8157268fdaf), u64(0x000012688b70e62b), u64(0x000001d74124e3d1),
+ u64(0x0000002f201d49fb), u64(0x00000004b6695433), u64(0x0000000078a42205),
+ u64(0x000000000c1069cd), u64(0x000000000134d761), u64(0x00000000001ee257),
+ u64(0x00000000000316a2), u64(0x0000000000004f10), u64(0x00000000000007e8),
+ u64(0x00000000000000ca), u64(0x0000000000000014), u64(0x0000000000000002)]
+)
diff --git a/v_windows/v/vlib/strconv/atoi.v b/v_windows/v/vlib/strconv/atoi.v
new file mode 100644
index 0000000..3334919
--- /dev/null
+++ b/v_windows/v/vlib/strconv/atoi.v
@@ -0,0 +1,261 @@
+module strconv
+
+// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
+// Use of this source code is governed by an MIT license
+// that can be found in the LICENSE file.
+// TODO: use optionals, or some way to return default with error.
+const (
+ // int_size is the size in bits of an int or uint value.
+ // int_size = 32 << (~u32(0) >> 63)
+ // max_u64 = u64(u64(1 << 63) - 1)
+ int_size = 32
+ max_u64 = u64(18446744073709551615) // as u64 // use this until we add support
+)
+
+pub fn byte_to_lower(c byte) byte {
+ return c | (`x` - `X`)
+}
+
+// common_parse_uint is called by parse_uint and allows the parsing
+// to stop on non or invalid digit characters and return with an error
+pub fn common_parse_uint(s string, _base int, _bit_size int, error_on_non_digit bool, error_on_high_digit bool) ?u64 {
+ result, err := common_parse_uint2(s, _base, _bit_size)
+ // TODO: error_on_non_digit and error_on_high_digit have no difference
+ if err != 0 && (error_on_non_digit || error_on_high_digit) {
+ match err {
+ -1 { return error('common_parse_uint: wrong base $_base for $s') }
+ -2 { return error('common_parse_uint: wrong bit size $_bit_size for $s') }
+ -3 { return error('common_parse_uint: integer overflow $s') }
+ else { return error('common_parse_uint: syntax error $s') }
+ }
+ }
+ return result
+}
+
+// the first returned value contains the parsed value,
+// the second returned value contains the error code (0 = OK, >1 = index of first non-parseable character + 1, -1 = wrong base, -2 = wrong bit size, -3 = overflow)
+pub fn common_parse_uint2(s string, _base int, _bit_size int) (u64, int) {
+ mut bit_size := _bit_size
+ mut base := _base
+ if s.len < 1 || !underscore_ok(s) {
+ // return error('parse_uint: syntax error $s')
+ return u64(0), 1
+ }
+ base0 := base == 0
+ mut start_index := 0
+ if 2 <= base && base <= 36 {
+ // valid base; nothing to do
+ } else if base == 0 {
+ // Look for octal, hex prefix.
+ base = 10
+ if s[0] == `0` {
+ if s.len >= 3 && byte_to_lower(s[1]) == `b` {
+ base = 2
+ start_index += 2
+ } else if s.len >= 3 && byte_to_lower(s[1]) == `o` {
+ base = 8
+ start_index += 2
+ } else if s.len >= 3 && byte_to_lower(s[1]) == `x` {
+ base = 16
+ start_index += 2
+ }
+ // manage leading zeros in decimal base's numbers
+ else if s.len >= 2 && (s[1] >= `0` && s[1] <= `9`) {
+ base = 10
+ start_index++
+ } else {
+ base = 8
+ start_index++
+ }
+ }
+ } else {
+ // return error('parse_uint: base error $s - $base')
+ return u64(0), -1
+ }
+ if bit_size == 0 {
+ bit_size = strconv.int_size
+ } else if bit_size < 0 || bit_size > 64 {
+ // return error('parse_uint: bitsize error $s - $bit_size')
+ return u64(0), -2
+ }
+ // Cutoff is the smallest number such that cutoff*base > maxUint64.
+ // Use compile-time constants for common cases.
+ cutoff := strconv.max_u64 / u64(base) + u64(1)
+ max_val := if bit_size == 64 { strconv.max_u64 } else { (u64(1) << u64(bit_size)) - u64(1) }
+ mut n := u64(0)
+ for i in start_index .. s.len {
+ c := s[i]
+ cl := byte_to_lower(c)
+ mut d := byte(0)
+ if c == `_` && base0 {
+ // underscore_ok already called
+ continue
+ } else if `0` <= c && c <= `9` {
+ d = c - `0`
+ } else if `a` <= cl && cl <= `z` {
+ d = cl - `a` + 10
+ } else {
+ return n, i + 1
+ }
+ if d >= byte(base) {
+ return n, i + 1
+ }
+ if n >= cutoff {
+ // n*base overflows
+ // return error('parse_uint: range error $s')
+ return max_val, -3
+ }
+ n *= u64(base)
+ n1 := n + u64(d)
+ if n1 < n || n1 > max_val {
+ // n+v overflows
+ // return error('parse_uint: range error $s')
+ return max_val, -3
+ }
+ n = n1
+ }
+ return n, 0
+}
+
+// parse_uint is like parse_int but for unsigned numbers.
+pub fn parse_uint(s string, _base int, _bit_size int) ?u64 {
+ return common_parse_uint(s, _base, _bit_size, true, true)
+}
+
+// common_parse_int is called by parse int and allows the parsing
+// to stop on non or invalid digit characters and return with an error
+pub fn common_parse_int(_s string, base int, _bit_size int, error_on_non_digit bool, error_on_high_digit bool) ?i64 {
+ mut s := _s
+ mut bit_size := _bit_size
+ if s.len < 1 {
+ // return error('parse_int: syntax error $s')
+ return i64(0)
+ }
+ // Pick off leading sign.
+ mut neg := false
+ if s[0] == `+` {
+ s = s[1..]
+ } else if s[0] == `-` {
+ neg = true
+ s = s[1..]
+ }
+ // Convert unsigned and check range.
+ // un := parse_uint(s, base, bit_size) or {
+ // return i64(0)
+ // }
+ un := common_parse_uint(s, base, bit_size, error_on_non_digit, error_on_high_digit) ?
+ if un == 0 {
+ return i64(0)
+ }
+ if bit_size == 0 {
+ bit_size = strconv.int_size
+ }
+ // TODO: check should u64(bit_size-1) be size of int (32)?
+ cutoff := u64(1) << u64(bit_size - 1)
+ if !neg && un >= cutoff {
+ // return error('parse_int: range error $s0')
+ return i64(cutoff - u64(1))
+ }
+ if neg && un > cutoff {
+ // return error('parse_int: range error $s0')
+ return -i64(cutoff)
+ }
+ return if neg { -i64(un) } else { i64(un) }
+}
+
+// parse_int interprets a string s in the given base (0, 2 to 36) and
+// bit size (0 to 64) and returns the corresponding value i.
+//
+// If the base argument is 0, the true base is implied by the string's
+// prefix: 2 for "0b", 8 for "0" or "0o", 16 for "0x", and 10 otherwise.
+// Also, for argument base 0 only, underscore characters are permitted
+// as defined by the Go syntax for integer literals.
+//
+// The bitSize argument specifies the integer type
+// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64
+// correspond to int, int8, int16, int32, and int64.
+// If bitSize is below 0 or above 64, an error is returned.
+pub fn parse_int(_s string, base int, _bit_size int) ?i64 {
+ return common_parse_int(_s, base, _bit_size, true, true)
+}
+
+// atoi is equivalent to parse_int(s, 10, 0), converted to type int.
+pub fn atoi(s string) ?int {
+ if s == '' {
+ return error('strconv.atoi: parsing "$s": invalid syntax ')
+ }
+ if (strconv.int_size == 32 && (0 < s.len && s.len < 10))
+ || (strconv.int_size == 64 && (0 < s.len && s.len < 19)) {
+ // Fast path for small integers that fit int type.
+ mut start_idx := 0
+ if s[0] == `-` || s[0] == `+` {
+ start_idx++
+ if s.len - start_idx < 1 {
+ // return 0, &NumError{fnAtoi, s0, ErrSyntax}
+ return error('strconv.atoi: parsing "$s": invalid syntax ')
+ }
+ }
+ mut n := 0
+ for i in start_idx .. s.len {
+ ch := s[i] - `0`
+ if ch > 9 {
+ // return 0, &NumError{fnAtoi, s0, ErrSyntax}
+ return error('strconv.atoi: parsing "$s": invalid syntax ')
+ }
+ n = n * 10 + int(ch)
+ }
+ return if s[0] == `-` { -n } else { n }
+ }
+ // Slow path for invalid, big, or underscored integers.
+ int64 := parse_int(s, 10, 0) ?
+ return int(int64)
+}
+
+// underscore_ok reports whether the underscores in s are allowed.
+// Checking them in this one function lets all the parsers skip over them simply.
+// Underscore must appear only between digits or between a base prefix and a digit.
+fn underscore_ok(s string) bool {
+ // saw tracks the last character (class) we saw:
+ // ^ for beginning of number,
+ // 0 for a digit or base prefix,
+ // _ for an underscore,
+ // ! for none of the above.
+ mut saw := `^`
+ mut i := 0
+ // Optional sign.
+ if s.len >= 1 && (s[0] == `-` || s[0] == `+`) {
+ i++
+ }
+ // Optional base prefix.
+ mut hex := false
+ if s.len - i >= 2 && s[i] == `0` && (byte_to_lower(s[i + 1]) == `b`
+ || byte_to_lower(s[i + 1]) == `o` || byte_to_lower(s[i + 1]) == `x`) {
+ saw = `0` // base prefix counts as a digit for "underscore as digit separator"
+ hex = byte_to_lower(s[i + 1]) == `x`
+ i += 2
+ }
+ // Number proper.
+ for ; i < s.len; i++ {
+ // Digits are always okay.
+ if (`0` <= s[i] && s[i] <= `9`) || (hex && `a` <= byte_to_lower(s[i])
+ && byte_to_lower(s[i]) <= `f`) {
+ saw = `0`
+ continue
+ }
+ // Underscore must follow digit.
+ if s[i] == `_` {
+ if saw != `0` {
+ return false
+ }
+ saw = `_`
+ continue
+ }
+ // Underscore must also be followed by digit.
+ if saw == `_` {
+ return false
+ }
+ // Saw non-digit, non-underscore.
+ saw = `!`
+ }
+ return saw != `_`
+}
diff --git a/v_windows/v/vlib/strconv/atoi_test.v b/v_windows/v/vlib/strconv/atoi_test.v
new file mode 100644
index 0000000..b356db6
--- /dev/null
+++ b/v_windows/v/vlib/strconv/atoi_test.v
@@ -0,0 +1,84 @@
+import strconv
+
+fn test_atoi() ? {
+ assert strconv.atoi('16') ? == 16
+ assert strconv.atoi('+16') ? == 16
+ assert strconv.atoi('-16') ? == -16
+
+ // invalid strings
+ if x := strconv.atoi('str') {
+ println(x)
+ assert false
+ } else {
+ assert true
+ }
+ if x := strconv.atoi('string_longer_than_10_chars') {
+ println(x)
+ assert false
+ } else {
+ assert true
+ }
+ if x := strconv.atoi('') {
+ println(x)
+ assert false
+ } else {
+ assert true
+ }
+}
+
+fn test_parse_int() ? {
+ // Different bases
+ assert strconv.parse_int('16', 16, 0) ? == 0x16
+ assert strconv.parse_int('16', 8, 0) ? == 0o16
+ assert strconv.parse_int('11', 2, 0) ? == 3
+ // Different bit sizes
+ assert strconv.parse_int('127', 10, 8) ? == 127
+ assert strconv.parse_int('128', 10, 8) ? == 127
+ assert strconv.parse_int('32767', 10, 16) ? == 32767
+ assert strconv.parse_int('32768', 10, 16) ? == 32767
+ assert strconv.parse_int('2147483647', 10, 32) ? == 2147483647
+ assert strconv.parse_int('2147483648', 10, 32) ? == 2147483647
+ assert strconv.parse_int('9223372036854775807', 10, 64) ? == 9223372036854775807
+ assert strconv.parse_int('9223372036854775808', 10, 64) ? == 9223372036854775807
+ assert strconv.parse_int('baobab', 36, 64) ? == 683058467
+ // Invalid bit sizes
+ if x := strconv.parse_int('123', 10, -1) {
+ println(x)
+ assert false
+ } else {
+ assert true
+ }
+ if x := strconv.parse_int('123', 10, 65) {
+ println(x)
+ assert false
+ } else {
+ assert true
+ }
+}
+
+fn test_common_parse_uint2() {
+ mut result, mut error := strconv.common_parse_uint2('1', 10, 8)
+ assert result == 1
+ assert error == 0
+ result, error = strconv.common_parse_uint2('123', 10, 8)
+ assert result == 123
+ assert error == 0
+ result, error = strconv.common_parse_uint2('123', 10, 65)
+ assert result == 0
+ assert error == -2
+ result, error = strconv.common_parse_uint2('123', 10, -1)
+ assert result == 0
+ assert error == -2
+ result, error = strconv.common_parse_uint2('', 10, 8)
+ assert result == 0
+ assert error == 1
+ result, error = strconv.common_parse_uint2('1a', 10, 8)
+ assert result == 1
+ assert error == 2
+ result, error = strconv.common_parse_uint2('12a', 10, 8)
+ assert result == 12
+ assert error == 3
+ result, error = strconv.common_parse_uint2('123a', 10, 8)
+ assert result == 123
+ assert error == 4
+}
diff --git a/v_windows/v/vlib/strconv/f32_f64_to_string_test.v b/v_windows/v/vlib/strconv/f32_f64_to_string_test.v
new file mode 100644
index 0000000..0b24aa2
--- /dev/null
+++ b/v_windows/v/vlib/strconv/f32_f64_to_string_test.v
@@ -0,0 +1,171 @@
+/**********************************************************************
+*
+* Float to string Test
+*
+**********************************************************************/
+import strconv
+import math
+
+union Ufloat32 {
+mut:
+ f f32 = f32(0)
+ b u32
+}
+
+union Ufloat64 {
+mut:
+ f f64 = f64(0)
+ b u64
+}
+
+fn f64_from_bits1(b u64) f64 {
+ mut x := Ufloat64{}
+ x.b = b
+ // C.printf("bin: %016llx\n",x.f)
+ return unsafe { x.f }
+}
+
+fn f32_from_bits1(b u32) f32 {
+ mut x := Ufloat32{}
+ x.b = b
+ // C.printf("bin: %08x\n",x.f)
+ return unsafe { x.f }
+}
+
+fn test_float_to_str() {
+ test_cases_f32 := [
+ f32_from_bits1(0x0000_0000), // +0
+ f32_from_bits1(0x8000_0000), // -0
+ f32_from_bits1(0xFFC0_0001), // sNan
+ f32_from_bits1(0xFF80_0001), // qNan
+ f32_from_bits1(0x7F80_0000), // +inf
+ f32_from_bits1(0xFF80_0000), // -inf
+ 1,
+ -1,
+ 10,
+ -10,
+ 0.3,
+ -0.3,
+ 1000000,
+ 123456.7,
+ 123e35,
+ -123.45,
+ 1e23,
+ f32_from_bits1(0x0080_0000), // smallest float32
+ math.max_f32,
+ 383260575764816448.0,
+ ]
+
+ exp_result_f32 := [
+ '0e+00',
+ '-0e+00',
+ 'nan',
+ 'nan',
+ '+inf',
+ '-inf',
+ '1.e+00',
+ '-1.e+00',
+ '1.e+01',
+ '-1.e+01',
+ '3.e-01',
+ '-3.e-01',
+ '1.e+06',
+ '1.234567e+05',
+ '1.23e+37',
+ '-1.2345e+02',
+ '1.e+23',
+ '1.1754944e-38', // aprox from 1.1754943508 × 10−38,
+ '3.4028235e+38',
+ '3.8326058e+17',
+ ]
+
+ test_cases_f64 := [
+ f64_from_bits1(0x0000_0000_0000_0000), // +0
+ f64_from_bits1(0x8000_0000_0000_0000), // -0
+ f64_from_bits1(0x7FF0_0000_0000_0001), // sNan
+ f64_from_bits1(0x7FF8_0000_0000_0001), // qNan
+ f64_from_bits1(0x7FF0_0000_0000_0000), // +inf
+ f64_from_bits1(0xFFF0_0000_0000_0000), // -inf
+ 1,
+ -1,
+ 10,
+ -10,
+ 0.3,
+ -0.3,
+ 1000000,
+ 123456.7,
+ 123e45,
+ -123.45,
+ 1e23,
+ f64_from_bits1(0x0010_0000_0000_0000), // smallest float64
+ math.max_f32,
+ 383260575764816448,
+ 383260575764816448,
+ // C failing cases
+ 123e300,
+ 123e-300,
+ 5.e-324,
+ -5.e-324,
+ ]
+
+ exp_result_f64 := [
+ '0e+00',
+ '-0e+00',
+ 'nan',
+ 'nan',
+ '+inf',
+ '-inf',
+ '1.e+00',
+ '-1.e+00',
+ '1.e+01',
+ '-1.e+01',
+ '3.e-01',
+ '-3.e-01',
+ '1.e+06',
+ '1.234567e+05',
+ '1.23e+47',
+ '-1.2345e+02',
+ '1.e+23',
+ '2.2250738585072014e-308',
+ '3.4028234663852886e+38',
+ '3.8326057576481645e+17',
+ '3.8326057576481645e+17',
+ '1.23e+302', // this test is failed from C sprintf!!
+ '1.23e-298',
+ '5.e-324',
+ '-5.e-324',
+ ]
+
+ // test f32
+ for c, x in test_cases_f32 {
+ println(x)
+ s := strconv.f32_to_str(x, 8)
+ s1 := exp_result_f32[c]
+ // println("$s1 $s")
+ assert s == s1
+ }
+
+ // test f64
+ for c, x in test_cases_f64 {
+ s := strconv.f64_to_str(x, 17)
+ s1 := exp_result_f64[c]
+ // println("$s1 $s")
+ assert s == s1
+ }
+
+ // test long format
+ for exp := 1; exp < 120; exp++ {
+ a := strconv.f64_to_str_l(('1e' + exp.str()).f64())
+ // println(a)
+ assert a.len == exp + 1
+
+ b := strconv.f64_to_str_l(('1e-' + exp.str()).f64())
+ // println(b)
+ assert b.len == exp + 2
+ }
+
+ // test rounding str conversion
+ // println( ftoa.f64_to_str(0.3456789123456, 4) )
+ // assert ftoa.f64_to_str(0.3456789123456, 4)=="3.4568e-01"
+ // assert ftoa.f32_to_str(0.345678, 3)=="3.457e-01"
+}
diff --git a/v_windows/v/vlib/strconv/f32_str.v b/v_windows/v/vlib/strconv/f32_str.v
new file mode 100644
index 0000000..8e17c89
--- /dev/null
+++ b/v_windows/v/vlib/strconv/f32_str.v
@@ -0,0 +1,377 @@
+module strconv
+
+/*=============================================================================
+
+f32 to string
+
+Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
+Use of this source code is governed by an MIT license
+that can be found in the LICENSE file.
+
+This file contains the f32 to string functions
+
+These functions are based on the work of:
+Publication:PLDI 2018: Proceedings of the 39th ACM SIGPLAN
+Conference on Programming Language Design and ImplementationJune 2018
+Pages 270–282 https://doi.org/10.1145/3192366.3192369
+
+inspired by the Go version here:
+https://github.com/cespare/ryu/tree/ba56a33f39e3bbbfa409095d0f9ae168a595feea
+
+=============================================================================*/
+
+// pow of ten table used by n_digit reduction
+const (
+ ten_pow_table_32 = [
+ u32(1),
+ u32(10),
+ u32(100),
+ u32(1000),
+ u32(10000),
+ u32(100000),
+ u32(1000000),
+ u32(10000000),
+ u32(100000000),
+ u32(1000000000),
+ u32(10000000000),
+ u32(100000000000),
+ ]
+)
+
+//=============================================================================
+// Conversion Functions
+//=============================================================================
+const (
+ mantbits32 = u32(23)
+ expbits32 = u32(8)
+ bias32 = 127 // f32 exponent bias
+ maxexp32 = 255
+)
+
+// max 46 char
+// -3.40282346638528859811704183484516925440e+38
+[direct_array_access]
+pub fn (d Dec32) get_string_32(neg bool, i_n_digit int, i_pad_digit int) string {
+ n_digit := i_n_digit + 1
+ pad_digit := i_pad_digit + 1
+ mut out := d.m
+ // mut out_len := decimal_len_32(out)
+ mut out_len := dec_digits(out)
+ out_len_original := out_len
+
+ mut fw_zeros := 0
+ if pad_digit > out_len {
+ fw_zeros = pad_digit - out_len
+ }
+
+ mut buf := []byte{len: int(out_len + 5 + 1 + 1)} // sign + mant_len + . + e + e_sign + exp_len(2) + \0}
+ mut i := 0
+
+ if neg {
+ if buf.data != 0 {
+ // The buf.data != 0 check here, is needed for clean compilation
+ // with `-cc gcc -cstrict -prod`. Without it, gcc produces:
+ // error: potential null pointer dereference
+ buf[i] = `-`
+ }
+ i++
+ }
+
+ mut disp := 0
+ if out_len <= 1 {
+ disp = 1
+ }
+
+ if n_digit < out_len {
+ // println("orig: ${out_len_original}")
+ out += strconv.ten_pow_table_32[out_len - n_digit - 1] * 5 // round to up
+ out /= strconv.ten_pow_table_32[out_len - n_digit]
+ out_len = n_digit
+ }
+
+ y := i + out_len
+ mut x := 0
+ for x < (out_len - disp - 1) {
+ buf[y - x] = `0` + byte(out % 10)
+ out /= 10
+ i++
+ x++
+ }
+
+ // no decimal digits needed, end here
+ if i_n_digit == 0 {
+ unsafe {
+ buf[i] = 0
+ return tos(&byte(&buf[0]), i)
+ }
+ }
+
+ if out_len >= 1 {
+ buf[y - x] = `.`
+ x++
+ i++
+ }
+
+ if y - x >= 0 {
+ buf[y - x] = `0` + byte(out % 10)
+ i++
+ }
+
+ for fw_zeros > 0 {
+ buf[i] = `0`
+ i++
+ fw_zeros--
+ }
+
+ buf[i] = `e`
+ i++
+
+ mut exp := d.e + out_len_original - 1
+ if exp < 0 {
+ buf[i] = `-`
+ i++
+ exp = -exp
+ } else {
+ buf[i] = `+`
+ i++
+ }
+
+ // Always print two digits to match strconv's formatting.
+ d1 := exp % 10
+ d0 := exp / 10
+ buf[i] = `0` + byte(d0)
+ i++
+ buf[i] = `0` + byte(d1)
+ i++
+ buf[i] = 0
+
+ return unsafe {
+ tos(&byte(&buf[0]), i)
+ }
+}
+
+fn f32_to_decimal_exact_int(i_mant u32, exp u32) (Dec32, bool) {
+ mut d := Dec32{}
+ e := exp - strconv.bias32
+ if e > strconv.mantbits32 {
+ return d, false
+ }
+ shift := strconv.mantbits32 - e
+ mant := i_mant | 0x0080_0000 // implicit 1
+ // mant := i_mant | (1 << mantbits32) // implicit 1
+ d.m = mant >> shift
+ if (d.m << shift) != mant {
+ return d, false
+ }
+ for (d.m % 10) == 0 {
+ d.m /= 10
+ d.e++
+ }
+ return d, true
+}
+
+fn f32_to_decimal(mant u32, exp u32) Dec32 {
+ mut e2 := 0
+ mut m2 := u32(0)
+ if exp == 0 {
+ // We subtract 2 so that the bounds computation has
+ // 2 additional bits.
+ e2 = 1 - strconv.bias32 - int(strconv.mantbits32) - 2
+ m2 = mant
+ } else {
+ e2 = int(exp) - strconv.bias32 - int(strconv.mantbits32) - 2
+ m2 = (u32(1) << strconv.mantbits32) | mant
+ }
+ even := (m2 & 1) == 0
+ accept_bounds := even
+
+ // Step 2: Determine the interval of valid decimal representations.
+ mv := u32(4 * m2)
+ mp := u32(4 * m2 + 2)
+ mm_shift := bool_to_u32(mant != 0 || exp <= 1)
+ mm := u32(4 * m2 - 1 - mm_shift)
+
+ mut vr := u32(0)
+ mut vp := u32(0)
+ mut vm := u32(0)
+ mut e10 := 0
+ mut vm_is_trailing_zeros := false
+ mut vr_is_trailing_zeros := false
+ mut last_removed_digit := byte(0)
+
+ if e2 >= 0 {
+ q := log10_pow2(e2)
+ e10 = int(q)
+ k := pow5_inv_num_bits_32 + pow5_bits(int(q)) - 1
+ i := -e2 + int(q) + k
+
+ vr = mul_pow5_invdiv_pow2(mv, q, i)
+ vp = mul_pow5_invdiv_pow2(mp, q, i)
+ vm = mul_pow5_invdiv_pow2(mm, q, i)
+ if q != 0 && (vp - 1) / 10 <= vm / 10 {
+ // We need to know one removed digit even if we are not
+ // going to loop below. We could use q = X - 1 above,
+ // except that would require 33 bits for the result, and
+ // we've found that 32-bit arithmetic is faster even on
+ // 64-bit machines.
+ l := pow5_inv_num_bits_32 + pow5_bits(int(q - 1)) - 1
+ last_removed_digit = byte(mul_pow5_invdiv_pow2(mv, q - 1, -e2 + int(q - 1) + l) % 10)
+ }
+ if q <= 9 {
+ // The largest power of 5 that fits in 24 bits is 5^10,
+ // but q <= 9 seems to be safe as well. Only one of mp,
+ // mv, and mm can be a multiple of 5, if any.
+ if mv % 5 == 0 {
+ vr_is_trailing_zeros = multiple_of_power_of_five_32(mv, q)
+ } else if accept_bounds {
+ vm_is_trailing_zeros = multiple_of_power_of_five_32(mm, q)
+ } else if multiple_of_power_of_five_32(mp, q) {
+ vp--
+ }
+ }
+ } else {
+ q := log10_pow5(-e2)
+ e10 = int(q) + e2
+ i := -e2 - int(q)
+ k := pow5_bits(i) - pow5_num_bits_32
+ mut j := int(q) - k
+ vr = mul_pow5_div_pow2(mv, u32(i), j)
+ vp = mul_pow5_div_pow2(mp, u32(i), j)
+ vm = mul_pow5_div_pow2(mm, u32(i), j)
+ if q != 0 && ((vp - 1) / 10) <= vm / 10 {
+ j = int(q) - 1 - (pow5_bits(i + 1) - pow5_num_bits_32)
+ last_removed_digit = byte(mul_pow5_div_pow2(mv, u32(i + 1), j) % 10)
+ }
+ if q <= 1 {
+ // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at
+ // least q trailing 0 bits. mv = 4 * m2, so it always
+ // has at least two trailing 0 bits.
+ vr_is_trailing_zeros = true
+ if accept_bounds {
+ // mm = mv - 1 - mm_shift, so it has 1 trailing 0 bit
+ // if mm_shift == 1.
+ vm_is_trailing_zeros = mm_shift == 1
+ } else {
+ // mp = mv + 2, so it always has at least one
+ // trailing 0 bit.
+ vp--
+ }
+ } else if q < 31 {
+ vr_is_trailing_zeros = multiple_of_power_of_two_32(mv, q - 1)
+ }
+ }
+
+ // Step 4: Find the shortest decimal representation
+ // in the interval of valid representations.
+ mut removed := 0
+ mut out := u32(0)
+ if vm_is_trailing_zeros || vr_is_trailing_zeros {
+ // General case, which happens rarely (~4.0%).
+ for vp / 10 > vm / 10 {
+ vm_is_trailing_zeros = vm_is_trailing_zeros && (vm % 10) == 0
+ vr_is_trailing_zeros = vr_is_trailing_zeros && (last_removed_digit == 0)
+ last_removed_digit = byte(vr % 10)
+ vr /= 10
+ vp /= 10
+ vm /= 10
+ removed++
+ }
+ if vm_is_trailing_zeros {
+ for vm % 10 == 0 {
+ vr_is_trailing_zeros = vr_is_trailing_zeros && (last_removed_digit == 0)
+ last_removed_digit = byte(vr % 10)
+ vr /= 10
+ vp /= 10
+ vm /= 10
+ removed++
+ }
+ }
+ if vr_is_trailing_zeros && (last_removed_digit == 5) && (vr % 2) == 0 {
+ // Round even if the exact number is .....50..0.
+ last_removed_digit = 4
+ }
+ out = vr
+ // We need to take vr + 1 if vr is outside bounds
+ // or we need to round up.
+ if (vr == vm && (!accept_bounds || !vm_is_trailing_zeros)) || last_removed_digit >= 5 {
+ out++
+ }
+ } else {
+ // Specialized for the common case (~96.0%). Percentages below
+ // are relative to this. Loop iterations below (approximately):
+ // 0: 13.6%, 1: 70.7%, 2: 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01%
+ for vp / 10 > vm / 10 {
+ last_removed_digit = byte(vr % 10)
+ vr /= 10
+ vp /= 10
+ vm /= 10
+ removed++
+ }
+ // We need to take vr + 1 if vr is outside bounds
+ // or we need to round up.
+ out = vr + bool_to_u32(vr == vm || last_removed_digit >= 5)
+ }
+
+ return Dec32{
+ m: out
+ e: e10 + removed
+ }
+}
+
+//=============================================================================
+// String Functions
+//=============================================================================
+
+// f32_to_str return a string in scientific notation with max n_digit after the dot
+pub fn f32_to_str(f f32, n_digit int) string {
+ mut u1 := Uf32{}
+ u1.f = f
+ u := unsafe { u1.u }
+
+ neg := (u >> (strconv.mantbits32 + strconv.expbits32)) != 0
+ mant := u & ((u32(1) << strconv.mantbits32) - u32(1))
+ exp := (u >> strconv.mantbits32) & ((u32(1) << strconv.expbits32) - u32(1))
+
+ // println("${neg} ${mant} e ${exp-bias32}")
+
+ // Exit early for easy cases.
+ if (exp == strconv.maxexp32) || (exp == 0 && mant == 0) {
+ return get_string_special(neg, exp == 0, mant == 0)
+ }
+
+ mut d, ok := f32_to_decimal_exact_int(mant, exp)
+ if !ok {
+ // println("with exp form")
+ d = f32_to_decimal(mant, exp)
+ }
+
+ // println("${d.m} ${d.e}")
+ return d.get_string_32(neg, n_digit, 0)
+}
+
+// f32_to_str return a string in scientific notation with max n_digit after the dot
+pub fn f32_to_str_pad(f f32, n_digit int) string {
+ mut u1 := Uf32{}
+ u1.f = f
+ u := unsafe { u1.u }
+
+ neg := (u >> (strconv.mantbits32 + strconv.expbits32)) != 0
+ mant := u & ((u32(1) << strconv.mantbits32) - u32(1))
+ exp := (u >> strconv.mantbits32) & ((u32(1) << strconv.expbits32) - u32(1))
+
+ // println("${neg} ${mant} e ${exp-bias32}")
+
+ // Exit early for easy cases.
+ if (exp == strconv.maxexp32) || (exp == 0 && mant == 0) {
+ return get_string_special(neg, exp == 0, mant == 0)
+ }
+
+ mut d, ok := f32_to_decimal_exact_int(mant, exp)
+ if !ok {
+ // println("with exp form")
+ d = f32_to_decimal(mant, exp)
+ }
+
+ // println("${d.m} ${d.e}")
+ return d.get_string_32(neg, n_digit, n_digit)
+}
diff --git a/v_windows/v/vlib/strconv/f64_str.v b/v_windows/v/vlib/strconv/f64_str.v
new file mode 100644
index 0000000..6be4354
--- /dev/null
+++ b/v_windows/v/vlib/strconv/f64_str.v
@@ -0,0 +1,418 @@
+module strconv
+
+/*=============================================================================
+
+f64 to string
+
+Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
+Use of this source code is governed by an MIT license
+that can be found in the LICENSE file.
+
+This file contains the f64 to string functions
+
+These functions are based on the work of:
+Publication:PLDI 2018: Proceedings of the 39th ACM SIGPLAN
+Conference on Programming Language Design and ImplementationJune 2018
+Pages 270–282 https://doi.org/10.1145/3192366.3192369
+
+inspired by the Go version here:
+https://github.com/cespare/ryu/tree/ba56a33f39e3bbbfa409095d0f9ae168a595feea
+
+=============================================================================*/
+
+// pow of ten table used by n_digit reduction
+const (
+ ten_pow_table_64 = [
+ u64(1),
+ u64(10),
+ u64(100),
+ u64(1000),
+ u64(10000),
+ u64(100000),
+ u64(1000000),
+ u64(10000000),
+ u64(100000000),
+ u64(1000000000),
+ u64(10000000000),
+ u64(100000000000),
+ u64(1000000000000),
+ u64(10000000000000),
+ u64(100000000000000),
+ u64(1000000000000000),
+ u64(10000000000000000),
+ u64(100000000000000000),
+ u64(1000000000000000000),
+ u64(10000000000000000000),
+ ]
+)
+
+//=============================================================================
+// Conversion Functions
+//=============================================================================
+const (
+ mantbits64 = u32(52)
+ expbits64 = u32(11)
+ bias64 = 1023 // f64 exponent bias
+ maxexp64 = 2047
+)
+
+[direct_array_access]
+fn (d Dec64) get_string_64(neg bool, i_n_digit int, i_pad_digit int) string {
+ mut n_digit := i_n_digit + 1
+ pad_digit := i_pad_digit + 1
+ mut out := d.m
+ mut d_exp := d.e
+ // mut out_len := decimal_len_64(out)
+ mut out_len := dec_digits(out)
+ out_len_original := out_len
+
+ mut fw_zeros := 0
+ if pad_digit > out_len {
+ fw_zeros = pad_digit - out_len
+ }
+
+ mut buf := []byte{len: (out_len + 6 + 1 + 1 + fw_zeros)} // sign + mant_len + . + e + e_sign + exp_len(2) + \0}
+ mut i := 0
+
+ if neg {
+ buf[i] = `-`
+ i++
+ }
+
+ mut disp := 0
+ if out_len <= 1 {
+ disp = 1
+ }
+
+ // rounding last used digit
+ if n_digit < out_len {
+ // println("out:[$out]")
+ out += strconv.ten_pow_table_64[out_len - n_digit - 1] * 5 // round to up
+ out /= strconv.ten_pow_table_64[out_len - n_digit]
+ // println("out1:[$out] ${d.m / ten_pow_table_64[out_len - n_digit ]}")
+ if d.m / strconv.ten_pow_table_64[out_len - n_digit] < out {
+ d_exp++
+ n_digit++
+ }
+
+ // println("cmp: ${d.m/ten_pow_table_64[out_len - n_digit ]} ${out/ten_pow_table_64[out_len - n_digit ]}")
+
+ out_len = n_digit
+ // println("orig: ${out_len_original} new len: ${out_len} out:[$out]")
+ }
+
+ y := i + out_len
+ mut x := 0
+ for x < (out_len - disp - 1) {
+ buf[y - x] = `0` + byte(out % 10)
+ out /= 10
+ i++
+ x++
+ }
+
+ // no decimal digits needed, end here
+ if i_n_digit == 0 {
+ unsafe {
+ buf[i] = 0
+ return tos(&byte(&buf[0]), i)
+ }
+ }
+
+ if out_len >= 1 {
+ buf[y - x] = `.`
+ x++
+ i++
+ }
+
+ if y - x >= 0 {
+ buf[y - x] = `0` + byte(out % 10)
+ i++
+ }
+
+ for fw_zeros > 0 {
+ buf[i] = `0`
+ i++
+ fw_zeros--
+ }
+
+ buf[i] = `e`
+ i++
+
+ mut exp := d_exp + out_len_original - 1
+ if exp < 0 {
+ buf[i] = `-`
+ i++
+ exp = -exp
+ } else {
+ buf[i] = `+`
+ i++
+ }
+
+ // Always print at least two digits to match strconv's formatting.
+ d2 := exp % 10
+ exp /= 10
+ d1 := exp % 10
+ d0 := exp / 10
+ if d0 > 0 {
+ buf[i] = `0` + byte(d0)
+ i++
+ }
+ buf[i] = `0` + byte(d1)
+ i++
+ buf[i] = `0` + byte(d2)
+ i++
+ buf[i] = 0
+
+ return unsafe {
+ tos(&byte(&buf[0]), i)
+ }
+}
+
+fn f64_to_decimal_exact_int(i_mant u64, exp u64) (Dec64, bool) {
+ mut d := Dec64{}
+ e := exp - strconv.bias64
+ if e > strconv.mantbits64 {
+ return d, false
+ }
+ shift := strconv.mantbits64 - e
+ mant := i_mant | u64(0x0010_0000_0000_0000) // implicit 1
+ // mant := i_mant | (1 << mantbits64) // implicit 1
+ d.m = mant >> shift
+ if (d.m << shift) != mant {
+ return d, false
+ }
+
+ for (d.m % 10) == 0 {
+ d.m /= 10
+ d.e++
+ }
+ return d, true
+}
+
+fn f64_to_decimal(mant u64, exp u64) Dec64 {
+ mut e2 := 0
+ mut m2 := u64(0)
+ if exp == 0 {
+ // We subtract 2 so that the bounds computation has
+ // 2 additional bits.
+ e2 = 1 - strconv.bias64 - int(strconv.mantbits64) - 2
+ m2 = mant
+ } else {
+ e2 = int(exp) - strconv.bias64 - int(strconv.mantbits64) - 2
+ m2 = (u64(1) << strconv.mantbits64) | mant
+ }
+ even := (m2 & 1) == 0
+ accept_bounds := even
+
+ // Step 2: Determine the interval of valid decimal representations.
+ mv := u64(4 * m2)
+ mm_shift := bool_to_u64(mant != 0 || exp <= 1)
+
+ // Step 3: Convert to a decimal power base uing 128-bit arithmetic.
+ mut vr := u64(0)
+ mut vp := u64(0)
+ mut vm := u64(0)
+ mut e10 := 0
+ mut vm_is_trailing_zeros := false
+ mut vr_is_trailing_zeros := false
+
+ if e2 >= 0 {
+ // This expression is slightly faster than max(0, log10Pow2(e2) - 1).
+ q := log10_pow2(e2) - bool_to_u32(e2 > 3)
+ e10 = int(q)
+ k := pow5_inv_num_bits_64 + pow5_bits(int(q)) - 1
+ i := -e2 + int(q) + k
+
+ mul := pow5_inv_split_64[q]
+ vr = mul_shift_64(u64(4) * m2, mul, i)
+ vp = mul_shift_64(u64(4) * m2 + u64(2), mul, i)
+ vm = mul_shift_64(u64(4) * m2 - u64(1) - mm_shift, mul, i)
+ if q <= 21 {
+ // This should use q <= 22, but I think 21 is also safe.
+ // Smaller values may still be safe, but it's more
+ // difficult to reason about them. Only one of mp, mv,
+ // and mm can be a multiple of 5, if any.
+ if mv % 5 == 0 {
+ vr_is_trailing_zeros = multiple_of_power_of_five_64(mv, q)
+ } else if accept_bounds {
+ // Same as min(e2 + (^mm & 1), pow5Factor64(mm)) >= q
+ // <=> e2 + (^mm & 1) >= q && pow5Factor64(mm) >= q
+ // <=> true && pow5Factor64(mm) >= q, since e2 >= q.
+ vm_is_trailing_zeros = multiple_of_power_of_five_64(mv - 1 - mm_shift,
+ q)
+ } else if multiple_of_power_of_five_64(mv + 2, q) {
+ vp--
+ }
+ }
+ } else {
+ // This expression is slightly faster than max(0, log10Pow5(-e2) - 1).
+ q := log10_pow5(-e2) - bool_to_u32(-e2 > 1)
+ e10 = int(q) + e2
+ i := -e2 - int(q)
+ k := pow5_bits(i) - pow5_num_bits_64
+ j := int(q) - k
+ mul := pow5_split_64[i]
+ vr = mul_shift_64(u64(4) * m2, mul, j)
+ vp = mul_shift_64(u64(4) * m2 + u64(2), mul, j)
+ vm = mul_shift_64(u64(4) * m2 - u64(1) - mm_shift, mul, j)
+ if q <= 1 {
+ // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits.
+ // mv = 4 * m2, so it always has at least two trailing 0 bits.
+ vr_is_trailing_zeros = true
+ if accept_bounds {
+ // mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff mmShift == 1.
+ vm_is_trailing_zeros = (mm_shift == 1)
+ } else {
+ // mp = mv + 2, so it always has at least one trailing 0 bit.
+ vp--
+ }
+ } else if q < 63 { // TODO(ulfjack/cespare): Use a tighter bound here.
+ // We need to compute min(ntz(mv), pow5Factor64(mv) - e2) >= q - 1
+ // <=> ntz(mv) >= q - 1 && pow5Factor64(mv) - e2 >= q - 1
+ // <=> ntz(mv) >= q - 1 (e2 is negative and -e2 >= q)
+ // <=> (mv & ((1 << (q - 1)) - 1)) == 0
+ // We also need to make sure that the left shift does not overflow.
+ vr_is_trailing_zeros = multiple_of_power_of_two_64(mv, q - 1)
+ }
+ }
+
+ // Step 4: Find the shortest decimal representation
+ // in the interval of valid representations.
+ mut removed := 0
+ mut last_removed_digit := byte(0)
+ mut out := u64(0)
+ // On average, we remove ~2 digits.
+ if vm_is_trailing_zeros || vr_is_trailing_zeros {
+ // General case, which happens rarely (~0.7%).
+ for {
+ vp_div_10 := vp / 10
+ vm_div_10 := vm / 10
+ if vp_div_10 <= vm_div_10 {
+ break
+ }
+ vm_mod_10 := vm % 10
+ vr_div_10 := vr / 10
+ vr_mod_10 := vr % 10
+ vm_is_trailing_zeros = vm_is_trailing_zeros && vm_mod_10 == 0
+ vr_is_trailing_zeros = vr_is_trailing_zeros && (last_removed_digit == 0)
+ last_removed_digit = byte(vr_mod_10)
+ vr = vr_div_10
+ vp = vp_div_10
+ vm = vm_div_10
+ removed++
+ }
+ if vm_is_trailing_zeros {
+ for {
+ vm_div_10 := vm / 10
+ vm_mod_10 := vm % 10
+ if vm_mod_10 != 0 {
+ break
+ }
+ vp_div_10 := vp / 10
+ vr_div_10 := vr / 10
+ vr_mod_10 := vr % 10
+ vr_is_trailing_zeros = vr_is_trailing_zeros && (last_removed_digit == 0)
+ last_removed_digit = byte(vr_mod_10)
+ vr = vr_div_10
+ vp = vp_div_10
+ vm = vm_div_10
+ removed++
+ }
+ }
+ if vr_is_trailing_zeros && (last_removed_digit == 5) && (vr % 2) == 0 {
+ // Round even if the exact number is .....50..0.
+ last_removed_digit = 4
+ }
+ out = vr
+ // We need to take vr + 1 if vr is outside bounds
+ // or we need to round up.
+ if (vr == vm && (!accept_bounds || !vm_is_trailing_zeros)) || last_removed_digit >= 5 {
+ out++
+ }
+ } else {
+ // Specialized for the common case (~99.3%).
+ // Percentages below are relative to this.
+ mut round_up := false
+ for vp / 100 > vm / 100 {
+ // Optimization: remove two digits at a time (~86.2%).
+ round_up = (vr % 100) >= 50
+ vr /= 100
+ vp /= 100
+ vm /= 100
+ removed += 2
+ }
+ // Loop iterations below (approximately), without optimization above:
+ // 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%, 6+: 0.02%
+ // Loop iterations below (approximately), with optimization above:
+ // 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02%
+ for vp / 10 > vm / 10 {
+ round_up = (vr % 10) >= 5
+ vr /= 10
+ vp /= 10
+ vm /= 10
+ removed++
+ }
+ // We need to take vr + 1 if vr is outside bounds
+ // or we need to round up.
+ out = vr + bool_to_u64(vr == vm || round_up)
+ }
+
+ return Dec64{
+ m: out
+ e: e10 + removed
+ }
+}
+
+//=============================================================================
+// String Functions
+//=============================================================================
+
+// f64_to_str return a string in scientific notation with max n_digit after the dot
+pub fn f64_to_str(f f64, n_digit int) string {
+ mut u1 := Uf64{}
+ u1.f = f
+ u := unsafe { u1.u }
+
+ neg := (u >> (strconv.mantbits64 + strconv.expbits64)) != 0
+ mant := u & ((u64(1) << strconv.mantbits64) - u64(1))
+ exp := (u >> strconv.mantbits64) & ((u64(1) << strconv.expbits64) - u64(1))
+ // println("s:${neg} mant:${mant} exp:${exp} float:${f} byte:${u1.u:016lx}")
+
+ // Exit early for easy cases.
+ if (exp == strconv.maxexp64) || (exp == 0 && mant == 0) {
+ return get_string_special(neg, exp == 0, mant == 0)
+ }
+
+ mut d, ok := f64_to_decimal_exact_int(mant, exp)
+ if !ok {
+ // println("to_decimal")
+ d = f64_to_decimal(mant, exp)
+ }
+ // println("${d.m} ${d.e}")
+ return d.get_string_64(neg, n_digit, 0)
+}
+
+// f64_to_str return a string in scientific notation with max n_digit after the dot
+pub fn f64_to_str_pad(f f64, n_digit int) string {
+ mut u1 := Uf64{}
+ u1.f = f
+ u := unsafe { u1.u }
+
+ neg := (u >> (strconv.mantbits64 + strconv.expbits64)) != 0
+ mant := u & ((u64(1) << strconv.mantbits64) - u64(1))
+ exp := (u >> strconv.mantbits64) & ((u64(1) << strconv.expbits64) - u64(1))
+ // println("s:${neg} mant:${mant} exp:${exp} float:${f} byte:${u1.u:016lx}")
+
+ // Exit early for easy cases.
+ if (exp == strconv.maxexp64) || (exp == 0 && mant == 0) {
+ return get_string_special(neg, exp == 0, mant == 0)
+ }
+
+ mut d, ok := f64_to_decimal_exact_int(mant, exp)
+ if !ok {
+ // println("to_decimal")
+ d = f64_to_decimal(mant, exp)
+ }
+ // println("DEBUG: ${d.m} ${d.e}")
+ return d.get_string_64(neg, n_digit, n_digit)
+}
diff --git a/v_windows/v/vlib/strconv/format.md b/v_windows/v/vlib/strconv/format.md
new file mode 100644
index 0000000..1563ce9
--- /dev/null
+++ b/v_windows/v/vlib/strconv/format.md
@@ -0,0 +1,250 @@
+# v_printf/v_sprintf
+
+These are v implementations of the C language `printf` and `sprintf` functions.
+
+***Note: These functions are platform dependent in C, but in V they are platform independent.***
+
+### v_sprintf
+
+`v_sprintf` has a variable number of parameters.
+The first is a format string to control the appearance of the final string.
+Each format specifier (%s, %d, etc.) in the format string
+is replaced by the textual version of the following parameters.
+
+```v
+import strconv
+
+fn main() {
+ a := 'World'
+ s := strconv.v_sprintf('Hello %s!', a)
+ println(s)
+}
+```
+
+```
+Hello World!
+```
+
+### v_printf
+
+`v_printf` creates the same modified string as `v_sprintf`, using the same format specifiers,
+but it will immediately print the modified string to stdout instead of returning a string.
+
+### Syntax
+
+The syntax for a format specifier is:
+
+```
+%[parameter][flags][width][.precision][length]type
+```
+
+#### Flags field
+
+The Flags field may be zero or more (in any order) of:
+
+| Character | Description |
+| ----------- | ------------------------------------------------------------ |
+| `-` (minus) | Left-align the output of this specifier. (The default is to right-align the output.) |
+| `+` (plus) | Prepends a plus for positive signed-numeric types. positive = `+`, negative = `-`. (The default doesn't prepend anything to positive numbers.) |
+| `0` (zero) | When the 'width' option is specified, prepends zeros for numeric types. (The default prepends spaces.) For example, `printf("%4X",3)` produces ` 3`, while `printf("%04X",3)` produces `0003`. |
+
+#### Width field
+
+The Width field specifies a *maximum* number of characters to output,
+and is typically used to pad fixed-width fields in tabulated output,
+it causes truncation of oversized fields.
+
+The width field may be omitted, or it may be a numeric integer value,
+or may also be specified by a parameter when indicated by an asterisk `*`.
+For example, `v_printf("%*.s", 5, my_string)` will result in ` mystring` being printed,
+with a total width of 5 characters.
+
+#### Length field
+
+The Length field can be omitted or be any of:
+
+| Character | Description |
+| --------- | ------------------------------------------------------------ |
+| `hh` | For integer types, causes `printf` to expect an `byte` or `i8` argument. |
+| `h` | For integer types, causes `printf` to expect an `int16` or `u16` argument. |
+| `l` | For integer types, causes `printf` to expect an `i64` or `u64` argument. |
+| `ll` | For integer types, causes `printf` to expect an `i64` or `u64` argument. |
+| | |
+| | |
+
+#### Type field
+
+The Type field can be any of:
+
+| Character | Description |
+| --------- | ------------------------------------------------------------ |
+| `%` | Prints a literal `%` character (this type doesn't accept any flags, width, precision, length fields). |
+| `d`, `i` | `int` as a signed `int` `%d` and `%i` are synonymous for output. The size of the argument is specified by the length field. |
+| `u` | `unsigned int`. The size of the argument is specified by the length field. |
+| `f`, `F` | `double` in normal notation. `f` and `F` only differs in how the strings are printed: lowercase or uppercase. |
+| `e`, `E` | `double` in scientific notation.`e` and `E` only differs in how the strings are printed: lowercase or uppercase. |
+| `g`, `G` | `double` in automatic notation.`g` and `G` only differs in how the strings are printed: lowercase or uppercase. |
+| `x`, `X` | `unsigned int` as a hexadecimal number. `x` uses lower-case letters and `X` uses upper-case. |
+| `s` | string |
+| `p` | `void *` (pointer to void) in an implementation-defined format. |
+| `c` | `char` (character). |
+
+## Examples
+
+various types
+
+```v oksyntax
+a0 := u32(10)
+b0 := 200
+c0 := byte(12)
+s0 := 'ciAo'
+ch0 := `B`
+f0 := 0.312345
+f1 := 200000.0
+sc0 := 'ciao: [%-08u] %d %hhd [%8s] [%08X] [%-20.4f] [%-20.4f] [%c]'
+temp_s = strconv.v_sprintf(sc0, a0, b0, c0, s0, b0, f0, f1, ch0)
+println(temp_s)
+```
+
+```
+ciao: [10 ] 200 12 [ ciAo] [000000C8] [0.3123 ] [200000.0000 ] [B]
+```
+
+integer
+
+```v oksyntax
+a := byte(12)
+b := i16(13)
+c := 14
+d := i64(15)
+sc1 := '==>%hhd %hd %d %ld'
+temp_s = strconv.v_sprintf(sc1, a, b, c, d)
+println(temp_s)
+```
+
+```
+==>12 13 14 15
+```
+
+unsigned integer
+
+```v oksyntax
+a1 := byte(0xff)
+b1 := u16(0xffff)
+c1 := u32(0xffffffff)
+d1 := u64(-1)
+sc2 := '%hhu %hu %u %lu'
+temp_s = strconv.v_sprintf(sc2, a1, b1, c1, d1)
+println(temp_s)
+```
+
+```
+255 65535 4294967295 18446744073709551615
+```
+
+hexadecimal
+
+```v oksyntax
+a1 := byte(0xff)
+b1 := i16(0xffff)
+c1 := u32(0xffffffff)
+d1 := u64(-1)
+sc3 := '%hhx %hx %x %lx'
+temp_s = strconv.v_sprintf(sc3, a1, b1, c1, d1)
+println(temp_s)
+```
+
+```
+ff ffff ffffffff ffffffffffffffff
+```
+
+hexadecimal
+
+```v oksyntax
+a2 := 125
+sc7 := '[%9x] [%9X] [%-9x] [%-9X] [%09x] [%09X]'
+temp_s = strconv.v_sprintf(sc7, a2, a2, a2, a2, a2, a2)
+println(temp_s)
+```
+
+```
+[ 7d] [ 7D] [7d ] [7D ] [00000007d] [00000007D]
+```
+
+floating points
+
+```v oksyntax
+f0 := 0.312345
+f1 := 200000.0
+f2 := -1234.300e6
+f3 := 1234.300e-6
+sc4 := '[%-20.3e] [%20.3e] [%-020.3e] [%-020.3E] [%-020.3e] [%-020.3e]'
+temp_s = strconv.v_sprintf(sc4, f0, f1, f1, f1, f2, f3)
+println(temp_s)
+```
+
+```
+[3.123e-01 ] [ 2.000e+05] [2.000e+05 ] [2.000E+05 ] [-1.234e+09 ] [1.234e-03 ]
+```
+
+float automatic notations
+
+```v oksyntax
+mut ft := -1e-7
+mut x := 0
+sc8 := '[%20g][%20G]|'
+for x < 12 {
+ temp_s = strconv.v_sprintf(sc8, ft, ft)
+ println('$temp_s\n')
+ ft = ft * 10.0
+ x++
+}
+```
+
+```
+[ -1e-07][ -1E-07]|
+[ -1e-06][ -1E-06]|
+[ -1e-05][ -1E-05]|
+[ -0.0001][ -0.0001]|
+[ -0.001][ -0.001]|
+[ -0.01][ -0.01]|
+[ -0.1][ -0.1]|
+[ -1][ -1]|
+[ -10][ -10]|
+[ -100][ -100]|
+[ -1000][ -1000]|
+[ -10000][ -10000]|
+
+```
+
+## Utility functions
+
+The format module also has some utility functions:
+
+```v oksyntax nofmt
+// calling struct
+struct BF_param {
+ pad_ch byte = ` ` // padding char
+ len0 int = -1 // default len for whole the number or string
+ len1 int = 6 // number of decimal digits, if needed
+ positive bool = true // mandatory: the sign of the number passed
+ sign_flag bool = false // flag for print sign as prefix in padding
+ allign Align_text = .right // alignment of the string
+ rm_tail_zero bool = false // remove the tail zeros from floats
+}
+
+// utilities
+fn format_dec(d u64, p BF_param) string
+fn format_fl(f f64, p BF_param) string
+fn format_es(f f64, p BF_param) string
+fn remove_tail_zeros(s string) string
+```
+
+`format_dec` format the integer number using the parameters in the `BF_param` struct.
+
+`format_fl` format a float number in normal notation using the parameters in the `BF_param` struct.
+
+`format_es format a float number in scientific notation using the parameters in the BF_param`
+struct.
+
+`remove_tail_zeros` removes the tailing zeros from a floating point number as string.
diff --git a/v_windows/v/vlib/strconv/format.v b/v_windows/v/vlib/strconv/format.v
new file mode 100644
index 0000000..e11a604
--- /dev/null
+++ b/v_windows/v/vlib/strconv/format.v
@@ -0,0 +1,113 @@
+module strconv
+
+/*
+printf/sprintf V implementation
+
+Copyright (c) 2020 Dario Deledda. All rights reserved.
+Use of this source code is governed by an MIT license
+that can be found in the LICENSE file.
+
+This file contains the printf/sprintf functions
+*/
+import strings
+
+pub enum Align_text {
+ right = 0
+ left
+ center
+}
+
+/*
+Float conversion utility
+*/
+const (
+ // rounding value
+ dec_round = [
+ f64(0.5),
+ 0.05,
+ 0.005,
+ 0.0005,
+ 0.00005,
+ 0.000005,
+ 0.0000005,
+ 0.00000005,
+ 0.000000005,
+ 0.0000000005,
+ 0.00000000005,
+ 0.000000000005,
+ 0.0000000000005,
+ 0.00000000000005,
+ 0.000000000000005,
+ 0.0000000000000005,
+ 0.00000000000000005,
+ 0.000000000000000005,
+ 0.0000000000000000005,
+ 0.00000000000000000005,
+ ]
+)
+
+/*
+const(
+ // rounding value
+ dec_round = [
+ f64(0.44),
+ 0.044,
+ 0.0044,
+ 0.00044,
+ 0.000044,
+ 0.0000044,
+ 0.00000044,
+ 0.000000044,
+ 0.0000000044,
+ 0.00000000044,
+ 0.000000000044,
+ 0.0000000000044,
+ 0.00000000000044,
+ 0.000000000000044,
+ 0.0000000000000044,
+ 0.00000000000000044,
+ 0.000000000000000044,
+ 0.0000000000000000044,
+ 0.00000000000000000044,
+ 0.000000000000000000044,
+ ]
+)
+*/
+// max float 1.797693134862315708145274237317043567981e+308
+
+/*
+Single format functions
+*/
+pub struct BF_param {
+pub mut:
+ pad_ch byte = byte(` `) // padding char
+ len0 int = -1 // default len for whole the number or string
+ len1 int = 6 // number of decimal digits, if needed
+ positive bool = true // mandatory: the sign of the number passed
+ sign_flag bool // flag for print sign as prefix in padding
+ allign Align_text = .right // alignment of the string
+ rm_tail_zero bool // remove the tail zeros from floats
+}
+
+pub fn format_str(s string, p BF_param) string {
+ if p.len0 <= 0 {
+ return s.clone()
+ }
+ dif := p.len0 - utf8_str_visible_length(s)
+ if dif <= 0 {
+ return s.clone()
+ }
+ mut res := strings.new_builder(s.len + dif)
+ if p.allign == .right {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ res.write_string(s)
+ if p.allign == .left {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ return res.str()
+}
diff --git a/v_windows/v/vlib/strconv/format_mem.v b/v_windows/v/vlib/strconv/format_mem.v
new file mode 100644
index 0000000..f3a11cb
--- /dev/null
+++ b/v_windows/v/vlib/strconv/format_mem.v
@@ -0,0 +1,498 @@
+/*=============================================================================
+Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
+Use of this source code is governed by an MIT license
+that can be found in the LICENSE file.
+
+This file contains string interpolation V functions
+=============================================================================*/
+module strconv
+
+import strings
+
+// strings.Builder version of format_str
+pub fn format_str_sb(s string, p BF_param, mut sb strings.Builder) {
+ if p.len0 <= 0 {
+ sb.write_string(s)
+ return
+ }
+ dif := p.len0 - utf8_str_visible_length(s)
+ if dif <= 0 {
+ sb.write_string(s)
+ return
+ }
+
+ if p.allign == .right {
+ for i1 := 0; i1 < dif; i1++ {
+ sb.write_b(p.pad_ch)
+ }
+ }
+ sb.write_string(s)
+ if p.allign == .left {
+ for i1 := 0; i1 < dif; i1++ {
+ sb.write_b(p.pad_ch)
+ }
+ }
+}
+
+const (
+ // digit pairs in reverse order
+ digit_pairs = '00102030405060708090011121314151617181910212223242526272829203132333435363738393041424344454647484940515253545556575859506162636465666768696071727374757677787970818283848586878889809192939495969798999'
+)
+
+// format_dec_sb format a u64
+[direct_array_access]
+pub fn format_dec_sb(d u64, p BF_param, mut res strings.Builder) {
+ mut n_char := dec_digits(d)
+ sign_len := if !p.positive || p.sign_flag { 1 } else { 0 }
+ number_len := sign_len + n_char
+ dif := p.len0 - number_len
+ mut sign_written := false
+
+ if p.allign == .right {
+ if p.pad_ch == `0` {
+ if p.positive {
+ if p.sign_flag {
+ res.write_b(`+`)
+ sign_written = true
+ }
+ } else {
+ res.write_b(`-`)
+ sign_written = true
+ }
+ }
+ // write the pad chars
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+
+ if !sign_written {
+ // no pad char, write the sign before the number
+ if p.positive {
+ if p.sign_flag {
+ res.write_b(`+`)
+ }
+ } else {
+ res.write_b(`-`)
+ }
+ }
+
+ /*
+ // Legacy version
+ // max u64 18446744073709551615 => 20 byte
+ mut buf := [32]byte{}
+ mut i := 20
+ mut d1 := d
+ for i >= (21 - n_char) {
+ buf[i] = byte(d1 % 10) + `0`
+ d1 = d1 / 10
+ i--
+ }
+ i++
+ */
+
+ //===========================================
+ // Speed version
+ // max u64 18446744073709551615 => 20 byte
+ mut buf := [32]byte{}
+ mut i := 20
+ mut n := d
+ mut d_i := u64(0)
+ if n > 0 {
+ for n > 0 {
+ n1 := n / 100
+ // calculate the digit_pairs start index
+ d_i = (n - (n1 * 100)) << 1
+ n = n1
+ unsafe {
+ buf[i] = strconv.digit_pairs.str[d_i]
+ }
+ i--
+ d_i++
+ unsafe {
+ buf[i] = strconv.digit_pairs.str[d_i]
+ }
+ i--
+ }
+ i++
+ // remove head zero
+ if d_i < 20 {
+ i++
+ }
+ unsafe { res.write_ptr(&buf[i], n_char) }
+ } else {
+ // we have a zero no need of more code!
+ res.write_b(`0`)
+ }
+ //===========================================
+
+ if p.allign == .left {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ return
+}
+
+[direct_array_access; manualfree]
+pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
+ unsafe {
+ // we add the rounding value
+ s := f64_to_str(f + dec_round[dec_digit], 18)
+ // check for +inf -inf Nan
+ if s.len > 2 && (s[0] == `n` || s[1] == `i`) {
+ return s
+ }
+
+ m_sgn_flag := false
+ mut sgn := 1
+ mut b := [26]byte{}
+ mut d_pos := 1
+ mut i := 0
+ mut i1 := 0
+ mut exp := 0
+ mut exp_sgn := 1
+
+ mut dot_res_sp := -1
+
+ // get sign and deciaml parts
+ for c in s {
+ if c == `-` {
+ sgn = -1
+ i++
+ } else if c == `+` {
+ sgn = 1
+ i++
+ } else if c >= `0` && c <= `9` {
+ b[i1] = c
+ i1++
+ i++
+ } else if c == `.` {
+ if sgn > 0 {
+ d_pos = i
+ } else {
+ d_pos = i - 1
+ }
+ i++
+ } else if c == `e` {
+ i++
+ break
+ } else {
+ s.free()
+ return '[Float conversion error!!]'
+ }
+ }
+ b[i1] = 0
+
+ // get exponent
+ if s[i] == `-` {
+ exp_sgn = -1
+ i++
+ } else if s[i] == `+` {
+ exp_sgn = 1
+ i++
+ }
+
+ mut c := i
+ for c < s.len {
+ exp = exp * 10 + int(s[c] - `0`)
+ c++
+ }
+
+ // allocate exp+32 chars for the return string
+ // mut res := []byte{len:exp+32,init:`0`}
+ mut res := []byte{len: exp + 32, init: 0}
+ mut r_i := 0 // result string buffer index
+
+ // println("s:${sgn} b:${b[0]} es:${exp_sgn} exp:${exp}")
+
+ // s no more needed
+ s.free()
+
+ if sgn == 1 {
+ if m_sgn_flag {
+ res[r_i] = `+`
+ r_i++
+ }
+ } else {
+ res[r_i] = `-`
+ r_i++
+ }
+
+ i = 0
+ if exp_sgn >= 0 {
+ for b[i] != 0 {
+ res[r_i] = b[i]
+ r_i++
+ i++
+ if i >= d_pos && exp >= 0 {
+ if exp == 0 {
+ dot_res_sp = r_i
+ res[r_i] = `.`
+ r_i++
+ }
+ exp--
+ }
+ }
+ for exp >= 0 {
+ res[r_i] = `0`
+ r_i++
+ exp--
+ }
+ // println("exp: $exp $r_i $dot_res_sp")
+ } else {
+ mut dot_p := true
+ for exp > 0 {
+ res[r_i] = `0`
+ r_i++
+ exp--
+ if dot_p {
+ dot_res_sp = r_i
+ res[r_i] = `.`
+ r_i++
+ dot_p = false
+ }
+ }
+ for b[i] != 0 {
+ res[r_i] = b[i]
+ r_i++
+ i++
+ }
+ }
+
+ // no more digits needed, stop here
+ if dec_digit <= 0 {
+ tmp_res := tos(res.data, dot_res_sp).clone()
+ res.free()
+ return tmp_res
+ }
+
+ // println("r_i-d_pos: ${r_i - d_pos}")
+ if dot_res_sp >= 0 {
+ if (r_i - dot_res_sp) > dec_digit {
+ r_i = dot_res_sp + dec_digit + 1
+ }
+ res[r_i] = 0
+ // println("result: [${tos(&res[0],r_i)}]")
+ tmp_res := tos(res.data, r_i).clone()
+ res.free()
+ return tmp_res
+ } else {
+ if dec_digit > 0 {
+ mut c1 := 0
+ res[r_i] = `.`
+ r_i++
+ for c1 < dec_digit {
+ res[r_i] = `0`
+ r_i++
+ c1++
+ }
+ res[r_i] = 0
+ }
+ tmp_res := tos(res.data, r_i).clone()
+ res.free()
+ return tmp_res
+ }
+ }
+}
+
+// strings.Builder version of format_fl
+[manualfree]
+pub fn format_fl(f f64, p BF_param) string {
+ unsafe {
+ mut s := ''
+ // mut fs := "1.2343"
+ mut fs := f64_to_str_lnd1(if f >= 0.0 { f } else { -f }, p.len1)
+ // println("Dario")
+ // println(fs)
+
+ // error!!
+ if fs[0] == `[` {
+ s.free()
+ return fs
+ }
+
+ if p.rm_tail_zero {
+ tmp := fs
+ fs = remove_tail_zeros(fs)
+ tmp.free()
+ }
+ mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
+
+ mut sign_len_diff := 0
+ if p.pad_ch == `0` {
+ if p.positive {
+ if p.sign_flag {
+ res.write_b(`+`)
+ sign_len_diff = -1
+ }
+ } else {
+ res.write_b(`-`)
+ sign_len_diff = -1
+ }
+ tmp := s
+ s = fs.clone()
+ tmp.free()
+ } else {
+ if p.positive {
+ if p.sign_flag {
+ tmp := s
+ s = '+' + fs
+ tmp.free()
+ } else {
+ tmp := s
+ s = fs.clone()
+ tmp.free()
+ }
+ } else {
+ tmp := s
+ s = '-' + fs
+ tmp.free()
+ }
+ }
+
+ dif := p.len0 - s.len + sign_len_diff
+
+ if p.allign == .right {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ res.write_string(s)
+ if p.allign == .left {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+
+ s.free()
+ fs.free()
+ tmp_res := res.str()
+ res.free()
+ return tmp_res
+ }
+}
+
+[manualfree]
+pub fn format_es(f f64, p BF_param) string {
+ unsafe {
+ mut s := ''
+ mut fs := f64_to_str_pad(if f > 0 { f } else { -f }, p.len1)
+ if p.rm_tail_zero {
+ fs = remove_tail_zeros(fs)
+ }
+ mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
+
+ mut sign_len_diff := 0
+ if p.pad_ch == `0` {
+ if p.positive {
+ if p.sign_flag {
+ res.write_b(`+`)
+ sign_len_diff = -1
+ }
+ } else {
+ res.write_b(`-`)
+ sign_len_diff = -1
+ }
+ tmp := s
+ s = fs.clone()
+ tmp.free()
+ } else {
+ if p.positive {
+ if p.sign_flag {
+ tmp := s
+ s = '+' + fs
+ tmp.free()
+ } else {
+ tmp := s
+ s = fs.clone()
+ tmp.free()
+ }
+ } else {
+ tmp := s
+ s = '-' + fs
+ tmp.free()
+ }
+ }
+
+ dif := p.len0 - s.len + sign_len_diff
+ if p.allign == .right {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ res.write_string(s)
+ if p.allign == .left {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ s.free()
+ fs.free()
+ tmp_res := res.str()
+ res.free()
+ return tmp_res
+ }
+}
+
+[direct_array_access]
+pub fn remove_tail_zeros(s string) string {
+ unsafe {
+ mut buf := malloc_noscan(s.len + 1)
+ mut i_d := 0
+ mut i_s := 0
+
+ // skip spaces
+ for i_s < s.len && s[i_s] !in [`-`, `+`] && (s[i_s] > `9` || s[i_s] < `0`) {
+ buf[i_d] = s[i_s]
+ i_s++
+ i_d++
+ }
+ // sign
+ if i_s < s.len && s[i_s] in [`-`, `+`] {
+ buf[i_d] = s[i_s]
+ i_s++
+ i_d++
+ }
+
+ // integer part
+ for i_s < s.len && s[i_s] >= `0` && s[i_s] <= `9` {
+ buf[i_d] = s[i_s]
+ i_s++
+ i_d++
+ }
+
+ // check decimals
+ if i_s < s.len && s[i_s] == `.` {
+ mut i_s1 := i_s + 1
+ mut sum := 0
+ for i_s1 < s.len && s[i_s1] >= `0` && s[i_s1] <= `9` {
+ sum += s[i_s1] - byte(`0`)
+ i_s1++
+ }
+ // decimal part must be copied
+ if sum > 0 {
+ for c_i in i_s .. i_s1 {
+ buf[i_d] = s[c_i]
+ i_d++
+ }
+ }
+ i_s = i_s1
+ }
+
+ if i_s < s.len && s[i_s] != `.` {
+ // check exponent
+ for {
+ buf[i_d] = s[i_s]
+ i_s++
+ i_d++
+ if i_s >= s.len {
+ break
+ }
+ }
+ }
+
+ buf[i_d] = 0
+ return tos(buf, i_d)
+ }
+}
diff --git a/v_windows/v/vlib/strconv/format_test.v b/v_windows/v/vlib/strconv/format_test.v
new file mode 100644
index 0000000..745318b
--- /dev/null
+++ b/v_windows/v/vlib/strconv/format_test.v
@@ -0,0 +1,110 @@
+import strconv
+
+fn test_format() {
+ mut temp_s := ''
+ mut tmp_str := ''
+ a0 := u32(10)
+ b0 := 200
+ c0 := byte(12)
+ s0 := 'ciAo'
+ ch0 := `B`
+ f0 := 0.312345
+ f1 := 200000.0
+ f2 := -1234.300e6
+ f3 := 1234.300e-6
+
+ sc0 := 'ciao: [%-08u] %d %hhd [%8s] [%08X] [%-20.4f] [%-20.4f] [%c]'
+ temp_s = strconv.v_sprintf(sc0, a0, b0, c0, s0, b0, f0, f1, ch0)
+ tmp_str = 'ciao: [10 ] 200 12 [ ciAo] [000000C8] [0.3123 ] [200000.0000 ] [B]'
+ // C.printf(sc0.str,a0 ,b0 ,c0 ,s0.str ,b0 ,f0, f1, ch0)
+ // println("\n$temp_s")
+ assert tmp_str == temp_s
+
+ a := byte(12)
+ b := i16(13)
+ c := 14
+ d := i64(15)
+ sc1 := '==>%hhd %hd %d %ld'
+ temp_s = strconv.v_sprintf(sc1, a, b, c, d)
+ tmp_str = '==>12 13 14 15'
+ // C.printf(sc1.str, a ,b ,c, d)
+ // println("\n$temp_s")
+ assert tmp_str == temp_s
+
+ a1 := byte(0xff)
+ b1 := i16(0xffff)
+ c1 := u32(0xffff_ffff)
+ d1 := u64(-1)
+ sc2 := '%hhu %hu %u %lu'
+ temp_s = strconv.v_sprintf(sc2, a1, b1, c1, d1)
+ tmp_str = '255 65535 4294967295 18446744073709551615'
+ // C.printf(sc2.str, a1 ,b1 ,c1, d1)
+ // println("\n$temp_s")
+ assert tmp_str == temp_s
+
+ sc3 := '%hhx %hx %x %lx'
+ temp_s = strconv.v_sprintf(sc3, a1, b1, c1, d1)
+ tmp_str = 'ff ffff ffffffff ffffffffffffffff'
+ // C.printf(sc3.str, a1 ,b1 ,c1, d1)
+ // println("\n$temp_s")
+ assert tmp_str == temp_s
+
+ sc4 := '[%-20.3e] [%20.3e] [%-020.3e] [%-020.3E] [%-020.3e] [%-020.3e]'
+ temp_s = strconv.v_sprintf(sc4, f0, f1, f1, f1, f2, f3)
+ tmp_str = '[3.123e-01 ] [ 2.000e+05] [2.000e+05 ] [2.000E+05 ] [-1.234e+09 ] [1.234e-03 ]'
+ // C.printf(sc4.str, f0, f1, f1, f1, f2, f3)
+ // println("\n$temp_s")
+ assert tmp_str == temp_s
+
+ sc5 := '[%.3f] [%0.3f] [%0.3F] [%0.3f] [%0.3F]'
+ temp_s = strconv.v_sprintf(sc5, f0, f1, f1, f2, f3)
+ tmp_str = '[0.312] [200000.000] [200000.000] [-1234300000.000] [0.001]'
+ // C.printf(sc5.str, f0, f1, f1, f2, f3, f3)
+ // println("\n$temp_s")
+ assert tmp_str == temp_s
+
+ ml := 3
+ sc6 := '%.*s [%05hhX]'
+ temp_s = strconv.v_sprintf(sc6, ml, s0, a)
+ tmp_str = 'ciA [0000C]'
+ // C.printf(sc6.str, ml, s0.str, a)
+ // println("\n$temp_s")
+ assert tmp_str == temp_s
+
+ a2 := 125
+ sc7 := '[%9x] [%9X] [%-9x] [%-9X] [%09x] [%09X]'
+ temp_s = strconv.v_sprintf(sc7, a2, a2, a2, a2, a2, a2)
+ tmp_str = '[ 7d] [ 7D] [7d ] [7D ] [00000007d] [00000007D]'
+ // C.printf(sc7.str, a2, a2, a2, a2, a2, a2)
+ // println("\n$temp_s")
+ assert tmp_str == temp_s
+
+ g_test := [
+ '[ -1e-07][ -1E-07]|',
+ '[ -1e-06][ -1E-06]|',
+ '[ -1e-05][ -1E-05]|',
+ '[ -0.0001][ -0.0001]|',
+ '[ -0.001][ -0.001]|',
+ '[ -0.01][ -0.01]|',
+ '[ -0.1][ -0.1]|',
+ '[ -1][ -1]|',
+ '[ -10][ -10]|',
+ '[ -100][ -100]|',
+ '[ -1000][ -1000]|',
+ '[ -10000][ -10000]|',
+ ]
+
+ mut ft := -1e-7
+ mut x := 0
+ mut cnt := 0
+ sc8 := '[%20g][%20G]|'
+ for x < 12 {
+ temp_s = strconv.v_sprintf(sc8, ft, ft)
+ // C.printf(sc8.str, ft, ft)
+ // println("\n$temp_s")
+ assert temp_s == g_test[cnt]
+ ft = ft * 10.0
+ x++
+ cnt++
+ }
+}
diff --git a/v_windows/v/vlib/strconv/ftoa.v b/v_windows/v/vlib/strconv/ftoa.v
new file mode 100644
index 0000000..700ecc7
--- /dev/null
+++ b/v_windows/v/vlib/strconv/ftoa.v
@@ -0,0 +1,39 @@
+module strconv
+
+/*
+f32/f64 ftoa functions
+
+Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
+Use of this source code is governed by an MIT license
+that can be found in the LICENSE file.
+
+This file contains the f32/f64 ftoa functions
+
+These functions are based on the work of:
+Publication:PLDI 2018: Proceedings of the 39th ACM SIGPLAN
+Conference on Programming Language Design and ImplementationJune 2018
+Pages 270–282 https://doi.org/10.1145/3192366.3192369
+
+inspired by the Go version here:
+https://github.com/cespare/ryu/tree/ba56a33f39e3bbbfa409095d0f9ae168a595feea
+*/
+
+[inline]
+pub fn ftoa_64(f f64) string {
+ return f64_to_str(f, 17)
+}
+
+[inline]
+pub fn ftoa_long_64(f f64) string {
+ return f64_to_str_l(f)
+}
+
+[inline]
+pub fn ftoa_32(f f32) string {
+ return f32_to_str(f, 8)
+}
+
+[inline]
+pub fn ftoa_long_32(f f32) string {
+ return f32_to_str_l(f)
+}
diff --git a/v_windows/v/vlib/strconv/number_to_base.v b/v_windows/v/vlib/strconv/number_to_base.v
new file mode 100644
index 0000000..0ca7e9c
--- /dev/null
+++ b/v_windows/v/vlib/strconv/number_to_base.v
@@ -0,0 +1,61 @@
+module strconv
+
+const base_digits = '0123456789abcdefghijklmnopqrstuvwxyz'
+
+// format_int returns the string representation of the number n in base `radix`
+// for digit values > 10, this function uses the small latin leters a-z.
+[manualfree]
+pub fn format_int(n i64, radix int) string {
+ unsafe {
+ if radix < 2 || radix > 36 {
+ panic('invalid radix: $radix . It should be => 2 and <= 36')
+ }
+ if n == 0 {
+ return '0'
+ }
+ mut n_copy := n
+ mut sign := ''
+ if n < 0 {
+ sign = '-'
+ n_copy = -n_copy
+ }
+ mut res := ''
+ for n_copy != 0 {
+ tmp_0 := res
+ tmp_1 := strconv.base_digits[n_copy % radix].ascii_str()
+ res = tmp_1 + res
+ tmp_0.free()
+ tmp_1.free()
+ // res = base_digits[n_copy % radix].ascii_str() + res
+ n_copy /= radix
+ }
+ return '$sign$res'
+ }
+}
+
+// format_uint returns the string representation of the number n in base `radix`
+// for digit values > 10, this function uses the small latin leters a-z.
+[manualfree]
+pub fn format_uint(n u64, radix int) string {
+ unsafe {
+ if radix < 2 || radix > 36 {
+ panic('invalid radix: $radix . It should be => 2 and <= 36')
+ }
+ if n == 0 {
+ return '0'
+ }
+ mut n_copy := n
+ mut res := ''
+ uradix := u64(radix)
+ for n_copy != 0 {
+ tmp_0 := res
+ tmp_1 := strconv.base_digits[n_copy % uradix].ascii_str()
+ res = tmp_1 + res
+ tmp_0.free()
+ tmp_1.free()
+ // res = base_digits[n_copy % uradix].ascii_str() + res
+ n_copy /= uradix
+ }
+ return res
+ }
+}
diff --git a/v_windows/v/vlib/strconv/number_to_base_test.v b/v_windows/v/vlib/strconv/number_to_base_test.v
new file mode 100644
index 0000000..b313b0f
--- /dev/null
+++ b/v_windows/v/vlib/strconv/number_to_base_test.v
@@ -0,0 +1,38 @@
+import strconv
+
+fn test_format_int() {
+ assert strconv.format_int(0, 2) == '0'
+ assert strconv.format_int(0, 10) == '0'
+ assert strconv.format_int(0, 16) == '0'
+ assert strconv.format_int(0, 36) == '0'
+ assert strconv.format_int(1, 2) == '1'
+ assert strconv.format_int(1, 10) == '1'
+ assert strconv.format_int(1, 16) == '1'
+ assert strconv.format_int(1, 36) == '1'
+ assert strconv.format_int(-1, 2) == '-1'
+ assert strconv.format_int(-1, 10) == '-1'
+ assert strconv.format_int(-1, 16) == '-1'
+ assert strconv.format_int(-1, 36) == '-1'
+ assert strconv.format_int(255, 2) == '11111111'
+ assert strconv.format_int(255, 8) == '377'
+ assert strconv.format_int(255, 10) == '255'
+ assert strconv.format_int(255, 16) == 'ff'
+ assert strconv.format_int(-255, 2) == '-11111111'
+ assert strconv.format_int(-255, 8) == '-377'
+ assert strconv.format_int(-255, 10) == '-255'
+ assert strconv.format_int(-255, 16) == '-ff'
+ for i in -256 .. 256 {
+ assert strconv.format_int(i, 10) == i.str()
+ }
+}
+
+fn test_format_uint() {
+ assert strconv.format_uint(0, 2) == '0'
+ assert strconv.format_int(255, 2) == '11111111'
+ assert strconv.format_int(255, 8) == '377'
+ assert strconv.format_int(255, 10) == '255'
+ assert strconv.format_int(255, 16) == 'ff'
+ assert strconv.format_uint(18446744073709551615, 2) == '1111111111111111111111111111111111111111111111111111111111111111'
+ assert strconv.format_uint(18446744073709551615, 16) == 'ffffffffffffffff'
+ assert strconv.format_uint(683058467, 36) == 'baobab'
+}
diff --git a/v_windows/v/vlib/strconv/structs.v b/v_windows/v/vlib/strconv/structs.v
new file mode 100644
index 0000000..35ade80
--- /dev/null
+++ b/v_windows/v/vlib/strconv/structs.v
@@ -0,0 +1,55 @@
+module strconv
+
+// The structure is filled by parser, then given to converter.
+pub struct PrepNumber {
+pub mut:
+ negative bool // 0 if positive number, 1 if negative
+ exponent int // power of 10 exponent
+ mantissa u64 // integer mantissa
+}
+
+// dec32 is a floating decimal type representing m * 10^e.
+struct Dec32 {
+mut:
+ m u32
+ e int
+}
+
+// dec64 is a floating decimal type representing m * 10^e.
+struct Dec64 {
+mut:
+ m u64
+ e int
+}
+
+struct Uint128 {
+mut:
+ lo u64
+ hi u64
+}
+
+// support union for convert f32 to u32
+union Uf32 {
+mut:
+ f f32
+ u u32
+}
+
+// support union for convert f64 to u64
+union Uf64 {
+mut:
+ f f64
+ u u64
+}
+
+pub union Float64u {
+pub mut:
+ f f64
+ u u64
+}
+
+pub union Float32u {
+pub mut:
+ f f32
+ u u32
+}
diff --git a/v_windows/v/vlib/strconv/tables.v b/v_windows/v/vlib/strconv/tables.v
new file mode 100644
index 0000000..4f6d3ac
--- /dev/null
+++ b/v_windows/v/vlib/strconv/tables.v
@@ -0,0 +1,738 @@
+module strconv
+
+const (
+ pow5_num_bits_32 = 61
+ pow5_inv_num_bits_32 = 59
+ pow5_num_bits_64 = 121
+ pow5_inv_num_bits_64 = 122
+
+ powers_of_10 = [
+ u64(1e0),
+ u64(1e1),
+ u64(1e2),
+ u64(1e3),
+ u64(1e4),
+ u64(1e5),
+ u64(1e6),
+ u64(1e7),
+ u64(1e8),
+ u64(1e9),
+ u64(1e10),
+ u64(1e11),
+ u64(1e12),
+ u64(1e13),
+ u64(1e14),
+ u64(1e15),
+ u64(1e16),
+ u64(1e17)
+ // We only need to find the length of at most 17 digit numbers.
+ ]
+
+ pow5_split_32 = [
+ u64(1152921504606846976),
+ u64(1441151880758558720),
+ u64(1801439850948198400),
+ u64(2251799813685248000),
+ u64(1407374883553280000),
+ u64(1759218604441600000),
+ u64(2199023255552000000),
+ u64(1374389534720000000),
+ u64(1717986918400000000),
+ u64(2147483648000000000),
+ u64(1342177280000000000),
+ u64(1677721600000000000),
+ u64(2097152000000000000),
+ u64(1310720000000000000),
+ u64(1638400000000000000),
+ u64(2048000000000000000),
+ u64(1280000000000000000),
+ u64(1600000000000000000),
+ u64(2000000000000000000),
+ u64(1250000000000000000),
+ u64(1562500000000000000),
+ u64(1953125000000000000),
+ u64(1220703125000000000),
+ u64(1525878906250000000),
+ u64(1907348632812500000),
+ u64(1192092895507812500),
+ u64(1490116119384765625),
+ u64(1862645149230957031),
+ u64(1164153218269348144),
+ u64(1455191522836685180),
+ u64(1818989403545856475),
+ u64(2273736754432320594),
+ u64(1421085471520200371),
+ u64(1776356839400250464),
+ u64(2220446049250313080),
+ u64(1387778780781445675),
+ u64(1734723475976807094),
+ u64(2168404344971008868),
+ u64(1355252715606880542),
+ u64(1694065894508600678),
+ u64(2117582368135750847),
+ u64(1323488980084844279),
+ u64(1654361225106055349),
+ u64(2067951531382569187),
+ u64(1292469707114105741),
+ u64(1615587133892632177),
+ u64(2019483917365790221),
+ ]
+
+ pow5_inv_split_32 = [
+ u64(576460752303423489),
+ u64(461168601842738791),
+ u64(368934881474191033),
+ u64(295147905179352826),
+ u64(472236648286964522),
+ u64(377789318629571618),
+ u64(302231454903657294),
+ u64(483570327845851670),
+ u64(386856262276681336),
+ u64(309485009821345069),
+ u64(495176015714152110),
+ u64(396140812571321688),
+ u64(316912650057057351),
+ u64(507060240091291761),
+ u64(405648192073033409),
+ u64(324518553658426727),
+ u64(519229685853482763),
+ u64(415383748682786211),
+ u64(332306998946228969),
+ u64(531691198313966350),
+ u64(425352958651173080),
+ u64(340282366920938464),
+ u64(544451787073501542),
+ u64(435561429658801234),
+ u64(348449143727040987),
+ u64(557518629963265579),
+ u64(446014903970612463),
+ u64(356811923176489971),
+ u64(570899077082383953),
+ u64(456719261665907162),
+ u64(365375409332725730),
+ ]
+
+ pow5_split_64 = [
+ Uint128{u64(0x0000000000000000), u64(0x0100000000000000)},
+ Uint128{u64(0x0000000000000000), u64(0x0140000000000000)},
+ Uint128{u64(0x0000000000000000), u64(0x0190000000000000)},
+ Uint128{u64(0x0000000000000000), u64(0x01f4000000000000)},
+ Uint128{u64(0x0000000000000000), u64(0x0138800000000000)},
+ Uint128{u64(0x0000000000000000), u64(0x0186a00000000000)},
+ Uint128{u64(0x0000000000000000), u64(0x01e8480000000000)},
+ Uint128{u64(0x0000000000000000), u64(0x01312d0000000000)},
+ Uint128{u64(0x0000000000000000), u64(0x017d784000000000)},
+ Uint128{u64(0x0000000000000000), u64(0x01dcd65000000000)},
+ Uint128{u64(0x0000000000000000), u64(0x012a05f200000000)},
+ Uint128{u64(0x0000000000000000), u64(0x0174876e80000000)},
+ Uint128{u64(0x0000000000000000), u64(0x01d1a94a20000000)},
+ Uint128{u64(0x0000000000000000), u64(0x012309ce54000000)},
+ Uint128{u64(0x0000000000000000), u64(0x016bcc41e9000000)},
+ Uint128{u64(0x0000000000000000), u64(0x01c6bf5263400000)},
+ Uint128{u64(0x0000000000000000), u64(0x011c37937e080000)},
+ Uint128{u64(0x0000000000000000), u64(0x016345785d8a0000)},
+ Uint128{u64(0x0000000000000000), u64(0x01bc16d674ec8000)},
+ Uint128{u64(0x0000000000000000), u64(0x01158e460913d000)},
+ Uint128{u64(0x0000000000000000), u64(0x015af1d78b58c400)},
+ Uint128{u64(0x0000000000000000), u64(0x01b1ae4d6e2ef500)},
+ Uint128{u64(0x0000000000000000), u64(0x010f0cf064dd5920)},
+ Uint128{u64(0x0000000000000000), u64(0x0152d02c7e14af68)},
+ Uint128{u64(0x0000000000000000), u64(0x01a784379d99db42)},
+ Uint128{u64(0x4000000000000000), u64(0x0108b2a2c2802909)},
+ Uint128{u64(0x9000000000000000), u64(0x014adf4b7320334b)},
+ Uint128{u64(0x7400000000000000), u64(0x019d971e4fe8401e)},
+ Uint128{u64(0x0880000000000000), u64(0x01027e72f1f12813)},
+ Uint128{u64(0xcaa0000000000000), u64(0x01431e0fae6d7217)},
+ Uint128{u64(0xbd48000000000000), u64(0x0193e5939a08ce9d)},
+ Uint128{u64(0x2c9a000000000000), u64(0x01f8def8808b0245)},
+ Uint128{u64(0x3be0400000000000), u64(0x013b8b5b5056e16b)},
+ Uint128{u64(0x0ad8500000000000), u64(0x018a6e32246c99c6)},
+ Uint128{u64(0x8d8e640000000000), u64(0x01ed09bead87c037)},
+ Uint128{u64(0xb878fe8000000000), u64(0x013426172c74d822)},
+ Uint128{u64(0x66973e2000000000), u64(0x01812f9cf7920e2b)},
+ Uint128{u64(0x403d0da800000000), u64(0x01e17b84357691b6)},
+ Uint128{u64(0xe826288900000000), u64(0x012ced32a16a1b11)},
+ Uint128{u64(0x622fb2ab40000000), u64(0x0178287f49c4a1d6)},
+ Uint128{u64(0xfabb9f5610000000), u64(0x01d6329f1c35ca4b)},
+ Uint128{u64(0x7cb54395ca000000), u64(0x0125dfa371a19e6f)},
+ Uint128{u64(0x5be2947b3c800000), u64(0x016f578c4e0a060b)},
+ Uint128{u64(0x32db399a0ba00000), u64(0x01cb2d6f618c878e)},
+ Uint128{u64(0xdfc9040047440000), u64(0x011efc659cf7d4b8)},
+ Uint128{u64(0x17bb450059150000), u64(0x0166bb7f0435c9e7)},
+ Uint128{u64(0xddaa16406f5a4000), u64(0x01c06a5ec5433c60)},
+ Uint128{u64(0x8a8a4de845986800), u64(0x0118427b3b4a05bc)},
+ Uint128{u64(0xad2ce16256fe8200), u64(0x015e531a0a1c872b)},
+ Uint128{u64(0x987819baecbe2280), u64(0x01b5e7e08ca3a8f6)},
+ Uint128{u64(0x1f4b1014d3f6d590), u64(0x0111b0ec57e6499a)},
+ Uint128{u64(0xa71dd41a08f48af4), u64(0x01561d276ddfdc00)},
+ Uint128{u64(0xd0e549208b31adb1), u64(0x01aba4714957d300)},
+ Uint128{u64(0x828f4db456ff0c8e), u64(0x010b46c6cdd6e3e0)},
+ Uint128{u64(0xa33321216cbecfb2), u64(0x014e1878814c9cd8)},
+ Uint128{u64(0xcbffe969c7ee839e), u64(0x01a19e96a19fc40e)},
+ Uint128{u64(0x3f7ff1e21cf51243), u64(0x0105031e2503da89)},
+ Uint128{u64(0x8f5fee5aa43256d4), u64(0x014643e5ae44d12b)},
+ Uint128{u64(0x7337e9f14d3eec89), u64(0x0197d4df19d60576)},
+ Uint128{u64(0x1005e46da08ea7ab), u64(0x01fdca16e04b86d4)},
+ Uint128{u64(0x8a03aec4845928cb), u64(0x013e9e4e4c2f3444)},
+ Uint128{u64(0xac849a75a56f72fd), u64(0x018e45e1df3b0155)},
+ Uint128{u64(0x17a5c1130ecb4fbd), u64(0x01f1d75a5709c1ab)},
+ Uint128{u64(0xeec798abe93f11d6), u64(0x013726987666190a)},
+ Uint128{u64(0xaa797ed6e38ed64b), u64(0x0184f03e93ff9f4d)},
+ Uint128{u64(0x1517de8c9c728bde), u64(0x01e62c4e38ff8721)},
+ Uint128{u64(0xad2eeb17e1c7976b), u64(0x012fdbb0e39fb474)},
+ Uint128{u64(0xd87aa5ddda397d46), u64(0x017bd29d1c87a191)},
+ Uint128{u64(0x4e994f5550c7dc97), u64(0x01dac74463a989f6)},
+ Uint128{u64(0xf11fd195527ce9de), u64(0x0128bc8abe49f639)},
+ Uint128{u64(0x6d67c5faa71c2456), u64(0x0172ebad6ddc73c8)},
+ Uint128{u64(0x88c1b77950e32d6c), u64(0x01cfa698c95390ba)},
+ Uint128{u64(0x957912abd28dfc63), u64(0x0121c81f7dd43a74)},
+ Uint128{u64(0xbad75756c7317b7c), u64(0x016a3a275d494911)},
+ Uint128{u64(0x298d2d2c78fdda5b), u64(0x01c4c8b1349b9b56)},
+ Uint128{u64(0xd9f83c3bcb9ea879), u64(0x011afd6ec0e14115)},
+ Uint128{u64(0x50764b4abe865297), u64(0x0161bcca7119915b)},
+ Uint128{u64(0x2493de1d6e27e73d), u64(0x01ba2bfd0d5ff5b2)},
+ Uint128{u64(0x56dc6ad264d8f086), u64(0x01145b7e285bf98f)},
+ Uint128{u64(0x2c938586fe0f2ca8), u64(0x0159725db272f7f3)},
+ Uint128{u64(0xf7b866e8bd92f7d2), u64(0x01afcef51f0fb5ef)},
+ Uint128{u64(0xfad34051767bdae3), u64(0x010de1593369d1b5)},
+ Uint128{u64(0x79881065d41ad19c), u64(0x015159af80444623)},
+ Uint128{u64(0x57ea147f49218603), u64(0x01a5b01b605557ac)},
+ Uint128{u64(0xb6f24ccf8db4f3c1), u64(0x01078e111c3556cb)},
+ Uint128{u64(0xa4aee003712230b2), u64(0x014971956342ac7e)},
+ Uint128{u64(0x4dda98044d6abcdf), u64(0x019bcdfabc13579e)},
+ Uint128{u64(0xf0a89f02b062b60b), u64(0x010160bcb58c16c2)},
+ Uint128{u64(0xacd2c6c35c7b638e), u64(0x0141b8ebe2ef1c73)},
+ Uint128{u64(0x98077874339a3c71), u64(0x01922726dbaae390)},
+ Uint128{u64(0xbe0956914080cb8e), u64(0x01f6b0f092959c74)},
+ Uint128{u64(0xf6c5d61ac8507f38), u64(0x013a2e965b9d81c8)},
+ Uint128{u64(0x34774ba17a649f07), u64(0x0188ba3bf284e23b)},
+ Uint128{u64(0x01951e89d8fdc6c8), u64(0x01eae8caef261aca)},
+ Uint128{u64(0x40fd3316279e9c3d), u64(0x0132d17ed577d0be)},
+ Uint128{u64(0xd13c7fdbb186434c), u64(0x017f85de8ad5c4ed)},
+ Uint128{u64(0x458b9fd29de7d420), u64(0x01df67562d8b3629)},
+ Uint128{u64(0xcb7743e3a2b0e494), u64(0x012ba095dc7701d9)},
+ Uint128{u64(0x3e5514dc8b5d1db9), u64(0x017688bb5394c250)},
+ Uint128{u64(0x4dea5a13ae346527), u64(0x01d42aea2879f2e4)},
+ Uint128{u64(0xb0b2784c4ce0bf38), u64(0x01249ad2594c37ce)},
+ Uint128{u64(0x5cdf165f6018ef06), u64(0x016dc186ef9f45c2)},
+ Uint128{u64(0xf416dbf7381f2ac8), u64(0x01c931e8ab871732)},
+ Uint128{u64(0xd88e497a83137abd), u64(0x011dbf316b346e7f)},
+ Uint128{u64(0xceb1dbd923d8596c), u64(0x01652efdc6018a1f)},
+ Uint128{u64(0xc25e52cf6cce6fc7), u64(0x01be7abd3781eca7)},
+ Uint128{u64(0xd97af3c1a40105dc), u64(0x01170cb642b133e8)},
+ Uint128{u64(0x0fd9b0b20d014754), u64(0x015ccfe3d35d80e3)},
+ Uint128{u64(0xd3d01cde90419929), u64(0x01b403dcc834e11b)},
+ Uint128{u64(0x6462120b1a28ffb9), u64(0x01108269fd210cb1)},
+ Uint128{u64(0xbd7a968de0b33fa8), u64(0x0154a3047c694fdd)},
+ Uint128{u64(0x2cd93c3158e00f92), u64(0x01a9cbc59b83a3d5)},
+ Uint128{u64(0x3c07c59ed78c09bb), u64(0x010a1f5b81324665)},
+ Uint128{u64(0x8b09b7068d6f0c2a), u64(0x014ca732617ed7fe)},
+ Uint128{u64(0x2dcc24c830cacf34), u64(0x019fd0fef9de8dfe)},
+ Uint128{u64(0xdc9f96fd1e7ec180), u64(0x0103e29f5c2b18be)},
+ Uint128{u64(0x93c77cbc661e71e1), u64(0x0144db473335deee)},
+ Uint128{u64(0x38b95beb7fa60e59), u64(0x01961219000356aa)},
+ Uint128{u64(0xc6e7b2e65f8f91ef), u64(0x01fb969f40042c54)},
+ Uint128{u64(0xfc50cfcffbb9bb35), u64(0x013d3e2388029bb4)},
+ Uint128{u64(0x3b6503c3faa82a03), u64(0x018c8dac6a0342a2)},
+ Uint128{u64(0xca3e44b4f9523484), u64(0x01efb1178484134a)},
+ Uint128{u64(0xbe66eaf11bd360d2), u64(0x0135ceaeb2d28c0e)},
+ Uint128{u64(0x6e00a5ad62c83907), u64(0x0183425a5f872f12)},
+ Uint128{u64(0x0980cf18bb7a4749), u64(0x01e412f0f768fad7)},
+ Uint128{u64(0x65f0816f752c6c8d), u64(0x012e8bd69aa19cc6)},
+ Uint128{u64(0xff6ca1cb527787b1), u64(0x017a2ecc414a03f7)},
+ Uint128{u64(0xff47ca3e2715699d), u64(0x01d8ba7f519c84f5)},
+ Uint128{u64(0xbf8cde66d86d6202), u64(0x0127748f9301d319)},
+ Uint128{u64(0x2f7016008e88ba83), u64(0x017151b377c247e0)},
+ Uint128{u64(0x3b4c1b80b22ae923), u64(0x01cda62055b2d9d8)},
+ Uint128{u64(0x250f91306f5ad1b6), u64(0x012087d4358fc827)},
+ Uint128{u64(0xee53757c8b318623), u64(0x0168a9c942f3ba30)},
+ Uint128{u64(0x29e852dbadfde7ac), u64(0x01c2d43b93b0a8bd)},
+ Uint128{u64(0x3a3133c94cbeb0cc), u64(0x0119c4a53c4e6976)},
+ Uint128{u64(0xc8bd80bb9fee5cff), u64(0x016035ce8b6203d3)},
+ Uint128{u64(0xbaece0ea87e9f43e), u64(0x01b843422e3a84c8)},
+ Uint128{u64(0x74d40c9294f238a7), u64(0x01132a095ce492fd)},
+ Uint128{u64(0xd2090fb73a2ec6d1), u64(0x0157f48bb41db7bc)},
+ Uint128{u64(0x068b53a508ba7885), u64(0x01adf1aea12525ac)},
+ Uint128{u64(0x8417144725748b53), u64(0x010cb70d24b7378b)},
+ Uint128{u64(0x651cd958eed1ae28), u64(0x014fe4d06de5056e)},
+ Uint128{u64(0xfe640faf2a8619b2), u64(0x01a3de04895e46c9)},
+ Uint128{u64(0x3efe89cd7a93d00f), u64(0x01066ac2d5daec3e)},
+ Uint128{u64(0xcebe2c40d938c413), u64(0x014805738b51a74d)},
+ Uint128{u64(0x426db7510f86f518), u64(0x019a06d06e261121)},
+ Uint128{u64(0xc9849292a9b4592f), u64(0x0100444244d7cab4)},
+ Uint128{u64(0xfbe5b73754216f7a), u64(0x01405552d60dbd61)},
+ Uint128{u64(0x7adf25052929cb59), u64(0x01906aa78b912cba)},
+ Uint128{u64(0x1996ee4673743e2f), u64(0x01f485516e7577e9)},
+ Uint128{u64(0xaffe54ec0828a6dd), u64(0x0138d352e5096af1)},
+ Uint128{u64(0x1bfdea270a32d095), u64(0x018708279e4bc5ae)},
+ Uint128{u64(0xa2fd64b0ccbf84ba), u64(0x01e8ca3185deb719)},
+ Uint128{u64(0x05de5eee7ff7b2f4), u64(0x01317e5ef3ab3270)},
+ Uint128{u64(0x0755f6aa1ff59fb1), u64(0x017dddf6b095ff0c)},
+ Uint128{u64(0x092b7454a7f3079e), u64(0x01dd55745cbb7ecf)},
+ Uint128{u64(0x65bb28b4e8f7e4c3), u64(0x012a5568b9f52f41)},
+ Uint128{u64(0xbf29f2e22335ddf3), u64(0x0174eac2e8727b11)},
+ Uint128{u64(0x2ef46f9aac035570), u64(0x01d22573a28f19d6)},
+ Uint128{u64(0xdd58c5c0ab821566), u64(0x0123576845997025)},
+ Uint128{u64(0x54aef730d6629ac0), u64(0x016c2d4256ffcc2f)},
+ Uint128{u64(0x29dab4fd0bfb4170), u64(0x01c73892ecbfbf3b)},
+ Uint128{u64(0xfa28b11e277d08e6), u64(0x011c835bd3f7d784)},
+ Uint128{u64(0x38b2dd65b15c4b1f), u64(0x0163a432c8f5cd66)},
+ Uint128{u64(0xc6df94bf1db35de7), u64(0x01bc8d3f7b3340bf)},
+ Uint128{u64(0xdc4bbcf772901ab0), u64(0x0115d847ad000877)},
+ Uint128{u64(0xd35eac354f34215c), u64(0x015b4e5998400a95)},
+ Uint128{u64(0x48365742a30129b4), u64(0x01b221effe500d3b)},
+ Uint128{u64(0x0d21f689a5e0ba10), u64(0x010f5535fef20845)},
+ Uint128{u64(0x506a742c0f58e894), u64(0x01532a837eae8a56)},
+ Uint128{u64(0xe4851137132f22b9), u64(0x01a7f5245e5a2ceb)},
+ Uint128{u64(0x6ed32ac26bfd75b4), u64(0x0108f936baf85c13)},
+ Uint128{u64(0x4a87f57306fcd321), u64(0x014b378469b67318)},
+ Uint128{u64(0x5d29f2cfc8bc07e9), u64(0x019e056584240fde)},
+ Uint128{u64(0xfa3a37c1dd7584f1), u64(0x0102c35f729689ea)},
+ Uint128{u64(0xb8c8c5b254d2e62e), u64(0x014374374f3c2c65)},
+ Uint128{u64(0x26faf71eea079fb9), u64(0x01945145230b377f)},
+ Uint128{u64(0xf0b9b4e6a48987a8), u64(0x01f965966bce055e)},
+ Uint128{u64(0x5674111026d5f4c9), u64(0x013bdf7e0360c35b)},
+ Uint128{u64(0x2c111554308b71fb), u64(0x018ad75d8438f432)},
+ Uint128{u64(0xb7155aa93cae4e7a), u64(0x01ed8d34e547313e)},
+ Uint128{u64(0x326d58a9c5ecf10c), u64(0x013478410f4c7ec7)},
+ Uint128{u64(0xff08aed437682d4f), u64(0x01819651531f9e78)},
+ Uint128{u64(0x3ecada89454238a3), u64(0x01e1fbe5a7e78617)},
+ Uint128{u64(0x873ec895cb496366), u64(0x012d3d6f88f0b3ce)},
+ Uint128{u64(0x290e7abb3e1bbc3f), u64(0x01788ccb6b2ce0c2)},
+ Uint128{u64(0xb352196a0da2ab4f), u64(0x01d6affe45f818f2)},
+ Uint128{u64(0xb0134fe24885ab11), u64(0x01262dfeebbb0f97)},
+ Uint128{u64(0x9c1823dadaa715d6), u64(0x016fb97ea6a9d37d)},
+ Uint128{u64(0x031e2cd19150db4b), u64(0x01cba7de5054485d)},
+ Uint128{u64(0x21f2dc02fad2890f), u64(0x011f48eaf234ad3a)},
+ Uint128{u64(0xaa6f9303b9872b53), u64(0x01671b25aec1d888)},
+ Uint128{u64(0xd50b77c4a7e8f628), u64(0x01c0e1ef1a724eaa)},
+ Uint128{u64(0xc5272adae8f199d9), u64(0x01188d357087712a)},
+ Uint128{u64(0x7670f591a32e004f), u64(0x015eb082cca94d75)},
+ Uint128{u64(0xd40d32f60bf98063), u64(0x01b65ca37fd3a0d2)},
+ Uint128{u64(0xc4883fd9c77bf03e), u64(0x0111f9e62fe44483)},
+ Uint128{u64(0xb5aa4fd0395aec4d), u64(0x0156785fbbdd55a4)},
+ Uint128{u64(0xe314e3c447b1a760), u64(0x01ac1677aad4ab0d)},
+ Uint128{u64(0xaded0e5aaccf089c), u64(0x010b8e0acac4eae8)},
+ Uint128{u64(0xd96851f15802cac3), u64(0x014e718d7d7625a2)},
+ Uint128{u64(0x8fc2666dae037d74), u64(0x01a20df0dcd3af0b)},
+ Uint128{u64(0x39d980048cc22e68), u64(0x010548b68a044d67)},
+ Uint128{u64(0x084fe005aff2ba03), u64(0x01469ae42c8560c1)},
+ Uint128{u64(0x4a63d8071bef6883), u64(0x0198419d37a6b8f1)},
+ Uint128{u64(0x9cfcce08e2eb42a4), u64(0x01fe52048590672d)},
+ Uint128{u64(0x821e00c58dd309a7), u64(0x013ef342d37a407c)},
+ Uint128{u64(0xa2a580f6f147cc10), u64(0x018eb0138858d09b)},
+ Uint128{u64(0x8b4ee134ad99bf15), u64(0x01f25c186a6f04c2)},
+ Uint128{u64(0x97114cc0ec80176d), u64(0x0137798f428562f9)},
+ Uint128{u64(0xfcd59ff127a01d48), u64(0x018557f31326bbb7)},
+ Uint128{u64(0xfc0b07ed7188249a), u64(0x01e6adefd7f06aa5)},
+ Uint128{u64(0xbd86e4f466f516e0), u64(0x01302cb5e6f642a7)},
+ Uint128{u64(0xace89e3180b25c98), u64(0x017c37e360b3d351)},
+ Uint128{u64(0x1822c5bde0def3be), u64(0x01db45dc38e0c826)},
+ Uint128{u64(0xcf15bb96ac8b5857), u64(0x01290ba9a38c7d17)},
+ Uint128{u64(0xc2db2a7c57ae2e6d), u64(0x01734e940c6f9c5d)},
+ Uint128{u64(0x3391f51b6d99ba08), u64(0x01d022390f8b8375)},
+ Uint128{u64(0x403b393124801445), u64(0x01221563a9b73229)},
+ Uint128{u64(0x904a077d6da01956), u64(0x016a9abc9424feb3)},
+ Uint128{u64(0x745c895cc9081fac), u64(0x01c5416bb92e3e60)},
+ Uint128{u64(0x48b9d5d9fda513cb), u64(0x011b48e353bce6fc)},
+ Uint128{u64(0x5ae84b507d0e58be), u64(0x01621b1c28ac20bb)},
+ Uint128{u64(0x31a25e249c51eeee), u64(0x01baa1e332d728ea)},
+ Uint128{u64(0x5f057ad6e1b33554), u64(0x0114a52dffc67992)},
+ Uint128{u64(0xf6c6d98c9a2002aa), u64(0x0159ce797fb817f6)},
+ Uint128{u64(0xb4788fefc0a80354), u64(0x01b04217dfa61df4)},
+ Uint128{u64(0xf0cb59f5d8690214), u64(0x010e294eebc7d2b8)},
+ Uint128{u64(0x2cfe30734e83429a), u64(0x0151b3a2a6b9c767)},
+ Uint128{u64(0xf83dbc9022241340), u64(0x01a6208b50683940)},
+ Uint128{u64(0x9b2695da15568c08), u64(0x0107d457124123c8)},
+ Uint128{u64(0xc1f03b509aac2f0a), u64(0x0149c96cd6d16cba)},
+ Uint128{u64(0x726c4a24c1573acd), u64(0x019c3bc80c85c7e9)},
+ Uint128{u64(0xe783ae56f8d684c0), u64(0x0101a55d07d39cf1)},
+ Uint128{u64(0x616499ecb70c25f0), u64(0x01420eb449c8842e)},
+ Uint128{u64(0xf9bdc067e4cf2f6c), u64(0x019292615c3aa539)},
+ Uint128{u64(0x782d3081de02fb47), u64(0x01f736f9b3494e88)},
+ Uint128{u64(0x4b1c3e512ac1dd0c), u64(0x013a825c100dd115)},
+ Uint128{u64(0x9de34de57572544f), u64(0x018922f31411455a)},
+ Uint128{u64(0x455c215ed2cee963), u64(0x01eb6bafd91596b1)},
+ Uint128{u64(0xcb5994db43c151de), u64(0x0133234de7ad7e2e)},
+ Uint128{u64(0x7e2ffa1214b1a655), u64(0x017fec216198ddba)},
+ Uint128{u64(0x1dbbf89699de0feb), u64(0x01dfe729b9ff1529)},
+ Uint128{u64(0xb2957b5e202ac9f3), u64(0x012bf07a143f6d39)},
+ Uint128{u64(0x1f3ada35a8357c6f), u64(0x0176ec98994f4888)},
+ Uint128{u64(0x270990c31242db8b), u64(0x01d4a7bebfa31aaa)},
+ Uint128{u64(0x5865fa79eb69c937), u64(0x0124e8d737c5f0aa)},
+ Uint128{u64(0xee7f791866443b85), u64(0x016e230d05b76cd4)},
+ Uint128{u64(0x2a1f575e7fd54a66), u64(0x01c9abd04725480a)},
+ Uint128{u64(0x5a53969b0fe54e80), u64(0x011e0b622c774d06)},
+ Uint128{u64(0xf0e87c41d3dea220), u64(0x01658e3ab7952047)},
+ Uint128{u64(0xed229b5248d64aa8), u64(0x01bef1c9657a6859)},
+ Uint128{u64(0x3435a1136d85eea9), u64(0x0117571ddf6c8138)},
+ Uint128{u64(0x4143095848e76a53), u64(0x015d2ce55747a186)},
+ Uint128{u64(0xd193cbae5b2144e8), u64(0x01b4781ead1989e7)},
+ Uint128{u64(0xe2fc5f4cf8f4cb11), u64(0x0110cb132c2ff630)},
+ Uint128{u64(0x1bbb77203731fdd5), u64(0x0154fdd7f73bf3bd)},
+ Uint128{u64(0x62aa54e844fe7d4a), u64(0x01aa3d4df50af0ac)},
+ Uint128{u64(0xbdaa75112b1f0e4e), u64(0x010a6650b926d66b)},
+ Uint128{u64(0xad15125575e6d1e2), u64(0x014cffe4e7708c06)},
+ Uint128{u64(0x585a56ead360865b), u64(0x01a03fde214caf08)},
+ Uint128{u64(0x37387652c41c53f8), u64(0x010427ead4cfed65)},
+ Uint128{u64(0x850693e7752368f7), u64(0x014531e58a03e8be)},
+ Uint128{u64(0x264838e1526c4334), u64(0x01967e5eec84e2ee)},
+ Uint128{u64(0xafda4719a7075402), u64(0x01fc1df6a7a61ba9)},
+ Uint128{u64(0x0de86c7008649481), u64(0x013d92ba28c7d14a)},
+ Uint128{u64(0x9162878c0a7db9a1), u64(0x018cf768b2f9c59c)},
+ Uint128{u64(0xb5bb296f0d1d280a), u64(0x01f03542dfb83703)},
+ Uint128{u64(0x5194f9e568323906), u64(0x01362149cbd32262)},
+ Uint128{u64(0xe5fa385ec23ec747), u64(0x0183a99c3ec7eafa)},
+ Uint128{u64(0x9f78c67672ce7919), u64(0x01e494034e79e5b9)},
+ Uint128{u64(0x03ab7c0a07c10bb0), u64(0x012edc82110c2f94)},
+ Uint128{u64(0x04965b0c89b14e9c), u64(0x017a93a2954f3b79)},
+ Uint128{u64(0x45bbf1cfac1da243), u64(0x01d9388b3aa30a57)},
+ Uint128{u64(0x8b957721cb92856a), u64(0x0127c35704a5e676)},
+ Uint128{u64(0x2e7ad4ea3e7726c4), u64(0x0171b42cc5cf6014)},
+ Uint128{u64(0x3a198a24ce14f075), u64(0x01ce2137f7433819)},
+ Uint128{u64(0xc44ff65700cd1649), u64(0x0120d4c2fa8a030f)},
+ Uint128{u64(0xb563f3ecc1005bdb), u64(0x016909f3b92c83d3)},
+ Uint128{u64(0xa2bcf0e7f14072d2), u64(0x01c34c70a777a4c8)},
+ Uint128{u64(0x65b61690f6c847c3), u64(0x011a0fc668aac6fd)},
+ Uint128{u64(0xbf239c35347a59b4), u64(0x016093b802d578bc)},
+ Uint128{u64(0xeeec83428198f021), u64(0x01b8b8a6038ad6eb)},
+ Uint128{u64(0x7553d20990ff9615), u64(0x01137367c236c653)},
+ Uint128{u64(0x52a8c68bf53f7b9a), u64(0x01585041b2c477e8)},
+ Uint128{u64(0x6752f82ef28f5a81), u64(0x01ae64521f7595e2)},
+ Uint128{u64(0x8093db1d57999890), u64(0x010cfeb353a97dad)},
+ Uint128{u64(0xe0b8d1e4ad7ffeb4), u64(0x01503e602893dd18)},
+ Uint128{u64(0x18e7065dd8dffe62), u64(0x01a44df832b8d45f)},
+ Uint128{u64(0x6f9063faa78bfefd), u64(0x0106b0bb1fb384bb)},
+ Uint128{u64(0x4b747cf9516efebc), u64(0x01485ce9e7a065ea)},
+ Uint128{u64(0xde519c37a5cabe6b), u64(0x019a742461887f64)},
+ Uint128{u64(0x0af301a2c79eb703), u64(0x01008896bcf54f9f)},
+ Uint128{u64(0xcdafc20b798664c4), u64(0x0140aabc6c32a386)},
+ Uint128{u64(0x811bb28e57e7fdf5), u64(0x0190d56b873f4c68)},
+ Uint128{u64(0xa1629f31ede1fd72), u64(0x01f50ac6690f1f82)},
+ Uint128{u64(0xa4dda37f34ad3e67), u64(0x013926bc01a973b1)},
+ Uint128{u64(0x0e150c5f01d88e01), u64(0x0187706b0213d09e)},
+ Uint128{u64(0x919a4f76c24eb181), u64(0x01e94c85c298c4c5)},
+ Uint128{u64(0x7b0071aa39712ef1), u64(0x0131cfd3999f7afb)},
+ Uint128{u64(0x59c08e14c7cd7aad), u64(0x017e43c8800759ba)},
+ Uint128{u64(0xf030b199f9c0d958), u64(0x01ddd4baa0093028)},
+ Uint128{u64(0x961e6f003c1887d7), u64(0x012aa4f4a405be19)},
+ Uint128{u64(0xfba60ac04b1ea9cd), u64(0x01754e31cd072d9f)},
+ Uint128{u64(0xfa8f8d705de65440), u64(0x01d2a1be4048f907)},
+ Uint128{u64(0xfc99b8663aaff4a8), u64(0x0123a516e82d9ba4)},
+ Uint128{u64(0x3bc0267fc95bf1d2), u64(0x016c8e5ca239028e)},
+ Uint128{u64(0xcab0301fbbb2ee47), u64(0x01c7b1f3cac74331)},
+ Uint128{u64(0x1eae1e13d54fd4ec), u64(0x011ccf385ebc89ff)},
+ Uint128{u64(0xe659a598caa3ca27), u64(0x01640306766bac7e)},
+ Uint128{u64(0x9ff00efefd4cbcb1), u64(0x01bd03c81406979e)},
+ Uint128{u64(0x23f6095f5e4ff5ef), u64(0x0116225d0c841ec3)},
+ Uint128{u64(0xecf38bb735e3f36a), u64(0x015baaf44fa52673)},
+ Uint128{u64(0xe8306ea5035cf045), u64(0x01b295b1638e7010)},
+ Uint128{u64(0x911e4527221a162b), u64(0x010f9d8ede39060a)},
+ Uint128{u64(0x3565d670eaa09bb6), u64(0x015384f295c7478d)},
+ Uint128{u64(0x82bf4c0d2548c2a3), u64(0x01a8662f3b391970)},
+ Uint128{u64(0x51b78f88374d79a6), u64(0x01093fdd8503afe6)},
+ Uint128{u64(0xe625736a4520d810), u64(0x014b8fd4e6449bdf)},
+ Uint128{u64(0xdfaed044d6690e14), u64(0x019e73ca1fd5c2d7)},
+ Uint128{u64(0xebcd422b0601a8cc), u64(0x0103085e53e599c6)},
+ Uint128{u64(0xa6c092b5c78212ff), u64(0x0143ca75e8df0038)},
+ Uint128{u64(0xd070b763396297bf), u64(0x0194bd136316c046)},
+ Uint128{u64(0x848ce53c07bb3daf), u64(0x01f9ec583bdc7058)},
+ Uint128{u64(0x52d80f4584d5068d), u64(0x013c33b72569c637)},
+ Uint128{u64(0x278e1316e60a4831), u64(0x018b40a4eec437c5)},
+ ]
+
+ pow5_inv_split_64 = [
+ Uint128{u64(0x0000000000000001), u64(0x0400000000000000)},
+ Uint128{u64(0x3333333333333334), u64(0x0333333333333333)},
+ Uint128{u64(0x28f5c28f5c28f5c3), u64(0x028f5c28f5c28f5c)},
+ Uint128{u64(0xed916872b020c49c), u64(0x020c49ba5e353f7c)},
+ Uint128{u64(0xaf4f0d844d013a93), u64(0x0346dc5d63886594)},
+ Uint128{u64(0x8c3f3e0370cdc876), u64(0x029f16b11c6d1e10)},
+ Uint128{u64(0xd698fe69270b06c5), u64(0x0218def416bdb1a6)},
+ Uint128{u64(0xf0f4ca41d811a46e), u64(0x035afe535795e90a)},
+ Uint128{u64(0xf3f70834acdae9f1), u64(0x02af31dc4611873b)},
+ Uint128{u64(0x5cc5a02a23e254c1), u64(0x0225c17d04dad296)},
+ Uint128{u64(0xfad5cd10396a2135), u64(0x036f9bfb3af7b756)},
+ Uint128{u64(0xfbde3da69454e75e), u64(0x02bfaffc2f2c92ab)},
+ Uint128{u64(0x2fe4fe1edd10b918), u64(0x0232f33025bd4223)},
+ Uint128{u64(0x4ca19697c81ac1bf), u64(0x0384b84d092ed038)},
+ Uint128{u64(0x3d4e1213067bce33), u64(0x02d09370d4257360)},
+ Uint128{u64(0x643e74dc052fd829), u64(0x024075f3dceac2b3)},
+ Uint128{u64(0x6d30baf9a1e626a7), u64(0x039a5652fb113785)},
+ Uint128{u64(0x2426fbfae7eb5220), u64(0x02e1dea8c8da92d1)},
+ Uint128{u64(0x1cebfcc8b9890e80), u64(0x024e4bba3a487574)},
+ Uint128{u64(0x94acc7a78f41b0cc), u64(0x03b07929f6da5586)},
+ Uint128{u64(0xaa23d2ec729af3d7), u64(0x02f394219248446b)},
+ Uint128{u64(0xbb4fdbf05baf2979), u64(0x025c768141d369ef)},
+ Uint128{u64(0xc54c931a2c4b758d), u64(0x03c7240202ebdcb2)},
+ Uint128{u64(0x9dd6dc14f03c5e0b), u64(0x0305b66802564a28)},
+ Uint128{u64(0x4b1249aa59c9e4d6), u64(0x026af8533511d4ed)},
+ Uint128{u64(0x44ea0f76f60fd489), u64(0x03de5a1ebb4fbb15)},
+ Uint128{u64(0x6a54d92bf80caa07), u64(0x0318481895d96277)},
+ Uint128{u64(0x21dd7a89933d54d2), u64(0x0279d346de4781f9)},
+ Uint128{u64(0x362f2a75b8622150), u64(0x03f61ed7ca0c0328)},
+ Uint128{u64(0xf825bb91604e810d), u64(0x032b4bdfd4d668ec)},
+ Uint128{u64(0xc684960de6a5340b), u64(0x0289097fdd7853f0)},
+ Uint128{u64(0xd203ab3e521dc33c), u64(0x02073accb12d0ff3)},
+ Uint128{u64(0xe99f7863b696052c), u64(0x033ec47ab514e652)},
+ Uint128{u64(0x87b2c6b62bab3757), u64(0x02989d2ef743eb75)},
+ Uint128{u64(0xd2f56bc4efbc2c45), u64(0x0213b0f25f69892a)},
+ Uint128{u64(0x1e55793b192d13a2), u64(0x0352b4b6ff0f41de)},
+ Uint128{u64(0x4b77942f475742e8), u64(0x02a8909265a5ce4b)},
+ Uint128{u64(0xd5f9435905df68ba), u64(0x022073a8515171d5)},
+ Uint128{u64(0x565b9ef4d6324129), u64(0x03671f73b54f1c89)},
+ Uint128{u64(0xdeafb25d78283421), u64(0x02b8e5f62aa5b06d)},
+ Uint128{u64(0x188c8eb12cecf681), u64(0x022d84c4eeeaf38b)},
+ Uint128{u64(0x8dadb11b7b14bd9b), u64(0x037c07a17e44b8de)},
+ Uint128{u64(0x7157c0e2c8dd647c), u64(0x02c99fb46503c718)},
+ Uint128{u64(0x8ddfcd823a4ab6ca), u64(0x023ae629ea696c13)},
+ Uint128{u64(0x1632e269f6ddf142), u64(0x0391704310a8acec)},
+ Uint128{u64(0x44f581ee5f17f435), u64(0x02dac035a6ed5723)},
+ Uint128{u64(0x372ace584c1329c4), u64(0x024899c4858aac1c)},
+ Uint128{u64(0xbeaae3c079b842d3), u64(0x03a75c6da27779c6)},
+ Uint128{u64(0x6555830061603576), u64(0x02ec49f14ec5fb05)},
+ Uint128{u64(0xb7779c004de6912b), u64(0x0256a18dd89e626a)},
+ Uint128{u64(0xf258f99a163db512), u64(0x03bdcf495a9703dd)},
+ Uint128{u64(0x5b7a614811caf741), u64(0x02fe3f6de212697e)},
+ Uint128{u64(0xaf951aa00e3bf901), u64(0x0264ff8b1b41edfe)},
+ Uint128{u64(0x7f54f7667d2cc19b), u64(0x03d4cc11c5364997)},
+ Uint128{u64(0x32aa5f8530f09ae3), u64(0x0310a3416a91d479)},
+ Uint128{u64(0xf55519375a5a1582), u64(0x0273b5cdeedb1060)},
+ Uint128{u64(0xbbbb5b8bc3c3559d), u64(0x03ec56164af81a34)},
+ Uint128{u64(0x2fc916096969114a), u64(0x03237811d593482a)},
+ Uint128{u64(0x596dab3ababa743c), u64(0x0282c674aadc39bb)},
+ Uint128{u64(0x478aef622efb9030), u64(0x0202385d557cfafc)},
+ Uint128{u64(0xd8de4bd04b2c19e6), u64(0x0336c0955594c4c6)},
+ Uint128{u64(0xad7ea30d08f014b8), u64(0x029233aaaadd6a38)},
+ Uint128{u64(0x24654f3da0c01093), u64(0x020e8fbbbbe454fa)},
+ Uint128{u64(0x3a3bb1fc346680eb), u64(0x034a7f92c63a2190)},
+ Uint128{u64(0x94fc8e635d1ecd89), u64(0x02a1ffa89e94e7a6)},
+ Uint128{u64(0xaa63a51c4a7f0ad4), u64(0x021b32ed4baa52eb)},
+ Uint128{u64(0xdd6c3b607731aaed), u64(0x035eb7e212aa1e45)},
+ Uint128{u64(0x1789c919f8f488bd), u64(0x02b22cb4dbbb4b6b)},
+ Uint128{u64(0xac6e3a7b2d906d64), u64(0x022823c3e2fc3c55)},
+ Uint128{u64(0x13e390c515b3e23a), u64(0x03736c6c9e606089)},
+ Uint128{u64(0xdcb60d6a77c31b62), u64(0x02c2bd23b1e6b3a0)},
+ Uint128{u64(0x7d5e7121f968e2b5), u64(0x0235641c8e52294d)},
+ Uint128{u64(0xc8971b698f0e3787), u64(0x0388a02db0837548)},
+ Uint128{u64(0xa078e2bad8d82c6c), u64(0x02d3b357c0692aa0)},
+ Uint128{u64(0xe6c71bc8ad79bd24), u64(0x0242f5dfcd20eee6)},
+ Uint128{u64(0x0ad82c7448c2c839), u64(0x039e5632e1ce4b0b)},
+ Uint128{u64(0x3be023903a356cfa), u64(0x02e511c24e3ea26f)},
+ Uint128{u64(0x2fe682d9c82abd95), u64(0x0250db01d8321b8c)},
+ Uint128{u64(0x4ca4048fa6aac8ee), u64(0x03b4919c8d1cf8e0)},
+ Uint128{u64(0x3d5003a61eef0725), u64(0x02f6dae3a4172d80)},
+ Uint128{u64(0x9773361e7f259f51), u64(0x025f1582e9ac2466)},
+ Uint128{u64(0x8beb89ca6508fee8), u64(0x03cb559e42ad070a)},
+ Uint128{u64(0x6fefa16eb73a6586), u64(0x0309114b688a6c08)},
+ Uint128{u64(0xf3261abef8fb846b), u64(0x026da76f86d52339)},
+ Uint128{u64(0x51d691318e5f3a45), u64(0x03e2a57f3e21d1f6)},
+ Uint128{u64(0x0e4540f471e5c837), u64(0x031bb798fe8174c5)},
+ Uint128{u64(0xd8376729f4b7d360), u64(0x027c92e0cb9ac3d0)},
+ Uint128{u64(0xf38bd84321261eff), u64(0x03fa849adf5e061a)},
+ Uint128{u64(0x293cad0280eb4bff), u64(0x032ed07be5e4d1af)},
+ Uint128{u64(0xedca240200bc3ccc), u64(0x028bd9fcb7ea4158)},
+ Uint128{u64(0xbe3b50019a3030a4), u64(0x02097b309321cde0)},
+ Uint128{u64(0xc9f88002904d1a9f), u64(0x03425eb41e9c7c9a)},
+ Uint128{u64(0x3b2d3335403daee6), u64(0x029b7ef67ee396e2)},
+ Uint128{u64(0x95bdc291003158b8), u64(0x0215ff2b98b6124e)},
+ Uint128{u64(0x892f9db4cd1bc126), u64(0x035665128df01d4a)},
+ Uint128{u64(0x07594af70a7c9a85), u64(0x02ab840ed7f34aa2)},
+ Uint128{u64(0x6c476f2c0863aed1), u64(0x0222d00bdff5d54e)},
+ Uint128{u64(0x13a57eacda3917b4), u64(0x036ae67966562217)},
+ Uint128{u64(0x0fb7988a482dac90), u64(0x02bbeb9451de81ac)},
+ Uint128{u64(0xd95fad3b6cf156da), u64(0x022fefa9db1867bc)},
+ Uint128{u64(0xf565e1f8ae4ef15c), u64(0x037fe5dc91c0a5fa)},
+ Uint128{u64(0x911e4e608b725ab0), u64(0x02ccb7e3a7cd5195)},
+ Uint128{u64(0xda7ea51a0928488d), u64(0x023d5fe9530aa7aa)},
+ Uint128{u64(0xf7310829a8407415), u64(0x039566421e7772aa)},
+ Uint128{u64(0x2c2739baed005cde), u64(0x02ddeb68185f8eef)},
+ Uint128{u64(0xbcec2e2f24004a4b), u64(0x024b22b9ad193f25)},
+ Uint128{u64(0x94ad16b1d333aa11), u64(0x03ab6ac2ae8ecb6f)},
+ Uint128{u64(0xaa241227dc2954db), u64(0x02ef889bbed8a2bf)},
+ Uint128{u64(0x54e9a81fe35443e2), u64(0x02593a163246e899)},
+ Uint128{u64(0x2175d9cc9eed396a), u64(0x03c1f689ea0b0dc2)},
+ Uint128{u64(0xe7917b0a18bdc788), u64(0x03019207ee6f3e34)},
+ Uint128{u64(0xb9412f3b46fe393a), u64(0x0267a8065858fe90)},
+ Uint128{u64(0xf535185ed7fd285c), u64(0x03d90cd6f3c1974d)},
+ Uint128{u64(0xc42a79e57997537d), u64(0x03140a458fce12a4)},
+ Uint128{u64(0x03552e512e12a931), u64(0x02766e9e0ca4dbb7)},
+ Uint128{u64(0x9eeeb081e3510eb4), u64(0x03f0b0fce107c5f1)},
+ Uint128{u64(0x4bf226ce4f740bc3), u64(0x0326f3fd80d304c1)},
+ Uint128{u64(0xa3281f0b72c33c9c), u64(0x02858ffe00a8d09a)},
+ Uint128{u64(0x1c2018d5f568fd4a), u64(0x020473319a20a6e2)},
+ Uint128{u64(0xf9ccf48988a7fba9), u64(0x033a51e8f69aa49c)},
+ Uint128{u64(0xfb0a5d3ad3b99621), u64(0x02950e53f87bb6e3)},
+ Uint128{u64(0x2f3b7dc8a96144e7), u64(0x0210d8432d2fc583)},
+ Uint128{u64(0xe52bfc7442353b0c), u64(0x034e26d1e1e608d1)},
+ Uint128{u64(0xb756639034f76270), u64(0x02a4ebdb1b1e6d74)},
+ Uint128{u64(0x2c451c735d92b526), u64(0x021d897c15b1f12a)},
+ Uint128{u64(0x13a1c71efc1deea3), u64(0x0362759355e981dd)},
+ Uint128{u64(0x761b05b2634b2550), u64(0x02b52adc44bace4a)},
+ Uint128{u64(0x91af37c1e908eaa6), u64(0x022a88b036fbd83b)},
+ Uint128{u64(0x82b1f2cfdb417770), u64(0x03774119f192f392)},
+ Uint128{u64(0xcef4c23fe29ac5f3), u64(0x02c5cdae5adbf60e)},
+ Uint128{u64(0x3f2a34ffe87bd190), u64(0x0237d7beaf165e72)},
+ Uint128{u64(0x984387ffda5fb5b2), u64(0x038c8c644b56fd83)},
+ Uint128{u64(0xe0360666484c915b), u64(0x02d6d6b6a2abfe02)},
+ Uint128{u64(0x802b3851d3707449), u64(0x024578921bbccb35)},
+ Uint128{u64(0x99dec082ebe72075), u64(0x03a25a835f947855)},
+ Uint128{u64(0xae4bcd358985b391), u64(0x02e8486919439377)},
+ Uint128{u64(0xbea30a913ad15c74), u64(0x02536d20e102dc5f)},
+ Uint128{u64(0xfdd1aa81f7b560b9), u64(0x03b8ae9b019e2d65)},
+ Uint128{u64(0x97daeece5fc44d61), u64(0x02fa2548ce182451)},
+ Uint128{u64(0xdfe258a51969d781), u64(0x0261b76d71ace9da)},
+ Uint128{u64(0x996a276e8f0fbf34), u64(0x03cf8be24f7b0fc4)},
+ Uint128{u64(0xe121b9253f3fcc2a), u64(0x030c6fe83f95a636)},
+ Uint128{u64(0xb41afa8432997022), u64(0x02705986994484f8)},
+ Uint128{u64(0xecf7f739ea8f19cf), u64(0x03e6f5a4286da18d)},
+ Uint128{u64(0x23f99294bba5ae40), u64(0x031f2ae9b9f14e0b)},
+ Uint128{u64(0x4ffadbaa2fb7be99), u64(0x027f5587c7f43e6f)},
+ Uint128{u64(0x7ff7c5dd1925fdc2), u64(0x03feef3fa6539718)},
+ Uint128{u64(0xccc637e4141e649b), u64(0x033258ffb842df46)},
+ Uint128{u64(0xd704f983434b83af), u64(0x028ead9960357f6b)},
+ Uint128{u64(0x126a6135cf6f9c8c), u64(0x020bbe144cf79923)},
+ Uint128{u64(0x83dd685618b29414), u64(0x0345fced47f28e9e)},
+ Uint128{u64(0x9cb12044e08edcdd), u64(0x029e63f1065ba54b)},
+ Uint128{u64(0x16f419d0b3a57d7d), u64(0x02184ff405161dd6)},
+ Uint128{u64(0x8b20294dec3bfbfb), u64(0x035a19866e89c956)},
+ Uint128{u64(0x3c19baa4bcfcc996), u64(0x02ae7ad1f207d445)},
+ Uint128{u64(0xc9ae2eea30ca3adf), u64(0x02252f0e5b39769d)},
+ Uint128{u64(0x0f7d17dd1add2afd), u64(0x036eb1b091f58a96)},
+ Uint128{u64(0x3f97464a7be42264), u64(0x02bef48d41913bab)},
+ Uint128{u64(0xcc790508631ce850), u64(0x02325d3dce0dc955)},
+ Uint128{u64(0xe0c1a1a704fb0d4d), u64(0x0383c862e3494222)},
+ Uint128{u64(0x4d67b4859d95a43e), u64(0x02cfd3824f6dce82)},
+ Uint128{u64(0x711fc39e17aae9cb), u64(0x023fdc683f8b0b9b)},
+ Uint128{u64(0xe832d2968c44a945), u64(0x039960a6cc11ac2b)},
+ Uint128{u64(0xecf575453d03ba9e), u64(0x02e11a1f09a7bcef)},
+ Uint128{u64(0x572ac4376402fbb1), u64(0x024dae7f3aec9726)},
+ Uint128{u64(0x58446d256cd192b5), u64(0x03af7d985e47583d)},
+ Uint128{u64(0x79d0575123dadbc4), u64(0x02f2cae04b6c4697)},
+ Uint128{u64(0x94a6ac40e97be303), u64(0x025bd5803c569edf)},
+ Uint128{u64(0x8771139b0f2c9e6c), u64(0x03c62266c6f0fe32)},
+ Uint128{u64(0x9f8da948d8f07ebd), u64(0x0304e85238c0cb5b)},
+ Uint128{u64(0xe60aedd3e0c06564), u64(0x026a5374fa33d5e2)},
+ Uint128{u64(0xa344afb9679a3bd2), u64(0x03dd5254c3862304)},
+ Uint128{u64(0xe903bfc78614fca8), u64(0x031775109c6b4f36)},
+ Uint128{u64(0xba6966393810ca20), u64(0x02792a73b055d8f8)},
+ Uint128{u64(0x2a423d2859b4769a), u64(0x03f510b91a22f4c1)},
+ Uint128{u64(0xee9b642047c39215), u64(0x032a73c7481bf700)},
+ Uint128{u64(0xbee2b680396941aa), u64(0x02885c9f6ce32c00)},
+ Uint128{u64(0xff1bc53361210155), u64(0x0206b07f8a4f5666)},
+ Uint128{u64(0x31c6085235019bbb), u64(0x033de73276e5570b)},
+ Uint128{u64(0x27d1a041c4014963), u64(0x0297ec285f1ddf3c)},
+ Uint128{u64(0xeca7b367d0010782), u64(0x021323537f4b18fc)},
+ Uint128{u64(0xadd91f0c8001a59d), u64(0x0351d21f3211c194)},
+ Uint128{u64(0xf17a7f3d3334847e), u64(0x02a7db4c280e3476)},
+ Uint128{u64(0x279532975c2a0398), u64(0x021fe2a3533e905f)},
+ Uint128{u64(0xd8eeb75893766c26), u64(0x0366376bb8641a31)},
+ Uint128{u64(0x7a5892ad42c52352), u64(0x02b82c562d1ce1c1)},
+ Uint128{u64(0xfb7a0ef102374f75), u64(0x022cf044f0e3e7cd)},
+ Uint128{u64(0xc59017e8038bb254), u64(0x037b1a07e7d30c7c)},
+ Uint128{u64(0x37a67986693c8eaa), u64(0x02c8e19feca8d6ca)},
+ Uint128{u64(0xf951fad1edca0bbb), u64(0x023a4e198a20abd4)},
+ Uint128{u64(0x28832ae97c76792b), u64(0x03907cf5a9cddfbb)},
+ Uint128{u64(0x2068ef21305ec756), u64(0x02d9fd9154a4b2fc)},
+ Uint128{u64(0x19ed8c1a8d189f78), u64(0x0247fe0ddd508f30)},
+ Uint128{u64(0x5caf4690e1c0ff26), u64(0x03a66349621a7eb3)},
+ Uint128{u64(0x4a25d20d81673285), u64(0x02eb82a11b48655c)},
+ Uint128{u64(0x3b5174d79ab8f537), u64(0x0256021a7c39eab0)},
+ Uint128{u64(0x921bee25c45b21f1), u64(0x03bcd02a605caab3)},
+ Uint128{u64(0xdb498b5169e2818e), u64(0x02fd735519e3bbc2)},
+ Uint128{u64(0x15d46f7454b53472), u64(0x02645c4414b62fcf)},
+ Uint128{u64(0xefba4bed545520b6), u64(0x03d3c6d35456b2e4)},
+ Uint128{u64(0xf2fb6ff110441a2b), u64(0x030fd242a9def583)},
+ Uint128{u64(0x8f2f8cc0d9d014ef), u64(0x02730e9bbb18c469)},
+ Uint128{u64(0xb1e5ae015c80217f), u64(0x03eb4a92c4f46d75)},
+ Uint128{u64(0xc1848b344a001acc), u64(0x0322a20f03f6bdf7)},
+ Uint128{u64(0xce03a2903b3348a3), u64(0x02821b3f365efe5f)},
+ Uint128{u64(0xd802e873628f6d4f), u64(0x0201af65c518cb7f)},
+ Uint128{u64(0x599e40b89db2487f), u64(0x0335e56fa1c14599)},
+ Uint128{u64(0xe14b66fa17c1d399), u64(0x029184594e3437ad)},
+ Uint128{u64(0x81091f2e7967dc7a), u64(0x020e037aa4f692f1)},
+ Uint128{u64(0x9b41cb7d8f0c93f6), u64(0x03499f2aa18a84b5)},
+ Uint128{u64(0xaf67d5fe0c0a0ff8), u64(0x02a14c221ad536f7)},
+ Uint128{u64(0xf2b977fe70080cc7), u64(0x021aa34e7bddc592)},
+ Uint128{u64(0x1df58cca4cd9ae0b), u64(0x035dd2172c9608eb)},
+ Uint128{u64(0xe4c470a1d7148b3c), u64(0x02b174df56de6d88)},
+ Uint128{u64(0x83d05a1b1276d5ca), u64(0x022790b2abe5246d)},
+ Uint128{u64(0x9fb3c35e83f1560f), u64(0x0372811ddfd50715)},
+ Uint128{u64(0xb2f635e5365aab3f), u64(0x02c200e4b310d277)},
+ Uint128{u64(0xf591c4b75eaeef66), u64(0x0234cd83c273db92)},
+ Uint128{u64(0xef4fa125644b18a3), u64(0x0387af39371fc5b7)},
+ Uint128{u64(0x8c3fb41de9d5ad4f), u64(0x02d2f2942c196af9)},
+ Uint128{u64(0x3cffc34b2177bdd9), u64(0x02425ba9bce12261)},
+ Uint128{u64(0x94cc6bab68bf9628), u64(0x039d5f75fb01d09b)},
+ Uint128{u64(0x10a38955ed6611b9), u64(0x02e44c5e6267da16)},
+ Uint128{u64(0xda1c6dde5784dafb), u64(0x02503d184eb97b44)},
+ Uint128{u64(0xf693e2fd58d49191), u64(0x03b394f3b128c53a)},
+ Uint128{u64(0xc5431bfde0aa0e0e), u64(0x02f610c2f4209dc8)},
+ Uint128{u64(0x6a9c1664b3bb3e72), u64(0x025e73cf29b3b16d)},
+ Uint128{u64(0x10f9bd6dec5eca4f), u64(0x03ca52e50f85e8af)},
+ Uint128{u64(0xda616457f04bd50c), u64(0x03084250d937ed58)},
+ Uint128{u64(0xe1e783798d09773d), u64(0x026d01da475ff113)},
+ Uint128{u64(0x030c058f480f252e), u64(0x03e19c9072331b53)},
+ Uint128{u64(0x68d66ad906728425), u64(0x031ae3a6c1c27c42)},
+ Uint128{u64(0x8711ef14052869b7), u64(0x027be952349b969b)},
+ Uint128{u64(0x0b4fe4ecd50d75f2), u64(0x03f97550542c242c)},
+ Uint128{u64(0xa2a650bd773df7f5), u64(0x032df7737689b689)},
+ Uint128{u64(0xb551da312c31932a), u64(0x028b2c5c5ed49207)},
+ Uint128{u64(0x5ddb14f4235adc22), u64(0x0208f049e576db39)},
+ Uint128{u64(0x2fc4ee536bc49369), u64(0x034180763bf15ec2)},
+ Uint128{u64(0xbfd0bea92303a921), u64(0x029acd2b63277f01)},
+ Uint128{u64(0x9973cbba8269541a), u64(0x021570ef8285ff34)},
+ Uint128{u64(0x5bec792a6a42202a), u64(0x0355817f373ccb87)},
+ Uint128{u64(0xe3239421ee9b4cef), u64(0x02aacdff5f63d605)},
+ Uint128{u64(0xb5b6101b25490a59), u64(0x02223e65e5e97804)},
+ Uint128{u64(0x22bce691d541aa27), u64(0x0369fd6fd64259a1)},
+ Uint128{u64(0xb563eba7ddce21b9), u64(0x02bb31264501e14d)},
+ Uint128{u64(0xf78322ecb171b494), u64(0x022f5a850401810a)},
+ Uint128{u64(0x259e9e47824f8753), u64(0x037ef73b399c01ab)},
+ Uint128{u64(0x1e187e9f9b72d2a9), u64(0x02cbf8fc2e1667bc)},
+ Uint128{u64(0x4b46cbb2e2c24221), u64(0x023cc73024deb963)},
+ Uint128{u64(0x120adf849e039d01), u64(0x039471e6a1645bd2)},
+ Uint128{u64(0xdb3be603b19c7d9a), u64(0x02dd27ebb4504974)},
+ Uint128{u64(0x7c2feb3627b0647c), u64(0x024a865629d9d45d)},
+ Uint128{u64(0x2d197856a5e7072c), u64(0x03aa7089dc8fba2f)},
+ Uint128{u64(0x8a7ac6abb7ec05bd), u64(0x02eec06e4a0c94f2)},
+ Uint128{u64(0xd52f05562cbcd164), u64(0x025899f1d4d6dd8e)},
+ Uint128{u64(0x21e4d556adfae8a0), u64(0x03c0f64fbaf1627e)},
+ Uint128{u64(0xe7ea444557fbed4d), u64(0x0300c50c958de864)},
+ Uint128{u64(0xecbb69d1132ff10a), u64(0x0267040a113e5383)},
+ Uint128{u64(0xadf8a94e851981aa), u64(0x03d8067681fd526c)},
+ Uint128{u64(0x8b2d543ed0e13488), u64(0x0313385ece6441f0)},
+ Uint128{u64(0xd5bddcff0d80f6d3), u64(0x0275c6b23eb69b26)},
+ Uint128{u64(0x892fc7fe7c018aeb), u64(0x03efa45064575ea4)},
+ Uint128{u64(0x3a8c9ffec99ad589), u64(0x03261d0d1d12b21d)},
+ Uint128{u64(0xc8707fff07af113b), u64(0x0284e40a7da88e7d)},
+ Uint128{u64(0x39f39998d2f2742f), u64(0x0203e9a1fe2071fe)},
+ Uint128{u64(0x8fec28f484b7204b), u64(0x033975cffd00b663)},
+ Uint128{u64(0xd989ba5d36f8e6a2), u64(0x02945e3ffd9a2b82)},
+ Uint128{u64(0x47a161e42bfa521c), u64(0x02104b66647b5602)},
+ Uint128{u64(0x0c35696d132a1cf9), u64(0x034d4570a0c5566a)},
+ Uint128{u64(0x09c454574288172d), u64(0x02a4378d4d6aab88)},
+ Uint128{u64(0xa169dd129ba0128b), u64(0x021cf93dd7888939)},
+ Uint128{u64(0x0242fb50f9001dab), u64(0x03618ec958da7529)},
+ Uint128{u64(0x9b68c90d940017bc), u64(0x02b4723aad7b90ed)},
+ Uint128{u64(0x4920a0d7a999ac96), u64(0x0229f4fbbdfc73f1)},
+ Uint128{u64(0x750101590f5c4757), u64(0x037654c5fcc71fe8)},
+ Uint128{u64(0x2a6734473f7d05df), u64(0x02c5109e63d27fed)},
+ Uint128{u64(0xeeb8f69f65fd9e4c), u64(0x0237407eb641fff0)},
+ Uint128{u64(0xe45b24323cc8fd46), u64(0x038b9a6456cfffe7)},
+ Uint128{u64(0xb6af502830a0ca9f), u64(0x02d6151d123fffec)},
+ Uint128{u64(0xf88c402026e7087f), u64(0x0244ddb0db666656)},
+ Uint128{u64(0x2746cd003e3e73fe), u64(0x03a162b4923d708b)},
+ Uint128{u64(0x1f6bd73364fec332), u64(0x02e7822a0e978d3c)},
+ Uint128{u64(0xe5efdf5c50cbcf5b), u64(0x0252ce880bac70fc)},
+ Uint128{u64(0x3cb2fefa1adfb22b), u64(0x03b7b0d9ac471b2e)},
+ Uint128{u64(0x308f3261af195b56), u64(0x02f95a47bd05af58)},
+ Uint128{u64(0x5a0c284e25ade2ab), u64(0x0261150630d15913)},
+ Uint128{u64(0x29ad0d49d5e30445), u64(0x03ce8809e7b55b52)},
+ Uint128{u64(0x548a7107de4f369d), u64(0x030ba007ec9115db)},
+ Uint128{u64(0xdd3b8d9fe50c2bb1), u64(0x026fb3398a0dab15)},
+ Uint128{u64(0x952c15cca1ad12b5), u64(0x03e5eb8f434911bc)},
+ Uint128{u64(0x775677d6e7bda891), u64(0x031e560c35d40e30)},
+ Uint128{u64(0xc5dec645863153a7), u64(0x027eab3cf7dcd826)},
+ ]
+)
diff --git a/v_windows/v/vlib/strconv/utilities.v b/v_windows/v/vlib/strconv/utilities.v
new file mode 100644
index 0000000..2098a73
--- /dev/null
+++ b/v_windows/v/vlib/strconv/utilities.v
@@ -0,0 +1,556 @@
+module strconv
+
+import math.bits
+// import math
+
+/*
+f32/f64 to string utilities
+
+Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
+Use of this source code is governed by an MIT license
+that can be found in the LICENSE file.
+
+This file contains the f32/f64 to string utilities functions
+
+These functions are based on the work of:
+Publication:PLDI 2018: Proceedings of the 39th ACM SIGPLAN
+Conference on Programming Language Design and ImplementationJune 2018
+Pages 270–282 https://doi.org/10.1145/3192366.3192369
+
+inspired by the Go version here:
+https://github.com/cespare/ryu/tree/ba56a33f39e3bbbfa409095d0f9ae168a595feea
+*/
+
+// General Utilities
+[if debug_strconv ?]
+fn assert1(t bool, msg string) {
+ if !t {
+ panic(msg)
+ }
+}
+
+[inline]
+fn bool_to_int(b bool) int {
+ if b {
+ return 1
+ }
+ return 0
+}
+
+[inline]
+fn bool_to_u32(b bool) u32 {
+ if b {
+ return u32(1)
+ }
+ return u32(0)
+}
+
+[inline]
+fn bool_to_u64(b bool) u64 {
+ if b {
+ return u64(1)
+ }
+ return u64(0)
+}
+
+fn get_string_special(neg bool, expZero bool, mantZero bool) string {
+ if !mantZero {
+ return 'nan'
+ }
+ if !expZero {
+ if neg {
+ return '-inf'
+ } else {
+ return '+inf'
+ }
+ }
+ if neg {
+ return '-0e+00'
+ }
+ return '0e+00'
+}
+
+/*
+32 bit functions
+*/
+
+fn mul_shift_32(m u32, mul u64, ishift int) u32 {
+ // QTODO
+ // assert ishift > 32
+
+ hi, lo := bits.mul_64(u64(m), mul)
+ shifted_sum := (lo >> u64(ishift)) + (hi << u64(64 - ishift))
+ assert1(shifted_sum <= 2147483647, 'shiftedSum <= math.max_u32')
+ return u32(shifted_sum)
+}
+
+fn mul_pow5_invdiv_pow2(m u32, q u32, j int) u32 {
+ return mul_shift_32(m, pow5_inv_split_32[q], j)
+}
+
+fn mul_pow5_div_pow2(m u32, i u32, j int) u32 {
+ return mul_shift_32(m, pow5_split_32[i], j)
+}
+
+fn pow5_factor_32(i_v u32) u32 {
+ mut v := i_v
+ for n := u32(0); true; n++ {
+ q := v / 5
+ r := v % 5
+ if r != 0 {
+ return n
+ }
+ v = q
+ }
+ return v
+}
+
+// multiple_of_power_of_five_32 reports whether v is divisible by 5^p.
+fn multiple_of_power_of_five_32(v u32, p u32) bool {
+ return pow5_factor_32(v) >= p
+}
+
+// multiple_of_power_of_two_32 reports whether v is divisible by 2^p.
+fn multiple_of_power_of_two_32(v u32, p u32) bool {
+ return u32(bits.trailing_zeros_32(v)) >= p
+}
+
+// log10_pow2 returns floor(log_10(2^e)).
+fn log10_pow2(e int) u32 {
+ // The first value this approximation fails for is 2^1651
+ // which is just greater than 10^297.
+ assert1(e >= 0, 'e >= 0')
+ assert1(e <= 1650, 'e <= 1650')
+ return (u32(e) * 78913) >> 18
+}
+
+// log10_pow5 returns floor(log_10(5^e)).
+fn log10_pow5(e int) u32 {
+ // The first value this approximation fails for is 5^2621
+ // which is just greater than 10^1832.
+ assert1(e >= 0, 'e >= 0')
+ assert1(e <= 2620, 'e <= 2620')
+ return (u32(e) * 732923) >> 20
+}
+
+// pow5_bits returns ceil(log_2(5^e)), or else 1 if e==0.
+fn pow5_bits(e int) int {
+ // This approximation works up to the point that the multiplication
+ // overflows at e = 3529. If the multiplication were done in 64 bits,
+ // it would fail at 5^4004 which is just greater than 2^9297.
+ assert1(e >= 0, 'e >= 0')
+ assert1(e <= 3528, 'e <= 3528')
+ return int(((u32(e) * 1217359) >> 19) + 1)
+}
+
+/*
+64 bit functions
+*/
+
+fn shift_right_128(v Uint128, shift int) u64 {
+ // The shift value is always modulo 64.
+ // In the current implementation of the 64-bit version
+ // of Ryu, the shift value is always < 64.
+ // (It is in the range [2, 59].)
+ // Check this here in case a future change requires larger shift
+ // values. In this case this function needs to be adjusted.
+ assert1(shift < 64, 'shift < 64')
+ return (v.hi << u64(64 - shift)) | (v.lo >> u32(shift))
+}
+
+fn mul_shift_64(m u64, mul Uint128, shift int) u64 {
+ hihi, hilo := bits.mul_64(m, mul.hi)
+ lohi, _ := bits.mul_64(m, mul.lo)
+ mut sum := Uint128{
+ lo: lohi + hilo
+ hi: hihi
+ }
+ if sum.lo < lohi {
+ sum.hi++ // overflow
+ }
+ return shift_right_128(sum, shift - 64)
+}
+
+fn pow5_factor_64(v_i u64) u32 {
+ mut v := v_i
+ for n := u32(0); true; n++ {
+ q := v / 5
+ r := v % 5
+ if r != 0 {
+ return n
+ }
+ v = q
+ }
+ return u32(0)
+}
+
+fn multiple_of_power_of_five_64(v u64, p u32) bool {
+ return pow5_factor_64(v) >= p
+}
+
+fn multiple_of_power_of_two_64(v u64, p u32) bool {
+ return u32(bits.trailing_zeros_64(v)) >= p
+}
+
+/*
+f64 to string with string format
+*/
+
+// TODO: Investigate precision issues
+// f32_to_str_l return a string with the f32 converted in a string in decimal notation
+[manualfree]
+pub fn f32_to_str_l(f f32) string {
+ s := f32_to_str(f, 6)
+ res := fxx_to_str_l_parse(s)
+ unsafe { s.free() }
+ return res
+}
+
+[manualfree]
+pub fn f32_to_str_l_no_dot(f f32) string {
+ s := f32_to_str(f, 6)
+ res := fxx_to_str_l_parse_no_dot(s)
+ unsafe { s.free() }
+ return res
+}
+
+[manualfree]
+pub fn f64_to_str_l(f f64) string {
+ s := f64_to_str(f, 18)
+ res := fxx_to_str_l_parse(s)
+ unsafe { s.free() }
+ return res
+}
+
+[manualfree]
+pub fn f64_to_str_l_no_dot(f f64) string {
+ s := f64_to_str(f, 18)
+ res := fxx_to_str_l_parse_no_dot(s)
+ unsafe { s.free() }
+ return res
+}
+
+// f64_to_str_l return a string with the f64 converted in a string in decimal notation
+[manualfree]
+pub fn fxx_to_str_l_parse(s string) string {
+ // check for +inf -inf Nan
+ if s.len > 2 && (s[0] == `n` || s[1] == `i`) {
+ return s.clone()
+ }
+
+ m_sgn_flag := false
+ mut sgn := 1
+ mut b := [26]byte{}
+ mut d_pos := 1
+ mut i := 0
+ mut i1 := 0
+ mut exp := 0
+ mut exp_sgn := 1
+
+ // get sign and decimal parts
+ for c in s {
+ if c == `-` {
+ sgn = -1
+ i++
+ } else if c == `+` {
+ sgn = 1
+ i++
+ } else if c >= `0` && c <= `9` {
+ b[i1] = c
+ i1++
+ i++
+ } else if c == `.` {
+ if sgn > 0 {
+ d_pos = i
+ } else {
+ d_pos = i - 1
+ }
+ i++
+ } else if c == `e` {
+ i++
+ break
+ } else {
+ return 'Float conversion error!!'
+ }
+ }
+ b[i1] = 0
+
+ // get exponent
+ if s[i] == `-` {
+ exp_sgn = -1
+ i++
+ } else if s[i] == `+` {
+ exp_sgn = 1
+ i++
+ }
+
+ mut c := i
+ for c < s.len {
+ exp = exp * 10 + int(s[c] - `0`)
+ c++
+ }
+
+ // allocate exp+32 chars for the return string
+ mut res := []byte{len: exp + 32, init: 0}
+ mut r_i := 0 // result string buffer index
+
+ // println("s:${sgn} b:${b[0]} es:${exp_sgn} exp:${exp}")
+
+ if sgn == 1 {
+ if m_sgn_flag {
+ res[r_i] = `+`
+ r_i++
+ }
+ } else {
+ res[r_i] = `-`
+ r_i++
+ }
+
+ i = 0
+ if exp_sgn >= 0 {
+ for b[i] != 0 {
+ res[r_i] = b[i]
+ r_i++
+ i++
+ if i >= d_pos && exp >= 0 {
+ if exp == 0 {
+ res[r_i] = `.`
+ r_i++
+ }
+ exp--
+ }
+ }
+ for exp >= 0 {
+ res[r_i] = `0`
+ r_i++
+ exp--
+ }
+ } else {
+ mut dot_p := true
+ for exp > 0 {
+ res[r_i] = `0`
+ r_i++
+ exp--
+ if dot_p {
+ res[r_i] = `.`
+ r_i++
+ dot_p = false
+ }
+ }
+ for b[i] != 0 {
+ res[r_i] = b[i]
+ r_i++
+ i++
+ }
+ }
+ /*
+ // remove the dot form the numbers like 2.
+ if r_i > 1 && res[r_i-1] == `.` {
+ r_i--
+ }
+ */
+ res[r_i] = 0
+ return unsafe { tos(res.data, r_i) }
+}
+
+// f64_to_str_l return a string with the f64 converted in a string in decimal notation
+[manualfree]
+pub fn fxx_to_str_l_parse_no_dot(s string) string {
+ // check for +inf -inf Nan
+ if s.len > 2 && (s[0] == `n` || s[1] == `i`) {
+ return s.clone()
+ }
+
+ m_sgn_flag := false
+ mut sgn := 1
+ mut b := [26]byte{}
+ mut d_pos := 1
+ mut i := 0
+ mut i1 := 0
+ mut exp := 0
+ mut exp_sgn := 1
+
+ // get sign and decimal parts
+ for c in s {
+ if c == `-` {
+ sgn = -1
+ i++
+ } else if c == `+` {
+ sgn = 1
+ i++
+ } else if c >= `0` && c <= `9` {
+ b[i1] = c
+ i1++
+ i++
+ } else if c == `.` {
+ if sgn > 0 {
+ d_pos = i
+ } else {
+ d_pos = i - 1
+ }
+ i++
+ } else if c == `e` {
+ i++
+ break
+ } else {
+ return 'Float conversion error!!'
+ }
+ }
+ b[i1] = 0
+
+ // get exponent
+ if s[i] == `-` {
+ exp_sgn = -1
+ i++
+ } else if s[i] == `+` {
+ exp_sgn = 1
+ i++
+ }
+
+ mut c := i
+ for c < s.len {
+ exp = exp * 10 + int(s[c] - `0`)
+ c++
+ }
+
+ // allocate exp+32 chars for the return string
+ mut res := []byte{len: exp + 32, init: 0}
+ mut r_i := 0 // result string buffer index
+
+ // println("s:${sgn} b:${b[0]} es:${exp_sgn} exp:${exp}")
+
+ if sgn == 1 {
+ if m_sgn_flag {
+ res[r_i] = `+`
+ r_i++
+ }
+ } else {
+ res[r_i] = `-`
+ r_i++
+ }
+
+ i = 0
+ if exp_sgn >= 0 {
+ for b[i] != 0 {
+ res[r_i] = b[i]
+ r_i++
+ i++
+ if i >= d_pos && exp >= 0 {
+ if exp == 0 {
+ res[r_i] = `.`
+ r_i++
+ }
+ exp--
+ }
+ }
+ for exp >= 0 {
+ res[r_i] = `0`
+ r_i++
+ exp--
+ }
+ } else {
+ mut dot_p := true
+ for exp > 0 {
+ res[r_i] = `0`
+ r_i++
+ exp--
+ if dot_p {
+ res[r_i] = `.`
+ r_i++
+ dot_p = false
+ }
+ }
+ for b[i] != 0 {
+ res[r_i] = b[i]
+ r_i++
+ i++
+ }
+ }
+
+ // remove the dot form the numbers like 2.
+ if r_i > 1 && res[r_i - 1] == `.` {
+ r_i--
+ }
+
+ res[r_i] = 0
+ return unsafe { tos(res.data, r_i) }
+}
+
+// dec_digits return the number of decimal digit of an u64
+pub fn dec_digits(n u64) int {
+ if n <= 9_999_999_999 { // 1-10
+ if n <= 99_999 { // 5
+ if n <= 99 { // 2
+ if n <= 9 { // 1
+ return 1
+ } else {
+ return 2
+ }
+ } else {
+ if n <= 999 { // 3
+ return 3
+ } else {
+ if n <= 9999 { // 4
+ return 4
+ } else {
+ return 5
+ }
+ }
+ }
+ } else {
+ if n <= 9_999_999 { // 7
+ if n <= 999_999 { // 6
+ return 6
+ } else {
+ return 7
+ }
+ } else {
+ if n <= 99_999_999 { // 8
+ return 8
+ } else {
+ if n <= 999_999_999 { // 9
+ return 9
+ }
+ return 10
+ }
+ }
+ }
+ } else {
+ if n <= 999_999_999_999_999 { // 5
+ if n <= 999_999_999_999 { // 2
+ if n <= 99_999_999_999 { // 1
+ return 11
+ } else {
+ return 12
+ }
+ } else {
+ if n <= 9_999_999_999_999 { // 3
+ return 13
+ } else {
+ if n <= 99_999_999_999_999 { // 4
+ return 14
+ } else {
+ return 15
+ }
+ }
+ }
+ } else {
+ if n <= 99_999_999_999_999_999 { // 7
+ if n <= 9_999_999_999_999_999 { // 6
+ return 16
+ } else {
+ return 17
+ }
+ } else {
+ if n <= 999_999_999_999_999_999 { // 8
+ return 18
+ } else {
+ if n <= 9_999_999_999_999_999_999 { // 9
+ return 19
+ }
+ return 20
+ }
+ }
+ }
+ }
+}
diff --git a/v_windows/v/vlib/strconv/vprintf.v b/v_windows/v/vlib/strconv/vprintf.v
new file mode 100644
index 0000000..18e37b6
--- /dev/null
+++ b/v_windows/v/vlib/strconv/vprintf.v
@@ -0,0 +1,726 @@
+/*=============================================================================
+Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
+Use of this source code is governed by an MIT license
+that can be found in the LICENSE file.
+
+This file contains string interpolation V functions
+=============================================================================*/
+module strconv
+
+import strings
+
+enum Char_parse_state {
+ start
+ norm_char
+ field_char
+ pad_ch
+ len_set_start
+ len_set_in
+ check_type
+ check_float
+ check_float_in
+ reset_params
+}
+
+pub fn v_printf(str string, pt ...voidptr) {
+ print(v_sprintf(str, pt))
+}
+
+pub fn v_sprintf(str string, pt ...voidptr) string {
+ mut res := strings.new_builder(pt.len * 16)
+
+ mut i := 0 // main string index
+ mut p_index := 0 // parameter index
+ mut sign := false // sign flag
+ mut allign := Align_text.right
+ mut len0 := -1 // forced length, if -1 free length
+ mut len1 := -1 // decimal part for floats
+ def_len1 := 6 // default value for len1
+ mut pad_ch := byte(` `) // pad char
+
+ // prefix chars for Length field
+ mut ch1 := `0` // +1 char if present else `0`
+ mut ch2 := `0` // +2 char if present else `0`
+
+ mut status := Char_parse_state.norm_char
+ for i < str.len {
+ if status == .reset_params {
+ sign = false
+ allign = .right
+ len0 = -1
+ len1 = -1
+ pad_ch = ` `
+ status = .norm_char
+ ch1 = `0`
+ ch2 = `0`
+ continue
+ }
+
+ ch := str[i]
+ if ch != `%` && status == .norm_char {
+ res.write_b(ch)
+ i++
+ continue
+ }
+ if ch == `%` && status == .norm_char {
+ status = .field_char
+ i++
+ continue
+ }
+
+ // single char, manage it here
+ if ch == `c` && status == .field_char {
+ v_sprintf_panic(p_index, pt.len)
+ d1 := unsafe { *(&byte(pt[p_index])) }
+ res.write_b(d1)
+ status = .reset_params
+ p_index++
+ i++
+ continue
+ }
+
+ // pointer, manage it here
+ if ch == `p` && status == .field_char {
+ v_sprintf_panic(p_index, pt.len)
+ res.write_string('0x')
+ res.write_string(ptr_str(unsafe { pt[p_index] }))
+ status = .reset_params
+ p_index++
+ i++
+ continue
+ }
+
+ if status == .field_char {
+ mut fc_ch1 := `0`
+ mut fc_ch2 := `0`
+ if (i + 1) < str.len {
+ fc_ch1 = str[i + 1]
+ if (i + 2) < str.len {
+ fc_ch2 = str[i + 2]
+ }
+ }
+ if ch == `+` {
+ sign = true
+ i++
+ continue
+ } else if ch == `-` {
+ allign = .left
+ i++
+ continue
+ } else if ch in [`0`, ` `] {
+ if allign == .right {
+ pad_ch = ch
+ }
+ i++
+ continue
+ } else if ch == `'` {
+ i++
+ continue
+ } else if ch == `.` && fc_ch1 >= `1` && fc_ch1 <= `9` {
+ status = .check_float
+ i++
+ continue
+ }
+ // manage "%.*s" precision field
+ else if ch == `.` && fc_ch1 == `*` && fc_ch2 == `s` {
+ v_sprintf_panic(p_index, pt.len)
+ len := unsafe { *(&int(pt[p_index])) }
+ p_index++
+ v_sprintf_panic(p_index, pt.len)
+ mut s := unsafe { *(&string(pt[p_index])) }
+ s = s[..len]
+ p_index++
+ res.write_string(s)
+ status = .reset_params
+ i += 3
+ continue
+ }
+ status = .len_set_start
+ continue
+ }
+
+ if status == .len_set_start {
+ if ch >= `1` && ch <= `9` {
+ len0 = int(ch - `0`)
+ status = .len_set_in
+ i++
+ continue
+ }
+ if ch == `.` {
+ status = .check_float
+ i++
+ continue
+ }
+ status = .check_type
+ continue
+ }
+
+ if status == .len_set_in {
+ if ch >= `0` && ch <= `9` {
+ len0 *= 10
+ len0 += int(ch - `0`)
+ i++
+ continue
+ }
+ if ch == `.` {
+ status = .check_float
+ i++
+ continue
+ }
+ status = .check_type
+ continue
+ }
+
+ if status == .check_float {
+ if ch >= `0` && ch <= `9` {
+ len1 = int(ch - `0`)
+ status = .check_float_in
+ i++
+ continue
+ }
+ status = .check_type
+ continue
+ }
+
+ if status == .check_float_in {
+ if ch >= `0` && ch <= `9` {
+ len1 *= 10
+ len1 += int(ch - `0`)
+ i++
+ continue
+ }
+ status = .check_type
+ continue
+ }
+
+ if status == .check_type {
+ if ch == `l` {
+ if ch1 == `0` {
+ ch1 = `l`
+ i++
+ continue
+ } else {
+ ch2 = `l`
+ i++
+ continue
+ }
+ } else if ch == `h` {
+ if ch1 == `0` {
+ ch1 = `h`
+ i++
+ continue
+ } else {
+ ch2 = `h`
+ i++
+ continue
+ }
+ }
+ // signed integer
+ else if ch in [`d`, `i`] {
+ mut d1 := u64(0)
+ mut positive := true
+
+ // println("$ch1 $ch2")
+ match ch1 {
+ // h for 16 bit int
+ // hh fot 8 bit int
+ `h` {
+ if ch2 == `h` {
+ v_sprintf_panic(p_index, pt.len)
+ x := unsafe { *(&i8(pt[p_index])) }
+ positive = if x >= 0 { true } else { false }
+ d1 = if positive { u64(x) } else { u64(-x) }
+ } else {
+ x := unsafe { *(&i16(pt[p_index])) }
+ positive = if x >= 0 { true } else { false }
+ d1 = if positive { u64(x) } else { u64(-x) }
+ }
+ }
+ // l i64
+ // ll i64 for now
+ `l` {
+ // placeholder for future 128bit integer code
+ /*
+ if ch2 == `l` {
+ v_sprintf_panic(p_index, pt.len)
+ x := *(&i128(pt[p_index]))
+ positive = if x >= 0 { true } else { false }
+ d1 = if positive { u128(x) } else { u128(-x) }
+ } else {
+ v_sprintf_panic(p_index, pt.len)
+ x := *(&i64(pt[p_index]))
+ positive = if x >= 0 { true } else { false }
+ d1 = if positive { u64(x) } else { u64(-x) }
+ }
+ */
+ v_sprintf_panic(p_index, pt.len)
+ x := unsafe { *(&i64(pt[p_index])) }
+ positive = if x >= 0 { true } else { false }
+ d1 = if positive { u64(x) } else { u64(-x) }
+ }
+ // default int
+ else {
+ v_sprintf_panic(p_index, pt.len)
+ x := unsafe { *(&int(pt[p_index])) }
+ positive = if x >= 0 { true } else { false }
+ d1 = if positive { u64(x) } else { u64(-x) }
+ }
+ }
+ res.write_string(format_dec_old(d1,
+ pad_ch: pad_ch
+ len0: len0
+ len1: 0
+ positive: positive
+ sign_flag: sign
+ allign: allign
+ ))
+ status = .reset_params
+ p_index++
+ i++
+ ch1 = `0`
+ ch2 = `0`
+ continue
+ }
+ // unsigned integer
+ else if ch == `u` {
+ mut d1 := u64(0)
+ positive := true
+ v_sprintf_panic(p_index, pt.len)
+ match ch1 {
+ // h for 16 bit unsigned int
+ // hh fot 8 bit unsigned int
+ `h` {
+ if ch2 == `h` {
+ d1 = u64(unsafe { *(&byte(pt[p_index])) })
+ } else {
+ d1 = u64(unsafe { *(&u16(pt[p_index])) })
+ }
+ }
+ // l u64
+ // ll u64 for now
+ `l` {
+ // placeholder for future 128bit integer code
+ /*
+ if ch2 == `l` {
+ d1 = u128(*(&u128(pt[p_index])))
+ } else {
+ d1 = u64(*(&u64(pt[p_index])))
+ }
+ */
+ d1 = u64(unsafe { *(&u64(pt[p_index])) })
+ }
+ // default int
+ else {
+ d1 = u64(unsafe { *(&u32(pt[p_index])) })
+ }
+ }
+
+ res.write_string(format_dec_old(d1,
+ pad_ch: pad_ch
+ len0: len0
+ len1: 0
+ positive: positive
+ sign_flag: sign
+ allign: allign
+ ))
+ status = .reset_params
+ p_index++
+ i++
+ continue
+ }
+ // hex
+ else if ch in [`x`, `X`] {
+ v_sprintf_panic(p_index, pt.len)
+ mut s := ''
+ match ch1 {
+ // h for 16 bit int
+ // hh fot 8 bit int
+ `h` {
+ if ch2 == `h` {
+ x := unsafe { *(&i8(pt[p_index])) }
+ s = x.hex()
+ } else {
+ x := unsafe { *(&i16(pt[p_index])) }
+ s = x.hex()
+ }
+ }
+ // l i64
+ // ll i64 for now
+ `l` {
+ // placeholder for future 128bit integer code
+ /*
+ if ch2 == `l` {
+ x := *(&i128(pt[p_index]))
+ s = x.hex()
+ } else {
+ x := *(&i64(pt[p_index]))
+ s = x.hex()
+ }
+ */
+ x := unsafe { *(&i64(pt[p_index])) }
+ s = x.hex()
+ }
+ else {
+ x := unsafe { *(&int(pt[p_index])) }
+ s = x.hex()
+ }
+ }
+
+ if ch == `X` {
+ s = s.to_upper()
+ }
+
+ res.write_string(format_str(s,
+ pad_ch: pad_ch
+ len0: len0
+ len1: 0
+ positive: true
+ sign_flag: false
+ allign: allign
+ ))
+ status = .reset_params
+ p_index++
+ i++
+ continue
+ }
+
+ // float and double
+ if ch in [`f`, `F`] {
+ v_sprintf_panic(p_index, pt.len)
+ x := unsafe { *(&f64(pt[p_index])) }
+ positive := x >= f64(0.0)
+ len1 = if len1 >= 0 { len1 } else { def_len1 }
+ s := format_fl_old(f64(x),
+ pad_ch: pad_ch
+ len0: len0
+ len1: len1
+ positive: positive
+ sign_flag: sign
+ allign: allign
+ )
+ res.write_string(if ch == `F` { s.to_upper() } else { s })
+ status = .reset_params
+ p_index++
+ i++
+ continue
+ } else if ch in [`e`, `E`] {
+ v_sprintf_panic(p_index, pt.len)
+ x := unsafe { *(&f64(pt[p_index])) }
+ positive := x >= f64(0.0)
+ len1 = if len1 >= 0 { len1 } else { def_len1 }
+ s := format_es_old(f64(x),
+ pad_ch: pad_ch
+ len0: len0
+ len1: len1
+ positive: positive
+ sign_flag: sign
+ allign: allign
+ )
+ res.write_string(if ch == `E` { s.to_upper() } else { s })
+ status = .reset_params
+ p_index++
+ i++
+ continue
+ } else if ch in [`g`, `G`] {
+ v_sprintf_panic(p_index, pt.len)
+ x := unsafe { *(&f64(pt[p_index])) }
+ positive := x >= f64(0.0)
+ mut s := ''
+ tx := fabs(x)
+ if tx < 999_999.0 && tx >= 0.00001 {
+ // println("Here g format_fl [$tx]")
+ len1 = if len1 >= 0 { len1 + 1 } else { def_len1 }
+ s = format_fl_old(x,
+ pad_ch: pad_ch
+ len0: len0
+ len1: len1
+ positive: positive
+ sign_flag: sign
+ allign: allign
+ rm_tail_zero: true
+ )
+ } else {
+ len1 = if len1 >= 0 { len1 + 1 } else { def_len1 }
+ s = format_es_old(x,
+ pad_ch: pad_ch
+ len0: len0
+ len1: len1
+ positive: positive
+ sign_flag: sign
+ allign: allign
+ rm_tail_zero: true
+ )
+ }
+ res.write_string(if ch == `G` { s.to_upper() } else { s })
+ status = .reset_params
+ p_index++
+ i++
+ continue
+ }
+ // string
+ else if ch == `s` {
+ v_sprintf_panic(p_index, pt.len)
+ s1 := unsafe { *(&string(pt[p_index])) }
+ pad_ch = ` `
+ res.write_string(format_str(s1,
+ pad_ch: pad_ch
+ len0: len0
+ len1: 0
+ positive: true
+ sign_flag: false
+ allign: allign
+ ))
+ status = .reset_params
+ p_index++
+ i++
+ continue
+ }
+ }
+
+ status = .reset_params
+ p_index++
+ i++
+ }
+
+ if p_index != pt.len {
+ panic('$p_index % conversion specifiers, but given $pt.len args')
+ }
+
+ return res.str()
+}
+
+[inline]
+fn v_sprintf_panic(idx int, len int) {
+ if idx >= len {
+ panic('${idx + 1} % conversion specifiers, but given only $len args')
+ }
+}
+
+fn fabs(x f64) f64 {
+ if x < 0.0 {
+ return -x
+ }
+ return x
+}
+
+// strings.Builder version of format_fl
+[manualfree]
+pub fn format_fl_old(f f64, p BF_param) string {
+ unsafe {
+ mut s := ''
+ // mut fs := "1.2343"
+ mut fs := f64_to_str_lnd1(if f >= 0.0 { f } else { -f }, p.len1)
+ // println("Dario")
+ // println(fs)
+
+ // error!!
+ if fs[0] == `[` {
+ s.free()
+ return fs
+ }
+
+ if p.rm_tail_zero {
+ tmp := fs
+ fs = remove_tail_zeros_old(fs)
+ tmp.free()
+ }
+ mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
+
+ mut sign_len_diff := 0
+ if p.pad_ch == `0` {
+ if p.positive {
+ if p.sign_flag {
+ res.write_b(`+`)
+ sign_len_diff = -1
+ }
+ } else {
+ res.write_b(`-`)
+ sign_len_diff = -1
+ }
+ tmp := s
+ s = fs.clone()
+ tmp.free()
+ } else {
+ if p.positive {
+ if p.sign_flag {
+ tmp := s
+ s = '+' + fs
+ tmp.free()
+ } else {
+ tmp := s
+ s = fs.clone()
+ tmp.free()
+ }
+ } else {
+ tmp := s
+ s = '-' + fs
+ tmp.free()
+ }
+ }
+
+ dif := p.len0 - s.len + sign_len_diff
+
+ if p.allign == .right {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ res.write_string(s)
+ if p.allign == .left {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+
+ s.free()
+ fs.free()
+ tmp_res := res.str()
+ res.free()
+ return tmp_res
+ }
+}
+
+[manualfree]
+pub fn format_es_old(f f64, p BF_param) string {
+ unsafe {
+ mut s := ''
+ mut fs := f64_to_str_pad(if f > 0 { f } else { -f }, p.len1)
+ if p.rm_tail_zero {
+ fs = remove_tail_zeros_old(fs)
+ }
+ mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
+
+ mut sign_len_diff := 0
+ if p.pad_ch == `0` {
+ if p.positive {
+ if p.sign_flag {
+ res.write_b(`+`)
+ sign_len_diff = -1
+ }
+ } else {
+ res.write_b(`-`)
+ sign_len_diff = -1
+ }
+ tmp := s
+ s = fs.clone()
+ tmp.free()
+ } else {
+ if p.positive {
+ if p.sign_flag {
+ tmp := s
+ s = '+' + fs
+ tmp.free()
+ } else {
+ tmp := s
+ s = fs.clone()
+ tmp.free()
+ }
+ } else {
+ tmp := s
+ s = '-' + fs
+ tmp.free()
+ }
+ }
+
+ dif := p.len0 - s.len + sign_len_diff
+ if p.allign == .right {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ res.write_string(s)
+ if p.allign == .left {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ s.free()
+ fs.free()
+ tmp_res := res.str()
+ res.free()
+ return tmp_res
+ }
+}
+
+pub fn remove_tail_zeros_old(s string) string {
+ mut i := 0
+ mut last_zero_start := -1
+ mut dot_pos := -1
+ mut in_decimal := false
+ mut prev_ch := byte(0)
+ for i < s.len {
+ ch := unsafe { s.str[i] }
+ if ch == `.` {
+ in_decimal = true
+ dot_pos = i
+ } else if in_decimal {
+ if ch == `0` && prev_ch != `0` {
+ last_zero_start = i
+ } else if ch >= `1` && ch <= `9` {
+ last_zero_start = -1
+ } else if ch == `e` {
+ break
+ }
+ }
+ prev_ch = ch
+ i++
+ }
+
+ mut tmp := ''
+ if last_zero_start > 0 {
+ if last_zero_start == dot_pos + 1 {
+ tmp = s[..dot_pos] + s[i..]
+ } else {
+ tmp = s[..last_zero_start] + s[i..]
+ }
+ } else {
+ tmp = s
+ }
+ if unsafe { tmp.str[tmp.len - 1] } == `.` {
+ return tmp[..tmp.len - 1]
+ }
+ return tmp
+}
+
+// max int64 9223372036854775807
+pub fn format_dec_old(d u64, p BF_param) string {
+ mut s := ''
+ mut res := strings.new_builder(20)
+ mut sign_len_diff := 0
+ if p.pad_ch == `0` {
+ if p.positive {
+ if p.sign_flag {
+ res.write_b(`+`)
+ sign_len_diff = -1
+ }
+ } else {
+ res.write_b(`-`)
+ sign_len_diff = -1
+ }
+ s = d.str()
+ } else {
+ if p.positive {
+ if p.sign_flag {
+ s = '+' + d.str()
+ } else {
+ s = d.str()
+ }
+ } else {
+ s = '-' + d.str()
+ }
+ }
+ dif := p.len0 - s.len + sign_len_diff
+
+ if p.allign == .right {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ res.write_string(s)
+ if p.allign == .left {
+ for i1 := 0; i1 < dif; i1++ {
+ res.write_b(p.pad_ch)
+ }
+ }
+ return res.str()
+}