strconv: vfmt everything

pull/10508/head
Delyan Angelov 2021-06-18 17:59:56 +03:00
parent 5dff8dc097
commit de384f1cc8
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
17 changed files with 1544 additions and 1252 deletions

View File

@ -43,7 +43,6 @@ const (
'vlib/',
]
vfmt_known_failing_exceptions = arrays.merge(verify_known_failing_exceptions, [
'vlib/strconv/' /* prevent conflicts, till the new pure V string interpolation is merged */,
'vlib/term/ui/input.v' /* comment after a struct embed is removed */,
'vlib/regex/regex_test.v' /* contains meaningfull formatting of the test case data */,
'vlib/readline/readline_test.v' /* vfmt eats `{ Readline }` from `import readline { Readline }` */,

View File

@ -414,7 +414,6 @@ 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{}

View File

@ -1,4 +1,5 @@
import strconv
/**********************************************************************
*
* String to float Test
@ -18,7 +19,7 @@ fn test_atof() {
-0.004,
0.0,
-0.0,
31234567890123
31234567890123,
]
// strings
@ -37,7 +38,6 @@ fn test_atof() {
// 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())
@ -71,5 +71,5 @@ fn test_atof() {
// double_minus_zero
f1 = -0.0
assert *ptr == u64(0x8000000000000000)
println("DONE!")
println('DONE!')
}

File diff suppressed because one or more lines are too long

View File

@ -69,15 +69,15 @@ pub fn common_parse_uint2(s string, _base int, _bit_size int) (u64, int) {
return u64(0), -1
}
if bit_size == 0 {
bit_size = int_size
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 := max_u64 / u64(base) + u64(1)
max_val := if bit_size == 64 { max_u64 } else { (u64(1) << u64(bit_size)) - u64(1) }
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]
@ -144,7 +144,7 @@ pub fn common_parse_int(_s string, base int, _bit_size int, error_on_non_digit b
return i64(0)
}
if bit_size == 0 {
bit_size = int_size
bit_size = strconv.int_size
}
// TODO: check should u64(bit_size-1) be size of int (32)?
cutoff := u64(1) << u64(bit_size - 1)
@ -156,11 +156,7 @@ pub fn common_parse_int(_s string, base int, _bit_size int, error_on_non_digit b
// return error('parse_int: range error $s0')
return -i64(cutoff)
}
return if neg {
-i64(un)
} else {
i64(un)
}
return if neg { -i64(un) } else { i64(un) }
}
// parse_int interprets a string s in the given base (0, 2 to 36) and
@ -184,9 +180,8 @@ pub fn atoi(s string) ?int {
if s == '' {
return error('strconv.atoi: parsing "$s": invalid syntax ')
}
if (int_size == 32 && (0 < s.len &&
s.len < 10)) ||
(int_size == 64 && (0 < s.len && s.len < 19)) {
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] == `+` {
@ -205,11 +200,7 @@ pub fn atoi(s string) ?int {
}
n = n * 10 + int(ch)
}
return if s[0] == `-` {
-n
} else {
n
}
return if s[0] == `-` { -n } else { n }
}
// Slow path for invalid, big, or underscored integers.
int64 := parse_int(s, 10, 0)
@ -233,8 +224,8 @@ fn underscore_ok(s string) bool {
}
// 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`) {
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
@ -242,8 +233,8 @@ fn underscore_ok(s string) bool {
// 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`) {
if (`0` <= s[i] && s[i] <= `9`) || (hex && `a` <= byte_to_lower(s[i])
&& byte_to_lower(s[i]) <= `f`) {
saw = `0`
continue
}

View File

@ -1,4 +1,5 @@
module strconv
/*=============================================================================
f32 to string
@ -78,8 +79,8 @@ pub fn (d Dec32) get_string_32(neg bool, i_n_digit int, i_pad_digit int) string
if n_digit < out_len {
// println("orig: ${out_len_original}")
out += ten_pow_table_32[out_len - n_digit - 1] * 5 // round to up
out /= ten_pow_table_32[out_len - n_digit]
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
}
@ -96,7 +97,7 @@ pub fn (d Dec32) get_string_32(neg bool, i_n_digit int, i_pad_digit int) string
if i_n_digit == 0 {
unsafe {
buf[i] = 0
return tos(byteptr(&buf[0]), i)
return tos(&byte(&buf[0]), i)
}
}
@ -140,17 +141,17 @@ pub fn (d Dec32) get_string_32(neg bool, i_n_digit int, i_pad_digit int) string
buf[i] = 0
return unsafe {
tos(byteptr(&buf[0]), i)
tos(&byte(&buf[0]), i)
}
}
fn f32_to_decimal_exact_int(i_mant u32, exp u32) (Dec32, bool) {
mut d := Dec32{}
e := exp - bias32
if e > mantbits32 {
e := exp - strconv.bias32
if e > strconv.mantbits32 {
return d, false
}
shift := mantbits32 - e
shift := strconv.mantbits32 - e
mant := i_mant | 0x0080_0000 // implicit 1
// mant := i_mant | (1 << mantbits32) // implicit 1
d.m = mant >> shift
@ -170,11 +171,11 @@ fn f32_to_decimal(mant u32, exp u32) Dec32 {
if exp == 0 {
// We subtract 2 so that the bounds computation has
// 2 additional bits.
e2 = 1 - bias32 - int(mantbits32) - 2
e2 = 1 - strconv.bias32 - int(strconv.mantbits32) - 2
m2 = mant
} else {
e2 = int(exp) - bias32 - int(mantbits32) - 2
m2 = (u32(1) << mantbits32) | mant
e2 = int(exp) - strconv.bias32 - int(strconv.mantbits32) - 2
m2 = (u32(1) << strconv.mantbits32) | mant
}
even := (m2 & 1) == 0
accept_bounds := even
@ -306,7 +307,10 @@ fn f32_to_decimal(mant u32, exp u32) Dec32 {
out = vr + bool_to_u32(vr == vm || last_removed_digit >= 5)
}
return Dec32{m: out e: e10 + removed}
return Dec32{
m: out
e: e10 + removed
}
}
//=============================================================================
@ -319,14 +323,14 @@ pub fn f32_to_str(f f32, n_digit int) string {
u1.f = f
u := unsafe { u1.u }
neg := (u >> (mantbits32 + expbits32)) != 0
mant := u & ((u32(1) << mantbits32) - u32(1))
exp := (u >> mantbits32) & ((u32(1) << expbits32) - u32(1))
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 == maxexp32) || (exp == 0 && mant == 0) {
if (exp == strconv.maxexp32) || (exp == 0 && mant == 0) {
return get_string_special(neg, exp == 0, mant == 0)
}
@ -346,14 +350,14 @@ pub fn f32_to_str_pad(f f32, n_digit int) string {
u1.f = f
u := unsafe { u1.u }
neg := (u >> (mantbits32 + expbits32)) != 0
mant := u & ((u32(1) << mantbits32) - u32(1))
exp := (u >> mantbits32) & ((u32(1) << expbits32) - u32(1))
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 == maxexp32) || (exp == 0 && mant == 0) {
if (exp == strconv.maxexp32) || (exp == 0 && mant == 0) {
return get_string_special(neg, exp == 0, mant == 0)
}

View File

@ -1,4 +1,5 @@
module strconv
/*=============================================================================
f64 to string
@ -86,10 +87,10 @@ fn (d Dec64) get_string_64(neg bool, i_n_digit int, i_pad_digit int) string {
// rounding last used digit
if n_digit < out_len {
// println("out:[$out]")
out += ten_pow_table_64[out_len - n_digit - 1] * 5 // round to up
out /= ten_pow_table_64[out_len - n_digit]
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 / ten_pow_table_64[out_len - n_digit] < out {
if d.m / strconv.ten_pow_table_64[out_len - n_digit] < out {
d_exp++
n_digit++
}
@ -113,7 +114,7 @@ fn (d Dec64) get_string_64(neg bool, i_n_digit int, i_pad_digit int) string {
if i_n_digit == 0 {
unsafe {
buf[i] = 0
return tos(byteptr(&buf[0]), i)
return tos(&byte(&buf[0]), i)
}
}
@ -163,17 +164,17 @@ fn (d Dec64) get_string_64(neg bool, i_n_digit int, i_pad_digit int) string {
buf[i] = 0
return unsafe {
tos(byteptr(&buf[0]), i)
tos(&byte(&buf[0]), i)
}
}
fn f64_to_decimal_exact_int(i_mant u64, exp u64) (Dec64, bool) {
mut d := Dec64{}
e := exp - bias64
if e > mantbits64 {
e := exp - strconv.bias64
if e > strconv.mantbits64 {
return d, false
}
shift := mantbits64 - e
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
@ -194,11 +195,11 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 {
if exp == 0 {
// We subtract 2 so that the bounds computation has
// 2 additional bits.
e2 = 1 - bias64 - int(mantbits64) - 2
e2 = 1 - strconv.bias64 - int(strconv.mantbits64) - 2
m2 = mant
} else {
e2 = int(exp) - bias64 - int(mantbits64) - 2
m2 = (u64(1) << mantbits64) | mant
e2 = int(exp) - strconv.bias64 - int(strconv.mantbits64) - 2
m2 = (u64(1) << strconv.mantbits64) | mant
}
even := (m2 & 1) == 0
accept_bounds := even
@ -237,7 +238,8 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 {
// 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)
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--
}
@ -355,7 +357,10 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 {
out = vr + bool_to_u64(vr == vm || round_up)
}
return Dec64{m: out, e: e10 + removed}
return Dec64{
m: out
e: e10 + removed
}
}
//=============================================================================
@ -368,13 +373,13 @@ pub fn f64_to_str(f f64, n_digit int) string {
u1.f = f
u := unsafe { u1.u }
neg := (u >> (mantbits64 + expbits64)) != 0
mant := u & ((u64(1) << mantbits64) - u64(1))
exp := (u >> mantbits64) & ((u64(1) << expbits64) - u64(1))
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 == maxexp64) || (exp == 0 && mant == 0) {
if (exp == strconv.maxexp64) || (exp == 0 && mant == 0) {
return get_string_special(neg, exp == 0, mant == 0)
}
@ -393,13 +398,13 @@ pub fn f64_to_str_pad(f f64, n_digit int) string {
u1.f = f
u := unsafe { u1.u }
neg := (u >> (mantbits64 + expbits64)) != 0
mant := u & ((u64(1) << mantbits64) - u64(1))
exp := (u >> mantbits64) & ((u64(1) << expbits64) - u64(1))
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 == maxexp64) || (exp == 0 && mant == 0) {
if (exp == strconv.maxexp64) || (exp == 0 && mant == 0) {
return get_string_special(neg, exp == 0, mant == 0)
}

View File

@ -1,7 +1,6 @@
module strconv
/*
printf/sprintf V implementation
Copyright (c) 2020 Dario Deledda. All rights reserved.
@ -9,9 +8,7 @@ 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 {
@ -21,9 +18,7 @@ pub enum Align_text {
}
/*
Float conversion utility
*/
const (
// rounding value
@ -81,9 +76,7 @@ const(
// max float 1.797693134862315708145274237317043567981e+308
/*
Single format functions
*/
pub struct BF_param {
pub mut:

View File

@ -6,6 +6,7 @@ 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
@ -103,10 +104,14 @@ pub fn format_dec_sb(d u64, p BF_param, mut res strings.Builder) {
// calculate the digit_pairs start index
d_i = (n - (n1 * 100)) << 1
n = n1
unsafe{ buf[i] = digit_pairs.str[d_i] }
unsafe {
buf[i] = strconv.digit_pairs.str[d_i]
}
i--
d_i++
unsafe{ buf[i] = digit_pairs.str[d_i] }
unsafe {
buf[i] = strconv.digit_pairs.str[d_i]
}
i--
}
i++
@ -115,7 +120,6 @@ pub fn format_dec_sb(d u64, p BF_param, mut res strings.Builder) {
i++
}
unsafe { res.write_ptr(&buf[i], n_char) }
} else {
// we have a zero no need of more code!
res.write_b(`0`)
@ -130,10 +134,7 @@ pub fn format_dec_sb(d u64, p BF_param, mut res strings.Builder) {
return
}
[manualfree]
[direct_array_access]
[direct_array_access; manualfree]
pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
unsafe {
// we add the rounding value
@ -162,8 +163,7 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
} else if c == `+` {
sgn = 1
i++
}
else if c >= `0` && c <= `9` {
} else if c >= `0` && c <= `9` {
b[i1] = c
i1++
i++
@ -179,7 +179,7 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
break
} else {
s.free()
return "[Float conversion error!!]"
return '[Float conversion error!!]'
}
}
b[i1] = 0
@ -293,7 +293,6 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
res.free()
return tmp_res
}
}
}
@ -301,7 +300,7 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
[manualfree]
pub fn format_fl(f f64, p BF_param) string {
unsafe {
mut s := ""
mut s := ''
// mut fs := "1.2343"
mut fs := f64_to_str_lnd1(if f >= 0.0 { f } else { -f }, p.len1)
// println("Dario")
@ -338,7 +337,7 @@ pub fn format_fl(f f64, p BF_param) string {
if p.positive {
if p.sign_flag {
tmp := s
s = "+" + fs
s = '+' + fs
tmp.free()
} else {
tmp := s
@ -347,7 +346,7 @@ pub fn format_fl(f f64, p BF_param) string {
}
} else {
tmp := s
s = "-" + fs
s = '-' + fs
tmp.free()
}
}
@ -366,7 +365,6 @@ pub fn format_fl(f f64, p BF_param) string {
}
}
s.free()
fs.free()
tmp_res := res.str()
@ -378,7 +376,7 @@ pub fn format_fl(f f64, p BF_param) string {
[manualfree]
pub fn format_es(f f64, p BF_param) string {
unsafe {
mut s := ""
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)
@ -403,7 +401,7 @@ pub fn format_es(f f64, p BF_param) string {
if p.positive {
if p.sign_flag {
tmp := s
s = "+" + fs
s = '+' + fs
tmp.free()
} else {
tmp := s
@ -412,7 +410,7 @@ pub fn format_es(f f64, p BF_param) string {
}
} else {
tmp := s
s = "-" + fs
s = '-' + fs
tmp.free()
}
}

View File

@ -1,21 +1,21 @@
import strconv
fn test_format() {
mut temp_s := ""
mut tmp_str:= ""
mut temp_s := ''
mut tmp_str := ''
a0 := u32(10)
b0 := 200
c0 := byte(12)
s0 := "ciAo"
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]"
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]"
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
@ -24,9 +24,9 @@ fn test_format(){
b := i16(13)
c := 14
d := i64(15)
sc1 := "==>%hhd %hd %d %ld"
sc1 := '==>%hhd %hd %d %ld'
temp_s = strconv.v_sprintf(sc1, a, b, c, d)
tmp_str = "==>12 13 14 15"
tmp_str = '==>12 13 14 15'
// C.printf(sc1.str, a ,b ,c, d)
// println("\n$temp_s")
assert tmp_str == temp_s
@ -35,69 +35,69 @@ fn test_format(){
b1 := i16(0xffff)
c1 := u32(0xffff_ffff)
d1 := u64(-1)
sc2 := "%hhu %hu %u %lu"
sc2 := '%hhu %hu %u %lu'
temp_s = strconv.v_sprintf(sc2, a1, b1, c1, d1)
tmp_str = "255 65535 4294967295 18446744073709551615"
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"
sc3 := '%hhx %hx %x %lx'
temp_s = strconv.v_sprintf(sc3, a1, b1, c1, d1)
tmp_str = "ff ffff ffffffff ffffffffffffffff"
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]"
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 ]"
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]"
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]"
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]"
sc6 := '%.*s [%05hhX]'
temp_s = strconv.v_sprintf(sc6, ml, s0, a)
tmp_str = "ciA [0000C]"
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]"
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]"
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]|"
'[ -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]|"
sc8 := '[%20g][%20G]|'
for x < 12 {
temp_s = strconv.v_sprintf(sc8, ft, ft)
// C.printf(sc8.str, ft, ft)

View File

@ -1,7 +1,6 @@
module strconv
/*
f32/f64 ftoa functions
Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
@ -17,7 +16,6 @@ Pages 270282 https://doi.org/10.1145/3192366.3192369
inspired by the Go version here:
https://github.com/cespare/ryu/tree/ba56a33f39e3bbbfa409095d0f9ae168a595feea
*/
[inline]

View File

@ -22,7 +22,7 @@ pub fn format_int(n i64, radix int) string {
mut res := ''
for n_copy != 0 {
tmp_0 := res
tmp_1 := base_digits[n_copy % radix].ascii_str()
tmp_1 := strconv.base_digits[n_copy % radix].ascii_str()
res = tmp_1 + res
tmp_0.free()
tmp_1.free()
@ -49,7 +49,7 @@ pub fn format_uint(n u64, radix int) string {
uradix := u64(radix)
for n_copy != 0 {
tmp_0 := res
tmp_1 := base_digits[n_copy % uradix].ascii_str()
tmp_1 := strconv.base_digits[n_copy % uradix].ascii_str()
res = tmp_1 + res
tmp_0.free()
tmp_1.free()

View File

@ -32,8 +32,7 @@ fn test_format_uint() {
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, 2) == '1111111111111111111111111111111111111111111111111111111111111111'
assert strconv.format_uint(18446744073709551615, 16) == 'ffffffffffffffff'
assert strconv.parse_int('baobab', 36, 64) == 683058467
assert strconv.format_uint(683058467, 36) == 'baobab'

View File

@ -29,29 +29,87 @@ powers_of_10 = [
]
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)
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)
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 = [
@ -380,7 +438,7 @@ pow5_split_64 =[
Uint128{u64(0xd070b763396297bf), u64(0x0194bd136316c046)},
Uint128{u64(0x848ce53c07bb3daf), u64(0x01f9ec583bdc7058)},
Uint128{u64(0x52d80f4584d5068d), u64(0x013c33b72569c637)},
Uint128{u64(0x278e1316e60a4831), u64(0x018b40a4eec437c5)}
Uint128{u64(0x278e1316e60a4831), u64(0x018b40a4eec437c5)},
]
pow5_inv_split_64 = [
@ -675,6 +733,6 @@ pow5_inv_split_64 = [
Uint128{u64(0xdd3b8d9fe50c2bb1), u64(0x026fb3398a0dab15)},
Uint128{u64(0x952c15cca1ad12b5), u64(0x03e5eb8f434911bc)},
Uint128{u64(0x775677d6e7bda891), u64(0x031e560c35d40e30)},
Uint128{u64(0xc5dec645863153a7), u64(0x027eab3cf7dcd826)}
Uint128{u64(0xc5dec645863153a7), u64(0x027eab3cf7dcd826)},
]
)

View File

@ -1,7 +1,6 @@
module strconv
/*
f32/f64 to string utilities
Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
@ -17,17 +16,13 @@ Pages 270282 https://doi.org/10.1145/3192366.3192369
inspired by the Go version here:
https://github.com/cespare/ryu/tree/ba56a33f39e3bbbfa409095d0f9ae168a595feea
*/
import math.bits
// import math
/*
General Utilities
*/
fn assert1(t bool, msg string) {
if !t {
@ -61,25 +56,23 @@ fn bool_to_u64(b bool) u64 {
fn get_string_special(neg bool, expZero bool, mantZero bool) string {
if !mantZero {
return "nan"
return 'nan'
}
if !expZero {
if neg {
return "-inf"
return '-inf'
} else {
return "+inf"
return '+inf'
}
}
if neg {
return "-0e+00"
return '-0e+00'
}
return "0e+00"
return '0e+00'
}
/*
32 bit functions
*/
// decimal_len_32 return the number of decimal digits of the input
[deprecated]
@ -87,16 +80,25 @@ pub fn decimal_len_32(u u32) int {
// Function precondition: u is not a 10-digit number.
// (9 digits are sufficient for round-tripping.)
// This benchmarked faster than the log2 approach used for u64.
assert1(u < 1000000000, "too big")
assert1(u < 1000000000, 'too big')
if u >= 100000000 { return 9 }
else if u >= 10000000 { return 8 }
else if u >= 1000000 { return 7 }
else if u >= 100000 { return 6 }
else if u >= 10000 { return 5 }
else if u >= 1000 { return 4 }
else if u >= 100 { return 3 }
else if u >= 10 { return 2 }
if u >= 100000000 {
return 9
} else if u >= 10000000 {
return 8
} else if u >= 1000000 {
return 7
} else if u >= 100000 {
return 6
} else if u >= 10000 {
return 5
} else if u >= 1000 {
return 4
} else if u >= 100 {
return 3
} else if u >= 10 {
return 2
}
return 1
}
@ -106,7 +108,7 @@ fn mul_shift_32(m u32, mul u64, ishift int) u32 {
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")
assert1(shifted_sum <= 2147483647, 'shiftedSum <= math.max_u32')
return u32(shifted_sum)
}
@ -120,7 +122,7 @@ fn mul_pow5_div_pow2(m u32, i u32, j int) u32 {
fn pow5_factor_32(i_v u32) u32 {
mut v := i_v
for n := u32(0); ; n++ {
for n := u32(0); true; n++ {
q := v / 5
r := v % 5
if r != 0 {
@ -145,8 +147,8 @@ fn multiple_of_power_of_two_32(v u32, p u32) bool {
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")
assert1(e >= 0, 'e >= 0')
assert1(e <= 1650, 'e <= 1650')
return (u32(e) * 78913) >> 18
}
@ -154,8 +156,8 @@ fn log10_pow2(e int) u32 {
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")
assert1(e >= 0, 'e >= 0')
assert1(e <= 2620, 'e <= 2620')
return (u32(e) * 732923) >> 20
}
@ -164,18 +166,17 @@ 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")
assert1(e >= 0, 'e >= 0')
assert1(e <= 3528, 'e <= 3528')
return int(((u32(e) * 1217359) >> 19) + 1)
}
/*
64 bit functions
*/
[deprecated]
// decimal_len_64 return the number of decimal digits of the input
[deprecated]
pub fn decimal_len_64(u u64) int {
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
log2 := 64 - bits.leading_zeros_64(u) - 1
@ -190,14 +191,17 @@ fn shift_right_128(v Uint128, shift int) u64 {
// (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")
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}
mut sum := Uint128{
lo: lohi + hilo
hi: hihi
}
if sum.lo < lohi {
sum.hi++ // overflow
}
@ -206,7 +210,7 @@ fn mul_shift_64(m u64, mul Uint128, shift int) u64 {
fn pow5_factor_64(v_i u64) u32 {
mut v := v_i
for n := u32(0); ; n++ {
for n := u32(0); true; n++ {
q := v / 5
r := v % 5
if r != 0 {
@ -226,9 +230,7 @@ fn multiple_of_power_of_two_64(v u64, p u32) bool {
}
/*
f64 to string with string format
*/
// TODO: Investigate precision issues
@ -265,7 +267,6 @@ pub fn f64_to_str_l_no_dot(f f64) string {
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 {
@ -291,8 +292,7 @@ pub fn fxx_to_str_l_parse(s string) string {
} else if c == `+` {
sgn = 1
i++
}
else if c >= `0` && c <= `9` {
} else if c >= `0` && c <= `9` {
b[i1] = c
i1++
i++
@ -307,7 +307,7 @@ pub fn fxx_to_str_l_parse(s string) string {
i++
break
} else {
return "Float conversion error!!"
return 'Float conversion error!!'
}
}
b[i1] = 0
@ -415,8 +415,7 @@ pub fn fxx_to_str_l_parse_no_dot(s string) string {
} else if c == `+` {
sgn = 1
i++
}
else if c >= `0` && c <= `9` {
} else if c >= `0` && c <= `9` {
b[i1] = c
i1++
i++
@ -431,7 +430,7 @@ pub fn fxx_to_str_l_parse_no_dot(s string) string {
i++
break
} else {
return "Float conversion error!!"
return 'Float conversion error!!'
}
}
b[i1] = 0

View File

@ -6,6 +6,7 @@ that can be found in the LICENSE file.
This file contains string interpolation V functions
=============================================================================*/
module strconv
import strings
enum Char_parse_state {
@ -15,11 +16,9 @@ enum Char_parse_state {
pad_ch
len_set_start
len_set_in
check_type
check_float
check_float_in
reset_params
}
@ -83,7 +82,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
// pointer, manage it here
if ch == `p` && status == .field_char {
v_sprintf_panic(p_index, pt.len)
res.write_string("0x")
res.write_string('0x')
res.write_string(ptr_str(unsafe { pt[p_index] }))
status = .reset_params
p_index++
@ -114,7 +113,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
}
i++
continue
} else if ch == `'` {
} else if ch == `\'` {
i++
continue
} else if ch == `.` && fc_ch1 >= `1` && fc_ch1 <= `9` {
@ -195,7 +194,6 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
}
if status == .check_type {
if ch == `l` {
if ch1 == `0` {
ch1 = `l`
@ -206,8 +204,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
i++
continue
}
}
else if ch == `h` {
} else if ch == `h` {
if ch1 == `0` {
ch1 = `h`
i++
@ -218,7 +215,6 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
continue
}
}
// signed integer
else if ch in [`d`, `i`] {
mut d1 := u64(0)
@ -269,9 +265,15 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
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}))
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++
@ -279,7 +281,6 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
ch2 = `0`
continue
}
// unsigned integer
else if ch == `u` {
mut d1 := u64(0)
@ -314,17 +315,23 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
}
}
res.write_string(format_dec_old(d1,{pad_ch: pad_ch, len0: len0, len1: 0, positive: positive, sign_flag: sign, allign: allign}))
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 := ""
mut s := ''
match ch1 {
// h for 16 bit int
// hh fot 8 bit int
@ -363,7 +370,14 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
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}))
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++
@ -376,38 +390,66 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
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})
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`] {
} 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})
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`] {
} 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 := ""
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})
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})
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
@ -415,13 +457,19 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
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}))
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++
@ -435,7 +483,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
}
if p_index != pt.len {
panic('${p_index} % conversion specifiers, but given ${pt.len} args')
panic('$p_index % conversion specifiers, but given $pt.len args')
}
return res.str()
@ -444,7 +492,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
[inline]
fn v_sprintf_panic(idx int, len int) {
if idx >= len {
panic('${idx+1} % conversion specifiers, but given only ${len} args')
panic('${idx + 1} % conversion specifiers, but given only $len args')
}
}
@ -459,7 +507,7 @@ fn fabs(x f64) f64 {
[manualfree]
pub fn format_fl_old(f f64, p BF_param) string {
unsafe {
mut s := ""
mut s := ''
// mut fs := "1.2343"
mut fs := f64_to_str_lnd1(if f >= 0.0 { f } else { -f }, p.len1)
// println("Dario")
@ -496,7 +544,7 @@ pub fn format_fl_old(f f64, p BF_param) string {
if p.positive {
if p.sign_flag {
tmp := s
s = "+" + fs
s = '+' + fs
tmp.free()
} else {
tmp := s
@ -505,7 +553,7 @@ pub fn format_fl_old(f f64, p BF_param) string {
}
} else {
tmp := s
s = "-" + fs
s = '-' + fs
tmp.free()
}
}
@ -524,7 +572,6 @@ pub fn format_fl_old(f f64, p BF_param) string {
}
}
s.free()
fs.free()
tmp_res := res.str()
@ -536,7 +583,7 @@ pub fn format_fl_old(f f64, p BF_param) string {
[manualfree]
pub fn format_es_old(f f64, p BF_param) string {
unsafe {
mut s := ""
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)
@ -561,7 +608,7 @@ pub fn format_es_old(f f64, p BF_param) string {
if p.positive {
if p.sign_flag {
tmp := s
s = "+" + fs
s = '+' + fs
tmp.free()
} else {
tmp := s
@ -570,7 +617,7 @@ pub fn format_es_old(f f64, p BF_param) string {
}
} else {
tmp := s
s = "-" + fs
s = '-' + fs
tmp.free()
}
}
@ -606,8 +653,7 @@ pub fn remove_tail_zeros_old(s string) string {
if ch == `.` {
in_decimal = true
dot_pos = i
}
else if in_decimal {
} else if in_decimal {
if ch == `0` && prev_ch != `0` {
last_zero_start = i
} else if ch >= `1` && ch <= `9` {
@ -620,7 +666,7 @@ pub fn remove_tail_zeros_old(s string) string {
i++
}
mut tmp := ""
mut tmp := ''
if last_zero_start > 0 {
if last_zero_start == dot_pos + 1 {
tmp = s[..dot_pos] + s[i..]
@ -638,7 +684,7 @@ pub fn remove_tail_zeros_old(s string) string {
// max int64 9223372036854775807
pub fn format_dec_old(d u64, p BF_param) string {
mut s := ""
mut s := ''
mut res := strings.new_builder(20)
mut sign_len_diff := 0
if p.pad_ch == `0` {
@ -655,12 +701,12 @@ pub fn format_dec_old(d u64, p BF_param) string {
} else {
if p.positive {
if p.sign_flag {
s = "+" + d.str()
s = '+' + d.str()
} else {
s = d.str()
}
} else {
s = "-" + d.str()
s = '-' + d.str()
}
}
dif := p.len0 - s.len + sign_len_diff