mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
strconv: vfmt everything
This commit is contained in:
parent
5dff8dc097
commit
de384f1cc8
@ -43,7 +43,6 @@ const (
|
|||||||
'vlib/',
|
'vlib/',
|
||||||
]
|
]
|
||||||
vfmt_known_failing_exceptions = arrays.merge(verify_known_failing_exceptions, [
|
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/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/regex/regex_test.v' /* contains meaningfull formatting of the test case data */,
|
||||||
'vlib/readline/readline_test.v' /* vfmt eats `{ Readline }` from `import readline { Readline }` */,
|
'vlib/readline/readline_test.v' /* vfmt eats `{ Readline }` from `import readline { Readline }` */,
|
||||||
|
@ -414,7 +414,6 @@ Public functions
|
|||||||
|
|
||||||
// atof64 return a f64 from a string doing a parsing operation
|
// atof64 return a f64 from a string doing a parsing operation
|
||||||
pub fn atof64(s string) f64 {
|
pub fn atof64(s string) f64 {
|
||||||
|
|
||||||
mut pn := PrepNumber{}
|
mut pn := PrepNumber{}
|
||||||
mut res_parsing := 0
|
mut res_parsing := 0
|
||||||
mut res := Float64u{}
|
mut res := Float64u{}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import strconv
|
import strconv
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
*
|
*
|
||||||
* String to float Test
|
* String to float Test
|
||||||
@ -18,7 +19,7 @@ fn test_atof() {
|
|||||||
-0.004,
|
-0.004,
|
||||||
0.0,
|
0.0,
|
||||||
-0.0,
|
-0.0,
|
||||||
31234567890123
|
31234567890123,
|
||||||
]
|
]
|
||||||
|
|
||||||
// strings
|
// strings
|
||||||
@ -33,28 +34,27 @@ fn test_atof() {
|
|||||||
]
|
]
|
||||||
|
|
||||||
// check conversion case 1 string <=> string
|
// check conversion case 1 string <=> string
|
||||||
for c,x in src_num {
|
for c, x in src_num {
|
||||||
// slow atof
|
// slow atof
|
||||||
assert strconv.atof64(src_num_str[c]).strlong() == x.strlong()
|
assert strconv.atof64(src_num_str[c]).strlong() == x.strlong()
|
||||||
|
|
||||||
|
|
||||||
// quick atof
|
// quick atof
|
||||||
mut s1 := (strconv.atof_quick(src_num_str[c]).str())
|
mut s1 := (strconv.atof_quick(src_num_str[c]).str())
|
||||||
mut s2 := (x.str())
|
mut s2 := (x.str())
|
||||||
delta := s1.f64() - s2.f64()
|
delta := s1.f64() - s2.f64()
|
||||||
//println("$s1 $s2 $delta")
|
// println("$s1 $s2 $delta")
|
||||||
assert delta < f64(1e-16)
|
assert delta < f64(1e-16)
|
||||||
|
|
||||||
// test C.atof
|
// test C.atof
|
||||||
n1 := x.strsci(18)
|
n1 := x.strsci(18)
|
||||||
n2 := f64(C.atof(&char(src_num_str[c].str))).strsci(18)
|
n2 := f64(C.atof(&char(src_num_str[c].str))).strsci(18)
|
||||||
//println("$n1 $n2")
|
// println("$n1 $n2")
|
||||||
assert n1 == n2
|
assert n1 == n2
|
||||||
}
|
}
|
||||||
|
|
||||||
// check conversion case 2 string <==> f64
|
// check conversion case 2 string <==> f64
|
||||||
// we don't test atof_quick beacuse we already know the rounding error
|
// we don't test atof_quick beacuse we already know the rounding error
|
||||||
for c,x in src_num_str {
|
for c, x in src_num_str {
|
||||||
b := src_num[c].strlong()
|
b := src_num[c].strlong()
|
||||||
a1 := strconv.atof64(x).strlong()
|
a1 := strconv.atof64(x).strlong()
|
||||||
assert a1 == b
|
assert a1 == b
|
||||||
@ -62,14 +62,14 @@ fn test_atof() {
|
|||||||
|
|
||||||
// special cases
|
// special cases
|
||||||
mut f1 := f64(0.0)
|
mut f1 := f64(0.0)
|
||||||
mut ptr := unsafe {&u64(&f1)}
|
mut ptr := unsafe { &u64(&f1) }
|
||||||
ptr = unsafe {&u64(&f1)}
|
ptr = unsafe { &u64(&f1) }
|
||||||
|
|
||||||
// double_plus_zero
|
// double_plus_zero
|
||||||
f1=0.0
|
f1 = 0.0
|
||||||
assert *ptr == u64(0x0000000000000000)
|
assert *ptr == u64(0x0000000000000000)
|
||||||
// double_minus_zero
|
// double_minus_zero
|
||||||
f1=-0.0
|
f1 = -0.0
|
||||||
assert *ptr == u64(0x8000000000000000)
|
assert *ptr == u64(0x8000000000000000)
|
||||||
println("DONE!")
|
println('DONE!')
|
||||||
}
|
}
|
||||||
|
File diff suppressed because one or more lines are too long
@ -69,15 +69,15 @@ pub fn common_parse_uint2(s string, _base int, _bit_size int) (u64, int) {
|
|||||||
return u64(0), -1
|
return u64(0), -1
|
||||||
}
|
}
|
||||||
if bit_size == 0 {
|
if bit_size == 0 {
|
||||||
bit_size = int_size
|
bit_size = strconv.int_size
|
||||||
} else if bit_size < 0 || bit_size > 64 {
|
} else if bit_size < 0 || bit_size > 64 {
|
||||||
// return error('parse_uint: bitsize error $s - $bit_size')
|
// return error('parse_uint: bitsize error $s - $bit_size')
|
||||||
return u64(0), -2
|
return u64(0), -2
|
||||||
}
|
}
|
||||||
// Cutoff is the smallest number such that cutoff*base > maxUint64.
|
// Cutoff is the smallest number such that cutoff*base > maxUint64.
|
||||||
// Use compile-time constants for common cases.
|
// Use compile-time constants for common cases.
|
||||||
cutoff := max_u64 / u64(base) + u64(1)
|
cutoff := strconv.max_u64 / u64(base) + u64(1)
|
||||||
max_val := if bit_size == 64 { max_u64 } else { (u64(1) << u64(bit_size)) - u64(1) }
|
max_val := if bit_size == 64 { strconv.max_u64 } else { (u64(1) << u64(bit_size)) - u64(1) }
|
||||||
mut n := u64(0)
|
mut n := u64(0)
|
||||||
for i in start_index .. s.len {
|
for i in start_index .. s.len {
|
||||||
c := s[i]
|
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)
|
return i64(0)
|
||||||
}
|
}
|
||||||
if bit_size == 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)?
|
// TODO: check should u64(bit_size-1) be size of int (32)?
|
||||||
cutoff := u64(1) << u64(bit_size - 1)
|
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 error('parse_int: range error $s0')
|
||||||
return -i64(cutoff)
|
return -i64(cutoff)
|
||||||
}
|
}
|
||||||
return if neg {
|
return if neg { -i64(un) } else { i64(un) }
|
||||||
-i64(un)
|
|
||||||
} else {
|
|
||||||
i64(un)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse_int interprets a string s in the given base (0, 2 to 36) and
|
// 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 == '' {
|
if s == '' {
|
||||||
return error('strconv.atoi: parsing "$s": invalid syntax ')
|
return error('strconv.atoi: parsing "$s": invalid syntax ')
|
||||||
}
|
}
|
||||||
if (int_size == 32 && (0 < s.len &&
|
if (strconv.int_size == 32 && (0 < s.len && s.len < 10))
|
||||||
s.len < 10)) ||
|
|| (strconv.int_size == 64 && (0 < s.len && s.len < 19)) {
|
||||||
(int_size == 64 && (0 < s.len && s.len < 19)) {
|
|
||||||
// Fast path for small integers that fit int type.
|
// Fast path for small integers that fit int type.
|
||||||
mut start_idx := 0
|
mut start_idx := 0
|
||||||
if s[0] == `-` || s[0] == `+` {
|
if s[0] == `-` || s[0] == `+` {
|
||||||
@ -205,11 +200,7 @@ pub fn atoi(s string) ?int {
|
|||||||
}
|
}
|
||||||
n = n * 10 + int(ch)
|
n = n * 10 + int(ch)
|
||||||
}
|
}
|
||||||
return if s[0] == `-` {
|
return if s[0] == `-` { -n } else { n }
|
||||||
-n
|
|
||||||
} else {
|
|
||||||
n
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Slow path for invalid, big, or underscored integers.
|
// Slow path for invalid, big, or underscored integers.
|
||||||
int64 := parse_int(s, 10, 0)
|
int64 := parse_int(s, 10, 0)
|
||||||
@ -233,8 +224,8 @@ fn underscore_ok(s string) bool {
|
|||||||
}
|
}
|
||||||
// Optional base prefix.
|
// Optional base prefix.
|
||||||
mut hex := false
|
mut hex := false
|
||||||
if s.len - i >= 2 && s[i] == `0` &&
|
if s.len - i >= 2 && s[i] == `0` && (byte_to_lower(s[i + 1]) == `b`
|
||||||
(byte_to_lower(s[i + 1]) == `b` || byte_to_lower(s[i + 1]) == `o` || byte_to_lower(s[i + 1]) == `x`) {
|
|| 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"
|
saw = `0` // base prefix counts as a digit for "underscore as digit separator"
|
||||||
hex = byte_to_lower(s[i + 1]) == `x`
|
hex = byte_to_lower(s[i + 1]) == `x`
|
||||||
i += 2
|
i += 2
|
||||||
@ -242,8 +233,8 @@ fn underscore_ok(s string) bool {
|
|||||||
// Number proper.
|
// Number proper.
|
||||||
for ; i < s.len; i++ {
|
for ; i < s.len; i++ {
|
||||||
// Digits are always okay.
|
// Digits are always okay.
|
||||||
if (`0` <= s[i] && s[i] <= `9`) ||
|
if (`0` <= s[i] && s[i] <= `9`) || (hex && `a` <= byte_to_lower(s[i])
|
||||||
(hex && `a` <= byte_to_lower(s[i]) && byte_to_lower(s[i]) <= `f`) {
|
&& byte_to_lower(s[i]) <= `f`) {
|
||||||
saw = `0`
|
saw = `0`
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
module strconv
|
module strconv
|
||||||
|
|
||||||
/*=============================================================================
|
/*=============================================================================
|
||||||
|
|
||||||
f32 to string
|
f32 to string
|
||||||
@ -20,7 +21,7 @@ https://github.com/cespare/ryu/tree/ba56a33f39e3bbbfa409095d0f9ae168a595feea
|
|||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
// pow of ten table used by n_digit reduction
|
// pow of ten table used by n_digit reduction
|
||||||
const(
|
const (
|
||||||
ten_pow_table_32 = [
|
ten_pow_table_32 = [
|
||||||
u32(1),
|
u32(1),
|
||||||
u32(10),
|
u32(10),
|
||||||
@ -40,34 +41,34 @@ const(
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Conversion Functions
|
// Conversion Functions
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
const(
|
const (
|
||||||
mantbits32 = u32(23)
|
mantbits32 = u32(23)
|
||||||
expbits32 = u32(8)
|
expbits32 = u32(8)
|
||||||
bias32 = 127 // f32 exponent bias
|
bias32 = 127 // f32 exponent bias
|
||||||
maxexp32 = 255
|
maxexp32 = 255
|
||||||
)
|
)
|
||||||
|
|
||||||
// max 46 char
|
// max 46 char
|
||||||
// -3.40282346638528859811704183484516925440e+38
|
// -3.40282346638528859811704183484516925440e+38
|
||||||
[direct_array_access]
|
[direct_array_access]
|
||||||
pub fn (d Dec32) get_string_32(neg bool, i_n_digit int, i_pad_digit int) string {
|
pub fn (d Dec32) get_string_32(neg bool, i_n_digit int, i_pad_digit int) string {
|
||||||
n_digit := i_n_digit + 1
|
n_digit := i_n_digit + 1
|
||||||
pad_digit := i_pad_digit + 1
|
pad_digit := i_pad_digit + 1
|
||||||
mut out := d.m
|
mut out := d.m
|
||||||
//mut out_len := decimal_len_32(out)
|
// mut out_len := decimal_len_32(out)
|
||||||
mut out_len := dec_digits(out)
|
mut out_len := dec_digits(out)
|
||||||
out_len_original := out_len
|
out_len_original := out_len
|
||||||
|
|
||||||
mut fw_zeros := 0
|
mut fw_zeros := 0
|
||||||
if pad_digit > out_len {
|
if pad_digit > out_len {
|
||||||
fw_zeros = 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 buf := []byte{len: int(out_len + 5 + 1 + 1)} // sign + mant_len + . + e + e_sign + exp_len(2) + \0}
|
||||||
mut i := 0
|
mut i := 0
|
||||||
|
|
||||||
if neg {
|
if neg {
|
||||||
buf[i]=`-`
|
buf[i] = `-`
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,16 +78,16 @@ pub fn (d Dec32) get_string_32(neg bool, i_n_digit int, i_pad_digit int) string
|
|||||||
}
|
}
|
||||||
|
|
||||||
if n_digit < out_len {
|
if n_digit < out_len {
|
||||||
//println("orig: ${out_len_original}")
|
// println("orig: ${out_len_original}")
|
||||||
out += ten_pow_table_32[out_len - n_digit - 1] * 5 // round to up
|
out += strconv.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]
|
||||||
out_len = n_digit
|
out_len = n_digit
|
||||||
}
|
}
|
||||||
|
|
||||||
y := i + out_len
|
y := i + out_len
|
||||||
mut x := 0
|
mut x := 0
|
||||||
for x < (out_len-disp-1) {
|
for x < (out_len - disp - 1) {
|
||||||
buf[y - x] = `0` + byte(out%10)
|
buf[y - x] = `0` + byte(out % 10)
|
||||||
out /= 10
|
out /= 10
|
||||||
i++
|
i++
|
||||||
x++
|
x++
|
||||||
@ -95,8 +96,8 @@ pub fn (d Dec32) get_string_32(neg bool, i_n_digit int, i_pad_digit int) string
|
|||||||
// no decimal digits needed, end here
|
// no decimal digits needed, end here
|
||||||
if i_n_digit == 0 {
|
if i_n_digit == 0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
buf[i]=0
|
buf[i] = 0
|
||||||
return tos(byteptr(&buf[0]), i)
|
return tos(&byte(&buf[0]), i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,8 +107,8 @@ pub fn (d Dec32) get_string_32(neg bool, i_n_digit int, i_pad_digit int) string
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
if y-x >= 0 {
|
if y - x >= 0 {
|
||||||
buf[y - x] = `0` + byte(out%10)
|
buf[y - x] = `0` + byte(out % 10)
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,42 +118,42 @@ pub fn (d Dec32) get_string_32(neg bool, i_n_digit int, i_pad_digit int) string
|
|||||||
fw_zeros--
|
fw_zeros--
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[i]=`e`
|
buf[i] = `e`
|
||||||
i++
|
i++
|
||||||
|
|
||||||
mut exp := d.e + out_len_original - 1
|
mut exp := d.e + out_len_original - 1
|
||||||
if exp < 0 {
|
if exp < 0 {
|
||||||
buf[i]=`-`
|
buf[i] = `-`
|
||||||
i++
|
i++
|
||||||
exp = -exp
|
exp = -exp
|
||||||
} else {
|
} else {
|
||||||
buf[i]=`+`
|
buf[i] = `+`
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always print two digits to match strconv's formatting.
|
// Always print two digits to match strconv's formatting.
|
||||||
d1 := exp % 10
|
d1 := exp % 10
|
||||||
d0 := exp / 10
|
d0 := exp / 10
|
||||||
buf[i]=`0` + byte(d0)
|
buf[i] = `0` + byte(d0)
|
||||||
i++
|
i++
|
||||||
buf[i]=`0` + byte(d1)
|
buf[i] = `0` + byte(d1)
|
||||||
i++
|
i++
|
||||||
buf[i]=0
|
buf[i] = 0
|
||||||
|
|
||||||
return unsafe {
|
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) {
|
fn f32_to_decimal_exact_int(i_mant u32, exp u32) (Dec32, bool) {
|
||||||
mut d := Dec32{}
|
mut d := Dec32{}
|
||||||
e := exp - bias32
|
e := exp - strconv.bias32
|
||||||
if e > mantbits32 {
|
if e > strconv.mantbits32 {
|
||||||
return d, false
|
return d, false
|
||||||
}
|
}
|
||||||
shift := mantbits32 - e
|
shift := strconv.mantbits32 - e
|
||||||
mant := i_mant | 0x0080_0000 // implicit 1
|
mant := i_mant | 0x0080_0000 // implicit 1
|
||||||
//mant := i_mant | (1 << mantbits32) // implicit 1
|
// mant := i_mant | (1 << mantbits32) // implicit 1
|
||||||
d.m = mant >> shift
|
d.m = mant >> shift
|
||||||
if (d.m << shift) != mant {
|
if (d.m << shift) != mant {
|
||||||
return d, false
|
return d, false
|
||||||
@ -170,28 +171,28 @@ fn f32_to_decimal(mant u32, exp u32) Dec32 {
|
|||||||
if exp == 0 {
|
if exp == 0 {
|
||||||
// We subtract 2 so that the bounds computation has
|
// We subtract 2 so that the bounds computation has
|
||||||
// 2 additional bits.
|
// 2 additional bits.
|
||||||
e2 = 1 - bias32 - int(mantbits32) - 2
|
e2 = 1 - strconv.bias32 - int(strconv.mantbits32) - 2
|
||||||
m2 = mant
|
m2 = mant
|
||||||
} else {
|
} else {
|
||||||
e2 = int(exp) - bias32 - int(mantbits32) - 2
|
e2 = int(exp) - strconv.bias32 - int(strconv.mantbits32) - 2
|
||||||
m2 = (u32(1) << mantbits32) | mant
|
m2 = (u32(1) << strconv.mantbits32) | mant
|
||||||
}
|
}
|
||||||
even := (m2 & 1) == 0
|
even := (m2 & 1) == 0
|
||||||
accept_bounds := even
|
accept_bounds := even
|
||||||
|
|
||||||
// Step 2: Determine the interval of valid decimal representations.
|
// Step 2: Determine the interval of valid decimal representations.
|
||||||
mv := u32(4 * m2)
|
mv := u32(4 * m2)
|
||||||
mp := u32(4 * m2 + 2)
|
mp := u32(4 * m2 + 2)
|
||||||
mm_shift := bool_to_u32(mant != 0 || exp <= 1)
|
mm_shift := bool_to_u32(mant != 0 || exp <= 1)
|
||||||
mm := u32(4 * m2 - 1 - mm_shift)
|
mm := u32(4 * m2 - 1 - mm_shift)
|
||||||
|
|
||||||
mut vr := u32(0)
|
mut vr := u32(0)
|
||||||
mut vp := u32(0)
|
mut vp := u32(0)
|
||||||
mut vm := u32(0)
|
mut vm := u32(0)
|
||||||
mut e10 := 0
|
mut e10 := 0
|
||||||
mut vm_is_trailing_zeros := false
|
mut vm_is_trailing_zeros := false
|
||||||
mut vr_is_trailing_zeros := false
|
mut vr_is_trailing_zeros := false
|
||||||
mut last_removed_digit := byte(0)
|
mut last_removed_digit := byte(0)
|
||||||
|
|
||||||
if e2 >= 0 {
|
if e2 >= 0 {
|
||||||
q := log10_pow2(e2)
|
q := log10_pow2(e2)
|
||||||
@ -202,7 +203,7 @@ fn f32_to_decimal(mant u32, exp u32) Dec32 {
|
|||||||
vr = mul_pow5_invdiv_pow2(mv, q, i)
|
vr = mul_pow5_invdiv_pow2(mv, q, i)
|
||||||
vp = mul_pow5_invdiv_pow2(mp, q, i)
|
vp = mul_pow5_invdiv_pow2(mp, q, i)
|
||||||
vm = mul_pow5_invdiv_pow2(mm, q, i)
|
vm = mul_pow5_invdiv_pow2(mm, q, i)
|
||||||
if q != 0 && (vp-1)/10 <= vm/10 {
|
if q != 0 && (vp - 1) / 10 <= vm / 10 {
|
||||||
// We need to know one removed digit even if we are not
|
// We need to know one removed digit even if we are not
|
||||||
// going to loop below. We could use q = X - 1 above,
|
// going to loop below. We could use q = X - 1 above,
|
||||||
// except that would require 33 bits for the result, and
|
// except that would require 33 bits for the result, and
|
||||||
@ -232,7 +233,7 @@ fn f32_to_decimal(mant u32, exp u32) Dec32 {
|
|||||||
vr = mul_pow5_div_pow2(mv, u32(i), j)
|
vr = mul_pow5_div_pow2(mv, u32(i), j)
|
||||||
vp = mul_pow5_div_pow2(mp, u32(i), j)
|
vp = mul_pow5_div_pow2(mp, u32(i), j)
|
||||||
vm = mul_pow5_div_pow2(mm, u32(i), j)
|
vm = mul_pow5_div_pow2(mm, u32(i), j)
|
||||||
if q != 0 && ((vp-1)/10) <= vm/10 {
|
if q != 0 && ((vp - 1) / 10) <= vm / 10 {
|
||||||
j = int(q) - 1 - (pow5_bits(i + 1) - pow5_num_bits_32)
|
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)
|
last_removed_digit = byte(mul_pow5_div_pow2(mv, u32(i + 1), j) % 10)
|
||||||
}
|
}
|
||||||
@ -258,10 +259,10 @@ fn f32_to_decimal(mant u32, exp u32) Dec32 {
|
|||||||
// Step 4: Find the shortest decimal representation
|
// Step 4: Find the shortest decimal representation
|
||||||
// in the interval of valid representations.
|
// in the interval of valid representations.
|
||||||
mut removed := 0
|
mut removed := 0
|
||||||
mut out := u32(0)
|
mut out := u32(0)
|
||||||
if vm_is_trailing_zeros || vr_is_trailing_zeros {
|
if vm_is_trailing_zeros || vr_is_trailing_zeros {
|
||||||
// General case, which happens rarely (~4.0%).
|
// General case, which happens rarely (~4.0%).
|
||||||
for vp/10 > vm/10 {
|
for vp / 10 > vm / 10 {
|
||||||
vm_is_trailing_zeros = vm_is_trailing_zeros && (vm % 10) == 0
|
vm_is_trailing_zeros = vm_is_trailing_zeros && (vm % 10) == 0
|
||||||
vr_is_trailing_zeros = vr_is_trailing_zeros && (last_removed_digit == 0)
|
vr_is_trailing_zeros = vr_is_trailing_zeros && (last_removed_digit == 0)
|
||||||
last_removed_digit = byte(vr % 10)
|
last_removed_digit = byte(vr % 10)
|
||||||
@ -271,7 +272,7 @@ fn f32_to_decimal(mant u32, exp u32) Dec32 {
|
|||||||
removed++
|
removed++
|
||||||
}
|
}
|
||||||
if vm_is_trailing_zeros {
|
if vm_is_trailing_zeros {
|
||||||
for vm%10 == 0 {
|
for vm % 10 == 0 {
|
||||||
vr_is_trailing_zeros = vr_is_trailing_zeros && (last_removed_digit == 0)
|
vr_is_trailing_zeros = vr_is_trailing_zeros && (last_removed_digit == 0)
|
||||||
last_removed_digit = byte(vr % 10)
|
last_removed_digit = byte(vr % 10)
|
||||||
vr /= 10
|
vr /= 10
|
||||||
@ -294,7 +295,7 @@ fn f32_to_decimal(mant u32, exp u32) Dec32 {
|
|||||||
// Specialized for the common case (~96.0%). Percentages below
|
// Specialized for the common case (~96.0%). Percentages below
|
||||||
// are relative to this. Loop iterations below (approximately):
|
// 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%
|
// 0: 13.6%, 1: 70.7%, 2: 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01%
|
||||||
for vp/10 > vm/10 {
|
for vp / 10 > vm / 10 {
|
||||||
last_removed_digit = byte(vr % 10)
|
last_removed_digit = byte(vr % 10)
|
||||||
vr /= 10
|
vr /= 10
|
||||||
vp /= 10
|
vp /= 10
|
||||||
@ -306,7 +307,10 @@ fn f32_to_decimal(mant u32, exp u32) Dec32 {
|
|||||||
out = vr + bool_to_u32(vr == vm || last_removed_digit >= 5)
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
@ -317,52 +321,52 @@ fn f32_to_decimal(mant u32, exp u32) Dec32 {
|
|||||||
pub fn f32_to_str(f f32, n_digit int) string {
|
pub fn f32_to_str(f f32, n_digit int) string {
|
||||||
mut u1 := Uf32{}
|
mut u1 := Uf32{}
|
||||||
u1.f = f
|
u1.f = f
|
||||||
u := unsafe {u1.u}
|
u := unsafe { u1.u }
|
||||||
|
|
||||||
neg := (u >> (mantbits32 + expbits32)) != 0
|
neg := (u >> (strconv.mantbits32 + strconv.expbits32)) != 0
|
||||||
mant := u & ((u32(1) << mantbits32) - u32(1))
|
mant := u & ((u32(1) << strconv.mantbits32) - u32(1))
|
||||||
exp := (u >> mantbits32) & ((u32(1) << expbits32) - u32(1))
|
exp := (u >> strconv.mantbits32) & ((u32(1) << strconv.expbits32) - u32(1))
|
||||||
|
|
||||||
//println("${neg} ${mant} e ${exp-bias32}")
|
// println("${neg} ${mant} e ${exp-bias32}")
|
||||||
|
|
||||||
// Exit early for easy cases.
|
// 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)
|
return get_string_special(neg, exp == 0, mant == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
mut d, ok := f32_to_decimal_exact_int(mant, exp)
|
mut d, ok := f32_to_decimal_exact_int(mant, exp)
|
||||||
if !ok {
|
if !ok {
|
||||||
//println("with exp form")
|
// println("with exp form")
|
||||||
d = f32_to_decimal(mant, exp)
|
d = f32_to_decimal(mant, exp)
|
||||||
}
|
}
|
||||||
|
|
||||||
//println("${d.m} ${d.e}")
|
// println("${d.m} ${d.e}")
|
||||||
return d.get_string_32(neg, n_digit,0)
|
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
|
// 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 {
|
pub fn f32_to_str_pad(f f32, n_digit int) string {
|
||||||
mut u1 := Uf32{}
|
mut u1 := Uf32{}
|
||||||
u1.f = f
|
u1.f = f
|
||||||
u := unsafe {u1.u}
|
u := unsafe { u1.u }
|
||||||
|
|
||||||
neg := (u >> (mantbits32 + expbits32)) != 0
|
neg := (u >> (strconv.mantbits32 + strconv.expbits32)) != 0
|
||||||
mant := u & ((u32(1) << mantbits32) - u32(1))
|
mant := u & ((u32(1) << strconv.mantbits32) - u32(1))
|
||||||
exp := (u >> mantbits32) & ((u32(1) << expbits32) - u32(1))
|
exp := (u >> strconv.mantbits32) & ((u32(1) << strconv.expbits32) - u32(1))
|
||||||
|
|
||||||
//println("${neg} ${mant} e ${exp-bias32}")
|
// println("${neg} ${mant} e ${exp-bias32}")
|
||||||
|
|
||||||
// Exit early for easy cases.
|
// 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)
|
return get_string_special(neg, exp == 0, mant == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
mut d, ok := f32_to_decimal_exact_int(mant, exp)
|
mut d, ok := f32_to_decimal_exact_int(mant, exp)
|
||||||
if !ok {
|
if !ok {
|
||||||
//println("with exp form")
|
// println("with exp form")
|
||||||
d = f32_to_decimal(mant, exp)
|
d = f32_to_decimal(mant, exp)
|
||||||
}
|
}
|
||||||
|
|
||||||
//println("${d.m} ${d.e}")
|
// println("${d.m} ${d.e}")
|
||||||
return d.get_string_32(neg, n_digit, n_digit)
|
return d.get_string_32(neg, n_digit, n_digit)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
module strconv
|
module strconv
|
||||||
|
|
||||||
/*=============================================================================
|
/*=============================================================================
|
||||||
|
|
||||||
f64 to string
|
f64 to string
|
||||||
@ -20,7 +21,7 @@ https://github.com/cespare/ryu/tree/ba56a33f39e3bbbfa409095d0f9ae168a595feea
|
|||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
// pow of ten table used by n_digit reduction
|
// pow of ten table used by n_digit reduction
|
||||||
const(
|
const (
|
||||||
ten_pow_table_64 = [
|
ten_pow_table_64 = [
|
||||||
u64(1),
|
u64(1),
|
||||||
u64(10),
|
u64(10),
|
||||||
@ -48,21 +49,21 @@ const(
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Conversion Functions
|
// Conversion Functions
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
const(
|
const (
|
||||||
mantbits64 = u32(52)
|
mantbits64 = u32(52)
|
||||||
expbits64 = u32(11)
|
expbits64 = u32(11)
|
||||||
bias64 = 1023 // f64 exponent bias
|
bias64 = 1023 // f64 exponent bias
|
||||||
maxexp64 = 2047
|
maxexp64 = 2047
|
||||||
)
|
)
|
||||||
|
|
||||||
[direct_array_access]
|
[direct_array_access]
|
||||||
fn (d Dec64) get_string_64(neg bool, i_n_digit int, i_pad_digit int) string {
|
fn (d Dec64) get_string_64(neg bool, i_n_digit int, i_pad_digit int) string {
|
||||||
mut n_digit := i_n_digit + 1
|
mut n_digit := i_n_digit + 1
|
||||||
pad_digit := i_pad_digit + 1
|
pad_digit := i_pad_digit + 1
|
||||||
mut out := d.m
|
mut out := d.m
|
||||||
mut d_exp := d.e
|
mut d_exp := d.e
|
||||||
// mut out_len := decimal_len_64(out)
|
// mut out_len := decimal_len_64(out)
|
||||||
mut out_len := dec_digits(out)
|
mut out_len := dec_digits(out)
|
||||||
out_len_original := out_len
|
out_len_original := out_len
|
||||||
|
|
||||||
mut fw_zeros := 0
|
mut fw_zeros := 0
|
||||||
@ -70,7 +71,7 @@ fn (d Dec64) get_string_64(neg bool, i_n_digit int, i_pad_digit int) string {
|
|||||||
fw_zeros = 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 buf := []byte{len: (out_len + 6 + 1 + 1 + fw_zeros)} // sign + mant_len + . + e + e_sign + exp_len(2) + \0}
|
||||||
mut i := 0
|
mut i := 0
|
||||||
|
|
||||||
if neg {
|
if neg {
|
||||||
@ -85,19 +86,19 @@ fn (d Dec64) get_string_64(neg bool, i_n_digit int, i_pad_digit int) string {
|
|||||||
|
|
||||||
// rounding last used digit
|
// rounding last used digit
|
||||||
if n_digit < out_len {
|
if n_digit < out_len {
|
||||||
//println("out:[$out]")
|
// println("out:[$out]")
|
||||||
out += ten_pow_table_64[out_len - n_digit - 1] * 5 // round to up
|
out += strconv.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]
|
||||||
//println("out1:[$out] ${d.m / 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++
|
d_exp++
|
||||||
n_digit++
|
n_digit++
|
||||||
}
|
}
|
||||||
|
|
||||||
//println("cmp: ${d.m/ten_pow_table_64[out_len - n_digit ]} ${out/ten_pow_table_64[out_len - 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
|
out_len = n_digit
|
||||||
//println("orig: ${out_len_original} new len: ${out_len} out:[$out]")
|
// println("orig: ${out_len_original} new len: ${out_len} out:[$out]")
|
||||||
}
|
}
|
||||||
|
|
||||||
y := i + out_len
|
y := i + out_len
|
||||||
@ -112,8 +113,8 @@ fn (d Dec64) get_string_64(neg bool, i_n_digit int, i_pad_digit int) string {
|
|||||||
// no decimal digits needed, end here
|
// no decimal digits needed, end here
|
||||||
if i_n_digit == 0 {
|
if i_n_digit == 0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
buf[i]=0
|
buf[i] = 0
|
||||||
return tos(byteptr(&buf[0]), i)
|
return tos(&byte(&buf[0]), i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +124,7 @@ fn (d Dec64) get_string_64(neg bool, i_n_digit int, i_pad_digit int) string {
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
if y-x >= 0 {
|
if y - x >= 0 {
|
||||||
buf[y - x] = `0` + byte(out % 10)
|
buf[y - x] = `0` + byte(out % 10)
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
@ -134,16 +135,16 @@ fn (d Dec64) get_string_64(neg bool, i_n_digit int, i_pad_digit int) string {
|
|||||||
fw_zeros--
|
fw_zeros--
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[i]=`e`
|
buf[i] = `e`
|
||||||
i++
|
i++
|
||||||
|
|
||||||
mut exp := d_exp + out_len_original - 1
|
mut exp := d_exp + out_len_original - 1
|
||||||
if exp < 0 {
|
if exp < 0 {
|
||||||
buf[i]=`-`
|
buf[i] = `-`
|
||||||
i++
|
i++
|
||||||
exp = -exp
|
exp = -exp
|
||||||
} else {
|
} else {
|
||||||
buf[i]=`+`
|
buf[i] = `+`
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,29 +154,29 @@ fn (d Dec64) get_string_64(neg bool, i_n_digit int, i_pad_digit int) string {
|
|||||||
d1 := exp % 10
|
d1 := exp % 10
|
||||||
d0 := exp / 10
|
d0 := exp / 10
|
||||||
if d0 > 0 {
|
if d0 > 0 {
|
||||||
buf[i]=`0` + byte(d0)
|
buf[i] = `0` + byte(d0)
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
buf[i]=`0` + byte(d1)
|
buf[i] = `0` + byte(d1)
|
||||||
i++
|
i++
|
||||||
buf[i]=`0` + byte(d2)
|
buf[i] = `0` + byte(d2)
|
||||||
i++
|
i++
|
||||||
buf[i]=0
|
buf[i] = 0
|
||||||
|
|
||||||
return unsafe {
|
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) {
|
fn f64_to_decimal_exact_int(i_mant u64, exp u64) (Dec64, bool) {
|
||||||
mut d := Dec64{}
|
mut d := Dec64{}
|
||||||
e := exp - bias64
|
e := exp - strconv.bias64
|
||||||
if e > mantbits64 {
|
if e > strconv.mantbits64 {
|
||||||
return d, false
|
return d, false
|
||||||
}
|
}
|
||||||
shift := mantbits64 - e
|
shift := strconv.mantbits64 - e
|
||||||
mant := i_mant | u64(0x0010_0000_0000_0000) // implicit 1
|
mant := i_mant | u64(0x0010_0000_0000_0000) // implicit 1
|
||||||
//mant := i_mant | (1 << mantbits64) // implicit 1
|
// mant := i_mant | (1 << mantbits64) // implicit 1
|
||||||
d.m = mant >> shift
|
d.m = mant >> shift
|
||||||
if (d.m << shift) != mant {
|
if (d.m << shift) != mant {
|
||||||
return d, false
|
return d, false
|
||||||
@ -194,24 +195,24 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 {
|
|||||||
if exp == 0 {
|
if exp == 0 {
|
||||||
// We subtract 2 so that the bounds computation has
|
// We subtract 2 so that the bounds computation has
|
||||||
// 2 additional bits.
|
// 2 additional bits.
|
||||||
e2 = 1 - bias64 - int(mantbits64) - 2
|
e2 = 1 - strconv.bias64 - int(strconv.mantbits64) - 2
|
||||||
m2 = mant
|
m2 = mant
|
||||||
} else {
|
} else {
|
||||||
e2 = int(exp) - bias64 - int(mantbits64) - 2
|
e2 = int(exp) - strconv.bias64 - int(strconv.mantbits64) - 2
|
||||||
m2 = (u64(1) << mantbits64) | mant
|
m2 = (u64(1) << strconv.mantbits64) | mant
|
||||||
}
|
}
|
||||||
even := (m2 & 1) == 0
|
even := (m2 & 1) == 0
|
||||||
accept_bounds := even
|
accept_bounds := even
|
||||||
|
|
||||||
// Step 2: Determine the interval of valid decimal representations.
|
// Step 2: Determine the interval of valid decimal representations.
|
||||||
mv := u64(4 * m2)
|
mv := u64(4 * m2)
|
||||||
mm_shift := bool_to_u64(mant != 0 || exp <= 1)
|
mm_shift := bool_to_u64(mant != 0 || exp <= 1)
|
||||||
|
|
||||||
// Step 3: Convert to a decimal power base uing 128-bit arithmetic.
|
// Step 3: Convert to a decimal power base uing 128-bit arithmetic.
|
||||||
mut vr := u64(0)
|
mut vr := u64(0)
|
||||||
mut vp := u64(0)
|
mut vp := u64(0)
|
||||||
mut vm := u64(0)
|
mut vm := u64(0)
|
||||||
mut e10 := 0
|
mut e10 := 0
|
||||||
mut vm_is_trailing_zeros := false
|
mut vm_is_trailing_zeros := false
|
||||||
mut vr_is_trailing_zeros := false
|
mut vr_is_trailing_zeros := false
|
||||||
|
|
||||||
@ -223,8 +224,8 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 {
|
|||||||
i := -e2 + int(q) + k
|
i := -e2 + int(q) + k
|
||||||
|
|
||||||
mul := pow5_inv_split_64[q]
|
mul := pow5_inv_split_64[q]
|
||||||
vr = mul_shift_64(u64(4) * m2 , mul, i)
|
vr = mul_shift_64(u64(4) * m2, mul, i)
|
||||||
vp = mul_shift_64(u64(4) * m2 + u64(2) , 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)
|
vm = mul_shift_64(u64(4) * m2 - u64(1) - mm_shift, mul, i)
|
||||||
if q <= 21 {
|
if q <= 21 {
|
||||||
// This should use q <= 22, but I think 21 is also safe.
|
// This should use q <= 22, but I think 21 is also safe.
|
||||||
@ -237,7 +238,8 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 {
|
|||||||
// Same as min(e2 + (^mm & 1), pow5Factor64(mm)) >= q
|
// Same as min(e2 + (^mm & 1), pow5Factor64(mm)) >= q
|
||||||
// <=> e2 + (^mm & 1) >= q && pow5Factor64(mm) >= q
|
// <=> e2 + (^mm & 1) >= q && pow5Factor64(mm) >= q
|
||||||
// <=> true && pow5Factor64(mm) >= q, since e2 >= 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) {
|
} else if multiple_of_power_of_five_64(mv + 2, q) {
|
||||||
vp--
|
vp--
|
||||||
}
|
}
|
||||||
@ -250,8 +252,8 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 {
|
|||||||
k := pow5_bits(i) - pow5_num_bits_64
|
k := pow5_bits(i) - pow5_num_bits_64
|
||||||
j := int(q) - k
|
j := int(q) - k
|
||||||
mul := pow5_split_64[i]
|
mul := pow5_split_64[i]
|
||||||
vr = mul_shift_64(u64(4) * m2 , mul, j)
|
vr = mul_shift_64(u64(4) * m2, mul, j)
|
||||||
vp = mul_shift_64(u64(4) * m2 + u64(2) , 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)
|
vm = mul_shift_64(u64(4) * m2 - u64(1) - mm_shift, mul, j)
|
||||||
if q <= 1 {
|
if q <= 1 {
|
||||||
// {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits.
|
// {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits.
|
||||||
@ -276,9 +278,9 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 {
|
|||||||
|
|
||||||
// Step 4: Find the shortest decimal representation
|
// Step 4: Find the shortest decimal representation
|
||||||
// in the interval of valid representations.
|
// in the interval of valid representations.
|
||||||
mut removed := 0
|
mut removed := 0
|
||||||
mut last_removed_digit := byte(0)
|
mut last_removed_digit := byte(0)
|
||||||
mut out := u64(0)
|
mut out := u64(0)
|
||||||
// On average, we remove ~2 digits.
|
// On average, we remove ~2 digits.
|
||||||
if vm_is_trailing_zeros || vr_is_trailing_zeros {
|
if vm_is_trailing_zeros || vr_is_trailing_zeros {
|
||||||
// General case, which happens rarely (~0.7%).
|
// General case, which happens rarely (~0.7%).
|
||||||
@ -355,7 +357,10 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 {
|
|||||||
out = vr + bool_to_u64(vr == vm || round_up)
|
out = vr + bool_to_u64(vr == vm || round_up)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Dec64{m: out, e: e10 + removed}
|
return Dec64{
|
||||||
|
m: out
|
||||||
|
e: e10 + removed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
@ -366,24 +371,24 @@ fn f64_to_decimal(mant u64, exp u64) Dec64 {
|
|||||||
pub fn f64_to_str(f f64, n_digit int) string {
|
pub fn f64_to_str(f f64, n_digit int) string {
|
||||||
mut u1 := Uf64{}
|
mut u1 := Uf64{}
|
||||||
u1.f = f
|
u1.f = f
|
||||||
u := unsafe {u1.u}
|
u := unsafe { u1.u }
|
||||||
|
|
||||||
neg := (u >> (mantbits64 + expbits64)) != 0
|
neg := (u >> (strconv.mantbits64 + strconv.expbits64)) != 0
|
||||||
mant := u & ((u64(1) << mantbits64) - u64(1))
|
mant := u & ((u64(1) << strconv.mantbits64) - u64(1))
|
||||||
exp := (u >> mantbits64) & ((u64(1) << expbits64) - 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}")
|
// println("s:${neg} mant:${mant} exp:${exp} float:${f} byte:${u1.u:016lx}")
|
||||||
|
|
||||||
// Exit early for easy cases.
|
// 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)
|
return get_string_special(neg, exp == 0, mant == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
mut d, ok := f64_to_decimal_exact_int(mant, exp)
|
mut d, ok := f64_to_decimal_exact_int(mant, exp)
|
||||||
if !ok {
|
if !ok {
|
||||||
//println("to_decimal")
|
// println("to_decimal")
|
||||||
d = f64_to_decimal(mant, exp)
|
d = f64_to_decimal(mant, exp)
|
||||||
}
|
}
|
||||||
//println("${d.m} ${d.e}")
|
// println("${d.m} ${d.e}")
|
||||||
return d.get_string_64(neg, n_digit, 0)
|
return d.get_string_64(neg, n_digit, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,23 +396,23 @@ pub fn f64_to_str(f f64, n_digit int) string {
|
|||||||
pub fn f64_to_str_pad(f f64, n_digit int) string {
|
pub fn f64_to_str_pad(f f64, n_digit int) string {
|
||||||
mut u1 := Uf64{}
|
mut u1 := Uf64{}
|
||||||
u1.f = f
|
u1.f = f
|
||||||
u := unsafe {u1.u}
|
u := unsafe { u1.u }
|
||||||
|
|
||||||
neg := (u >> (mantbits64 + expbits64)) != 0
|
neg := (u >> (strconv.mantbits64 + strconv.expbits64)) != 0
|
||||||
mant := u & ((u64(1) << mantbits64) - u64(1))
|
mant := u & ((u64(1) << strconv.mantbits64) - u64(1))
|
||||||
exp := (u >> mantbits64) & ((u64(1) << expbits64) - 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}")
|
// println("s:${neg} mant:${mant} exp:${exp} float:${f} byte:${u1.u:016lx}")
|
||||||
|
|
||||||
// Exit early for easy cases.
|
// 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)
|
return get_string_special(neg, exp == 0, mant == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
mut d, ok := f64_to_decimal_exact_int(mant, exp)
|
mut d, ok := f64_to_decimal_exact_int(mant, exp)
|
||||||
if !ok {
|
if !ok {
|
||||||
//println("to_decimal")
|
// println("to_decimal")
|
||||||
d = f64_to_decimal(mant, exp)
|
d = f64_to_decimal(mant, exp)
|
||||||
}
|
}
|
||||||
//println("DEBUG: ${d.m} ${d.e}")
|
// println("DEBUG: ${d.m} ${d.e}")
|
||||||
return d.get_string_64(neg, n_digit, n_digit)
|
return d.get_string_64(neg, n_digit, n_digit)
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
module strconv
|
module strconv
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
printf/sprintf V implementation
|
printf/sprintf V implementation
|
||||||
|
|
||||||
Copyright (c) 2020 Dario Deledda. All rights reserved.
|
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.
|
that can be found in the LICENSE file.
|
||||||
|
|
||||||
This file contains the printf/sprintf functions
|
This file contains the printf/sprintf functions
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
pub enum Align_text {
|
pub enum Align_text {
|
||||||
@ -21,11 +18,9 @@ pub enum Align_text {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Float conversion utility
|
Float conversion utility
|
||||||
|
|
||||||
*/
|
*/
|
||||||
const(
|
const (
|
||||||
// rounding value
|
// rounding value
|
||||||
dec_round = [
|
dec_round = [
|
||||||
f64(0.5),
|
f64(0.5),
|
||||||
@ -81,19 +76,17 @@ const(
|
|||||||
// max float 1.797693134862315708145274237317043567981e+308
|
// max float 1.797693134862315708145274237317043567981e+308
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Single format functions
|
||||||
Single format functions
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
pub struct BF_param {
|
pub struct BF_param {
|
||||||
pub mut:
|
pub mut:
|
||||||
pad_ch byte = byte(` `) // padding char
|
pad_ch byte = byte(` `) // padding char
|
||||||
len0 int = -1 // default len for whole the number or string
|
len0 int = -1 // default len for whole the number or string
|
||||||
len1 int = 6 // number of decimal digits, if needed
|
len1 int = 6 // number of decimal digits, if needed
|
||||||
positive bool = true // mandatory: the sign of the number passed
|
positive bool = true // mandatory: the sign of the number passed
|
||||||
sign_flag bool // flag for print sign as prefix in padding
|
sign_flag bool // flag for print sign as prefix in padding
|
||||||
allign Align_text = .right // alignment of the string
|
allign Align_text = .right // alignment of the string
|
||||||
rm_tail_zero bool // remove the tail zeros from floats
|
rm_tail_zero bool // remove the tail zeros from floats
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format_str(s string, p BF_param) string {
|
pub fn format_str(s string, p BF_param) string {
|
||||||
@ -106,13 +99,13 @@ pub fn format_str(s string, p BF_param) string {
|
|||||||
}
|
}
|
||||||
mut res := strings.new_builder(s.len + dif)
|
mut res := strings.new_builder(s.len + dif)
|
||||||
if p.allign == .right {
|
if p.allign == .right {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.write_string(s)
|
res.write_string(s)
|
||||||
if p.allign == .left {
|
if p.allign == .left {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ that can be found in the LICENSE file.
|
|||||||
This file contains string interpolation V functions
|
This file contains string interpolation V functions
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
module strconv
|
module strconv
|
||||||
|
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
// strings.Builder version of format_str
|
// strings.Builder version of format_str
|
||||||
@ -19,15 +20,15 @@ pub fn format_str_sb(s string, p BF_param, mut sb strings.Builder) {
|
|||||||
sb.write_string(s)
|
sb.write_string(s)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.allign == .right {
|
if p.allign == .right {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
sb.write_b(p.pad_ch)
|
sb.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb.write_string(s)
|
sb.write_string(s)
|
||||||
if p.allign == .left {
|
if p.allign == .left {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
sb.write_b(p.pad_ch)
|
sb.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,10 +61,10 @@ pub fn format_dec_sb(d u64, p BF_param, mut res strings.Builder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// write the pad chars
|
// write the pad chars
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sign_written {
|
if !sign_written {
|
||||||
// no pad char, write the sign before the number
|
// no pad char, write the sign before the number
|
||||||
@ -103,10 +104,14 @@ pub fn format_dec_sb(d u64, p BF_param, mut res strings.Builder) {
|
|||||||
// calculate the digit_pairs start index
|
// calculate the digit_pairs start index
|
||||||
d_i = (n - (n1 * 100)) << 1
|
d_i = (n - (n1 * 100)) << 1
|
||||||
n = n1
|
n = n1
|
||||||
unsafe{ buf[i] = digit_pairs.str[d_i] }
|
unsafe {
|
||||||
|
buf[i] = strconv.digit_pairs.str[d_i]
|
||||||
|
}
|
||||||
i--
|
i--
|
||||||
d_i++
|
d_i++
|
||||||
unsafe{ buf[i] = digit_pairs.str[d_i] }
|
unsafe {
|
||||||
|
buf[i] = strconv.digit_pairs.str[d_i]
|
||||||
|
}
|
||||||
i--
|
i--
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
@ -114,8 +119,7 @@ pub fn format_dec_sb(d u64, p BF_param, mut res strings.Builder) {
|
|||||||
if d_i < 20 {
|
if d_i < 20 {
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
unsafe{ res.write_ptr(&buf[i],n_char) }
|
unsafe { res.write_ptr(&buf[i], n_char) }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// we have a zero no need of more code!
|
// we have a zero no need of more code!
|
||||||
res.write_b(`0`)
|
res.write_b(`0`)
|
||||||
@ -123,19 +127,16 @@ pub fn format_dec_sb(d u64, p BF_param, mut res strings.Builder) {
|
|||||||
//===========================================
|
//===========================================
|
||||||
|
|
||||||
if p.allign == .left {
|
if p.allign == .left {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[direct_array_access; manualfree]
|
||||||
|
|
||||||
[manualfree]
|
|
||||||
[direct_array_access]
|
|
||||||
pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
|
pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
|
||||||
unsafe{
|
unsafe {
|
||||||
// we add the rounding value
|
// we add the rounding value
|
||||||
s := f64_to_str(f + dec_round[dec_digit], 18)
|
s := f64_to_str(f + dec_round[dec_digit], 18)
|
||||||
// check for +inf -inf Nan
|
// check for +inf -inf Nan
|
||||||
@ -144,13 +145,13 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_sgn_flag := false
|
m_sgn_flag := false
|
||||||
mut sgn := 1
|
mut sgn := 1
|
||||||
mut b := [26]byte{}
|
mut b := [26]byte{}
|
||||||
mut d_pos := 1
|
mut d_pos := 1
|
||||||
mut i := 0
|
mut i := 0
|
||||||
mut i1 := 0
|
mut i1 := 0
|
||||||
mut exp := 0
|
mut exp := 0
|
||||||
mut exp_sgn := 1
|
mut exp_sgn := 1
|
||||||
|
|
||||||
mut dot_res_sp := -1
|
mut dot_res_sp := -1
|
||||||
|
|
||||||
@ -162,8 +163,7 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
|
|||||||
} else if c == `+` {
|
} else if c == `+` {
|
||||||
sgn = 1
|
sgn = 1
|
||||||
i++
|
i++
|
||||||
}
|
} else if c >= `0` && c <= `9` {
|
||||||
else if c >= `0` && c <= `9` {
|
|
||||||
b[i1] = c
|
b[i1] = c
|
||||||
i1++
|
i1++
|
||||||
i++
|
i++
|
||||||
@ -171,7 +171,7 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
|
|||||||
if sgn > 0 {
|
if sgn > 0 {
|
||||||
d_pos = i
|
d_pos = i
|
||||||
} else {
|
} else {
|
||||||
d_pos = i-1
|
d_pos = i - 1
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
} else if c == `e` {
|
} else if c == `e` {
|
||||||
@ -179,7 +179,7 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
|
|||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
s.free()
|
s.free()
|
||||||
return "[Float conversion error!!]"
|
return '[Float conversion error!!]'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b[i1] = 0
|
b[i1] = 0
|
||||||
@ -200,11 +200,11 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// allocate exp+32 chars for the return string
|
// 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 res := []byte{len: exp+32, init: 0}
|
mut res := []byte{len: exp + 32, init: 0}
|
||||||
mut r_i := 0 // result string buffer index
|
mut r_i := 0 // result string buffer index
|
||||||
|
|
||||||
//println("s:${sgn} b:${b[0]} es:${exp_sgn} exp:${exp}")
|
// println("s:${sgn} b:${b[0]} es:${exp_sgn} exp:${exp}")
|
||||||
|
|
||||||
// s no more needed
|
// s no more needed
|
||||||
s.free()
|
s.free()
|
||||||
@ -239,14 +239,14 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
|
|||||||
r_i++
|
r_i++
|
||||||
exp--
|
exp--
|
||||||
}
|
}
|
||||||
//println("exp: $exp $r_i $dot_res_sp")
|
// println("exp: $exp $r_i $dot_res_sp")
|
||||||
} else {
|
} else {
|
||||||
mut dot_p := true
|
mut dot_p := true
|
||||||
for exp > 0 {
|
for exp > 0 {
|
||||||
res[r_i] = `0`
|
res[r_i] = `0`
|
||||||
r_i++
|
r_i++
|
||||||
exp--
|
exp--
|
||||||
if dot_p {
|
if dot_p {
|
||||||
dot_res_sp = r_i
|
dot_res_sp = r_i
|
||||||
res[r_i] = `.`
|
res[r_i] = `.`
|
||||||
r_i++
|
r_i++
|
||||||
@ -266,14 +266,14 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
|
|||||||
res.free()
|
res.free()
|
||||||
return tmp_res
|
return tmp_res
|
||||||
}
|
}
|
||||||
|
|
||||||
//println("r_i-d_pos: ${r_i - d_pos}")
|
// println("r_i-d_pos: ${r_i - d_pos}")
|
||||||
if dot_res_sp >= 0 {
|
if dot_res_sp >= 0 {
|
||||||
if (r_i - dot_res_sp) > dec_digit {
|
if (r_i - dot_res_sp) > dec_digit {
|
||||||
r_i = dot_res_sp + dec_digit + 1
|
r_i = dot_res_sp + dec_digit + 1
|
||||||
}
|
}
|
||||||
res[r_i] = 0
|
res[r_i] = 0
|
||||||
//println("result: [${tos(&res[0],r_i)}]")
|
// println("result: [${tos(&res[0],r_i)}]")
|
||||||
tmp_res := tos(res.data, r_i).clone()
|
tmp_res := tos(res.data, r_i).clone()
|
||||||
res.free()
|
res.free()
|
||||||
return tmp_res
|
return tmp_res
|
||||||
@ -293,19 +293,18 @@ pub fn f64_to_str_lnd1(f f64, dec_digit int) string {
|
|||||||
res.free()
|
res.free()
|
||||||
return tmp_res
|
return tmp_res
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// strings.Builder version of format_fl
|
// strings.Builder version of format_fl
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn format_fl(f f64, p BF_param) string {
|
pub fn format_fl(f f64, p BF_param) string {
|
||||||
unsafe{
|
unsafe {
|
||||||
mut s := ""
|
mut s := ''
|
||||||
//mut fs := "1.2343"
|
// mut fs := "1.2343"
|
||||||
mut fs := f64_to_str_lnd1(if f >= 0.0 {f} else {-f}, p.len1)
|
mut fs := f64_to_str_lnd1(if f >= 0.0 { f } else { -f }, p.len1)
|
||||||
//println("Dario")
|
// println("Dario")
|
||||||
//println(fs)
|
// println(fs)
|
||||||
|
|
||||||
// error!!
|
// error!!
|
||||||
if fs[0] == `[` {
|
if fs[0] == `[` {
|
||||||
@ -318,7 +317,7 @@ pub fn format_fl(f f64, p BF_param) string {
|
|||||||
fs = remove_tail_zeros(fs)
|
fs = remove_tail_zeros(fs)
|
||||||
tmp.free()
|
tmp.free()
|
||||||
}
|
}
|
||||||
mut res := strings.new_builder( if p.len0 > fs.len { p.len0 } else { fs.len })
|
mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
|
||||||
|
|
||||||
mut sign_len_diff := 0
|
mut sign_len_diff := 0
|
||||||
if p.pad_ch == `0` {
|
if p.pad_ch == `0` {
|
||||||
@ -338,7 +337,7 @@ pub fn format_fl(f f64, p BF_param) string {
|
|||||||
if p.positive {
|
if p.positive {
|
||||||
if p.sign_flag {
|
if p.sign_flag {
|
||||||
tmp := s
|
tmp := s
|
||||||
s = "+" + fs
|
s = '+' + fs
|
||||||
tmp.free()
|
tmp.free()
|
||||||
} else {
|
} else {
|
||||||
tmp := s
|
tmp := s
|
||||||
@ -347,7 +346,7 @@ pub fn format_fl(f f64, p BF_param) string {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tmp := s
|
tmp := s
|
||||||
s = "-" + fs
|
s = '-' + fs
|
||||||
tmp.free()
|
tmp.free()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,18 +354,17 @@ pub fn format_fl(f f64, p BF_param) string {
|
|||||||
dif := p.len0 - s.len + sign_len_diff
|
dif := p.len0 - s.len + sign_len_diff
|
||||||
|
|
||||||
if p.allign == .right {
|
if p.allign == .right {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.write_string(s)
|
res.write_string(s)
|
||||||
if p.allign == .left {
|
if p.allign == .left {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
s.free()
|
s.free()
|
||||||
fs.free()
|
fs.free()
|
||||||
tmp_res := res.str()
|
tmp_res := res.str()
|
||||||
@ -377,13 +375,13 @@ pub fn format_fl(f f64, p BF_param) string {
|
|||||||
|
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn format_es(f f64, p BF_param) string {
|
pub fn format_es(f f64, p BF_param) string {
|
||||||
unsafe{
|
unsafe {
|
||||||
mut s := ""
|
mut s := ''
|
||||||
mut fs := f64_to_str_pad(if f> 0 {f} else {-f},p.len1)
|
mut fs := f64_to_str_pad(if f > 0 { f } else { -f }, p.len1)
|
||||||
if p.rm_tail_zero {
|
if p.rm_tail_zero {
|
||||||
fs = remove_tail_zeros(fs)
|
fs = remove_tail_zeros(fs)
|
||||||
}
|
}
|
||||||
mut res := strings.new_builder( if p.len0 > fs.len { p.len0 } else { fs.len })
|
mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
|
||||||
|
|
||||||
mut sign_len_diff := 0
|
mut sign_len_diff := 0
|
||||||
if p.pad_ch == `0` {
|
if p.pad_ch == `0` {
|
||||||
@ -403,7 +401,7 @@ pub fn format_es(f f64, p BF_param) string {
|
|||||||
if p.positive {
|
if p.positive {
|
||||||
if p.sign_flag {
|
if p.sign_flag {
|
||||||
tmp := s
|
tmp := s
|
||||||
s = "+" + fs
|
s = '+' + fs
|
||||||
tmp.free()
|
tmp.free()
|
||||||
} else {
|
} else {
|
||||||
tmp := s
|
tmp := s
|
||||||
@ -412,20 +410,20 @@ pub fn format_es(f f64, p BF_param) string {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tmp := s
|
tmp := s
|
||||||
s = "-" + fs
|
s = '-' + fs
|
||||||
tmp.free()
|
tmp.free()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dif := p.len0 - s.len + sign_len_diff
|
dif := p.len0 - s.len + sign_len_diff
|
||||||
if p.allign == .right {
|
if p.allign == .right {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.write_string(s)
|
res.write_string(s)
|
||||||
if p.allign == .left {
|
if p.allign == .left {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -439,19 +437,19 @@ pub fn format_es(f f64, p BF_param) string {
|
|||||||
|
|
||||||
[direct_array_access]
|
[direct_array_access]
|
||||||
pub fn remove_tail_zeros(s string) string {
|
pub fn remove_tail_zeros(s string) string {
|
||||||
unsafe{
|
unsafe {
|
||||||
mut buf := malloc_noscan(s.len + 1)
|
mut buf := malloc_noscan(s.len + 1)
|
||||||
mut i_d := 0
|
mut i_d := 0
|
||||||
mut i_s := 0
|
mut i_s := 0
|
||||||
|
|
||||||
// skip spaces
|
// skip spaces
|
||||||
for i_s < s.len && s[i_s] !in [`-`,`+`] && (s[i_s] > `9` || s[i_s] < `0`) {
|
for i_s < s.len && s[i_s] !in [`-`, `+`] && (s[i_s] > `9` || s[i_s] < `0`) {
|
||||||
buf[i_d] = s[i_s]
|
buf[i_d] = s[i_s]
|
||||||
i_s++
|
i_s++
|
||||||
i_d++
|
i_d++
|
||||||
}
|
}
|
||||||
// sign
|
// sign
|
||||||
if i_s < s.len && s[i_s] in [`-`,`+`] {
|
if i_s < s.len && s[i_s] in [`-`, `+`] {
|
||||||
buf[i_d] = s[i_s]
|
buf[i_d] = s[i_s]
|
||||||
i_s++
|
i_s++
|
||||||
i_d++
|
i_d++
|
||||||
|
@ -1,107 +1,107 @@
|
|||||||
import strconv
|
import strconv
|
||||||
|
|
||||||
fn test_format(){
|
fn test_format() {
|
||||||
mut temp_s := ""
|
mut temp_s := ''
|
||||||
mut tmp_str:= ""
|
mut tmp_str := ''
|
||||||
a0 := u32(10)
|
a0 := u32(10)
|
||||||
b0 := 200
|
b0 := 200
|
||||||
c0 := byte(12)
|
c0 := byte(12)
|
||||||
s0 := "ciAo"
|
s0 := 'ciAo'
|
||||||
ch0 := `B`
|
ch0 := `B`
|
||||||
f0 := 0.312345
|
f0 := 0.312345
|
||||||
f1 := 200000.0
|
f1 := 200000.0
|
||||||
f2 := -1234.300e6
|
f2 := -1234.300e6
|
||||||
f3 := 1234.300e-6
|
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)
|
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)
|
// C.printf(sc0.str,a0 ,b0 ,c0 ,s0.str ,b0 ,f0, f1, ch0)
|
||||||
//println("\n$temp_s")
|
// println("\n$temp_s")
|
||||||
assert tmp_str == temp_s
|
assert tmp_str == temp_s
|
||||||
|
|
||||||
a := byte(12)
|
a := byte(12)
|
||||||
b := i16(13)
|
b := i16(13)
|
||||||
c := 14
|
c := 14
|
||||||
d := i64(15)
|
d := i64(15)
|
||||||
sc1 := "==>%hhd %hd %d %ld"
|
sc1 := '==>%hhd %hd %d %ld'
|
||||||
temp_s = strconv.v_sprintf(sc1, a ,b ,c, d)
|
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)
|
// C.printf(sc1.str, a ,b ,c, d)
|
||||||
//println("\n$temp_s")
|
// println("\n$temp_s")
|
||||||
assert tmp_str == temp_s
|
assert tmp_str == temp_s
|
||||||
|
|
||||||
a1 := byte(0xff)
|
a1 := byte(0xff)
|
||||||
b1 := i16(0xffff)
|
b1 := i16(0xffff)
|
||||||
c1 := u32(0xffff_ffff)
|
c1 := u32(0xffff_ffff)
|
||||||
d1 := u64(-1)
|
d1 := u64(-1)
|
||||||
sc2 := "%hhu %hu %u %lu"
|
sc2 := '%hhu %hu %u %lu'
|
||||||
temp_s = strconv.v_sprintf(sc2, a1 ,b1 ,c1, d1)
|
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)
|
// C.printf(sc2.str, a1 ,b1 ,c1, d1)
|
||||||
//println("\n$temp_s")
|
// 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
|
assert tmp_str == temp_s
|
||||||
|
|
||||||
sc4 := "[%-20.3e] [%20.3e] [%-020.3e] [%-020.3E] [%-020.3e] [%-020.3e]"
|
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)
|
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)
|
// C.printf(sc4.str, f0, f1, f1, f1, f2, f3)
|
||||||
//println("\n$temp_s")
|
// println("\n$temp_s")
|
||||||
assert tmp_str == 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)
|
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)
|
// C.printf(sc5.str, f0, f1, f1, f2, f3, f3)
|
||||||
//println("\n$temp_s")
|
// println("\n$temp_s")
|
||||||
assert tmp_str == temp_s
|
assert tmp_str == temp_s
|
||||||
|
|
||||||
ml := 3
|
ml := 3
|
||||||
sc6 := "%.*s [%05hhX]"
|
sc6 := '%.*s [%05hhX]'
|
||||||
temp_s = strconv.v_sprintf(sc6, ml, s0 , a)
|
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)
|
// C.printf(sc6.str, ml, s0.str, a)
|
||||||
//println("\n$temp_s")
|
// println("\n$temp_s")
|
||||||
assert tmp_str == temp_s
|
assert tmp_str == temp_s
|
||||||
|
|
||||||
a2 := 125
|
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)
|
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)
|
// C.printf(sc7.str, a2, a2, a2, a2, a2, a2)
|
||||||
//println("\n$temp_s")
|
// println("\n$temp_s")
|
||||||
assert tmp_str == temp_s
|
assert tmp_str == temp_s
|
||||||
|
|
||||||
g_test := [
|
g_test := [
|
||||||
"[ -1e-07][ -1E-07]|",
|
'[ -1e-07][ -1E-07]|',
|
||||||
"[ -1e-06][ -1E-06]|",
|
'[ -1e-06][ -1E-06]|',
|
||||||
"[ -1e-05][ -1E-05]|",
|
'[ -1e-05][ -1E-05]|',
|
||||||
"[ -0.0001][ -0.0001]|",
|
'[ -0.0001][ -0.0001]|',
|
||||||
"[ -0.001][ -0.001]|",
|
'[ -0.001][ -0.001]|',
|
||||||
"[ -0.01][ -0.01]|",
|
'[ -0.01][ -0.01]|',
|
||||||
"[ -0.1][ -0.1]|",
|
'[ -0.1][ -0.1]|',
|
||||||
"[ -1][ -1]|",
|
'[ -1][ -1]|',
|
||||||
"[ -10][ -10]|",
|
'[ -10][ -10]|',
|
||||||
"[ -100][ -100]|",
|
'[ -100][ -100]|',
|
||||||
"[ -1000][ -1000]|",
|
'[ -1000][ -1000]|',
|
||||||
"[ -10000][ -10000]|"
|
'[ -10000][ -10000]|',
|
||||||
]
|
]
|
||||||
|
|
||||||
mut ft := -1e-7
|
mut ft := -1e-7
|
||||||
mut x := 0
|
mut x := 0
|
||||||
mut cnt:= 0
|
mut cnt := 0
|
||||||
sc8 := "[%20g][%20G]|"
|
sc8 := '[%20g][%20G]|'
|
||||||
for x < 12 {
|
for x < 12 {
|
||||||
temp_s = strconv.v_sprintf(sc8, ft, ft)
|
temp_s = strconv.v_sprintf(sc8, ft, ft)
|
||||||
//C.printf(sc8.str, ft, ft)
|
// C.printf(sc8.str, ft, ft)
|
||||||
//println("\n$temp_s")
|
// println("\n$temp_s")
|
||||||
assert temp_s == g_test[cnt]
|
assert temp_s == g_test[cnt]
|
||||||
ft = ft * 10.0
|
ft = ft * 10.0
|
||||||
x++
|
x++
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
module strconv
|
module strconv
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
f32/f64 ftoa functions
|
f32/f64 ftoa functions
|
||||||
|
|
||||||
Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
|
Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
|
||||||
@ -17,12 +16,11 @@ Pages 270–282 https://doi.org/10.1145/3192366.3192369
|
|||||||
|
|
||||||
inspired by the Go version here:
|
inspired by the Go version here:
|
||||||
https://github.com/cespare/ryu/tree/ba56a33f39e3bbbfa409095d0f9ae168a595feea
|
https://github.com/cespare/ryu/tree/ba56a33f39e3bbbfa409095d0f9ae168a595feea
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
pub fn ftoa_64(f f64) string {
|
pub fn ftoa_64(f f64) string {
|
||||||
return f64_to_str(f,17)
|
return f64_to_str(f, 17)
|
||||||
}
|
}
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
@ -32,7 +30,7 @@ pub fn ftoa_long_64(f f64) string {
|
|||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
pub fn ftoa_32(f f32) string {
|
pub fn ftoa_32(f f32) string {
|
||||||
return f32_to_str(f,8)
|
return f32_to_str(f, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
|
@ -6,7 +6,7 @@ const base_digits = '0123456789abcdefghijklmnopqrstuvwxyz'
|
|||||||
// for digit values > 10, this function uses the small latin leters a-z.
|
// for digit values > 10, this function uses the small latin leters a-z.
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn format_int(n i64, radix int) string {
|
pub fn format_int(n i64, radix int) string {
|
||||||
unsafe{
|
unsafe {
|
||||||
if radix < 2 || radix > 36 {
|
if radix < 2 || radix > 36 {
|
||||||
panic('invalid radix: $radix . It should be => 2 and <= 36')
|
panic('invalid radix: $radix . It should be => 2 and <= 36')
|
||||||
}
|
}
|
||||||
@ -22,11 +22,11 @@ pub fn format_int(n i64, radix int) string {
|
|||||||
mut res := ''
|
mut res := ''
|
||||||
for n_copy != 0 {
|
for n_copy != 0 {
|
||||||
tmp_0 := res
|
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
|
res = tmp_1 + res
|
||||||
tmp_0.free()
|
tmp_0.free()
|
||||||
tmp_1.free()
|
tmp_1.free()
|
||||||
//res = base_digits[n_copy % radix].ascii_str() + res
|
// res = base_digits[n_copy % radix].ascii_str() + res
|
||||||
n_copy /= radix
|
n_copy /= radix
|
||||||
}
|
}
|
||||||
return '$sign$res'
|
return '$sign$res'
|
||||||
@ -37,7 +37,7 @@ pub fn format_int(n i64, radix int) string {
|
|||||||
// for digit values > 10, this function uses the small latin leters a-z.
|
// for digit values > 10, this function uses the small latin leters a-z.
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn format_uint(n u64, radix int) string {
|
pub fn format_uint(n u64, radix int) string {
|
||||||
unsafe{
|
unsafe {
|
||||||
if radix < 2 || radix > 36 {
|
if radix < 2 || radix > 36 {
|
||||||
panic('invalid radix: $radix . It should be => 2 and <= 36')
|
panic('invalid radix: $radix . It should be => 2 and <= 36')
|
||||||
}
|
}
|
||||||
@ -49,11 +49,11 @@ pub fn format_uint(n u64, radix int) string {
|
|||||||
uradix := u64(radix)
|
uradix := u64(radix)
|
||||||
for n_copy != 0 {
|
for n_copy != 0 {
|
||||||
tmp_0 := res
|
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
|
res = tmp_1 + res
|
||||||
tmp_0.free()
|
tmp_0.free()
|
||||||
tmp_1.free()
|
tmp_1.free()
|
||||||
//res = base_digits[n_copy % uradix].ascii_str() + res
|
// res = base_digits[n_copy % uradix].ascii_str() + res
|
||||||
n_copy /= uradix
|
n_copy /= uradix
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
|
@ -32,8 +32,7 @@ fn test_format_uint() {
|
|||||||
assert strconv.format_int(255, 8) == '377'
|
assert strconv.format_int(255, 8) == '377'
|
||||||
assert strconv.format_int(255, 10) == '255'
|
assert strconv.format_int(255, 10) == '255'
|
||||||
assert strconv.format_int(255, 16) == 'ff'
|
assert strconv.format_int(255, 16) == 'ff'
|
||||||
assert strconv.format_uint(18446744073709551615, 2) ==
|
assert strconv.format_uint(18446744073709551615, 2) == '1111111111111111111111111111111111111111111111111111111111111111'
|
||||||
'1111111111111111111111111111111111111111111111111111111111111111'
|
|
||||||
assert strconv.format_uint(18446744073709551615, 16) == 'ffffffffffffffff'
|
assert strconv.format_uint(18446744073709551615, 16) == 'ffffffffffffffff'
|
||||||
assert strconv.parse_int('baobab', 36, 64) == 683058467
|
assert strconv.parse_int('baobab', 36, 64) == 683058467
|
||||||
assert strconv.format_uint(683058467, 36) == 'baobab'
|
assert strconv.format_uint(683058467, 36) == 'baobab'
|
||||||
|
@ -4,8 +4,8 @@ module strconv
|
|||||||
pub struct PrepNumber {
|
pub struct PrepNumber {
|
||||||
pub mut:
|
pub mut:
|
||||||
negative bool // 0 if positive number, 1 if negative
|
negative bool // 0 if positive number, 1 if negative
|
||||||
exponent int // power of 10 exponent
|
exponent int // power of 10 exponent
|
||||||
mantissa u64 // integer mantissa
|
mantissa u64 // integer mantissa
|
||||||
}
|
}
|
||||||
|
|
||||||
// dec32 is a floating decimal type representing m * 10^e.
|
// dec32 is a floating decimal type representing m * 10^e.
|
||||||
@ -52,4 +52,4 @@ pub union Float32u {
|
|||||||
pub mut:
|
pub mut:
|
||||||
f f32
|
f f32
|
||||||
u u32
|
u u32
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,6 @@
|
|||||||
module strconv
|
module strconv
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
f32/f64 to string utilities
|
f32/f64 to string utilities
|
||||||
|
|
||||||
Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
|
Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
|
||||||
@ -17,17 +16,13 @@ Pages 270–282 https://doi.org/10.1145/3192366.3192369
|
|||||||
|
|
||||||
inspired by the Go version here:
|
inspired by the Go version here:
|
||||||
https://github.com/cespare/ryu/tree/ba56a33f39e3bbbfa409095d0f9ae168a595feea
|
https://github.com/cespare/ryu/tree/ba56a33f39e3bbbfa409095d0f9ae168a595feea
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import math.bits
|
import math.bits
|
||||||
|
|
||||||
//import math
|
// import math
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
General Utilities
|
General Utilities
|
||||||
|
|
||||||
*/
|
*/
|
||||||
fn assert1(t bool, msg string) {
|
fn assert1(t bool, msg string) {
|
||||||
if !t {
|
if !t {
|
||||||
@ -61,25 +56,23 @@ fn bool_to_u64(b bool) u64 {
|
|||||||
|
|
||||||
fn get_string_special(neg bool, expZero bool, mantZero bool) string {
|
fn get_string_special(neg bool, expZero bool, mantZero bool) string {
|
||||||
if !mantZero {
|
if !mantZero {
|
||||||
return "nan"
|
return 'nan'
|
||||||
}
|
}
|
||||||
if !expZero {
|
if !expZero {
|
||||||
if neg {
|
if neg {
|
||||||
return "-inf"
|
return '-inf'
|
||||||
} else {
|
} else {
|
||||||
return "+inf"
|
return '+inf'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if neg {
|
if neg {
|
||||||
return "-0e+00"
|
return '-0e+00'
|
||||||
}
|
}
|
||||||
return "0e+00"
|
return '0e+00'
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
32 bit functions
|
||||||
32 bit functions
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
// decimal_len_32 return the number of decimal digits of the input
|
// decimal_len_32 return the number of decimal digits of the input
|
||||||
[deprecated]
|
[deprecated]
|
||||||
@ -87,26 +80,35 @@ pub fn decimal_len_32(u u32) int {
|
|||||||
// Function precondition: u is not a 10-digit number.
|
// Function precondition: u is not a 10-digit number.
|
||||||
// (9 digits are sufficient for round-tripping.)
|
// (9 digits are sufficient for round-tripping.)
|
||||||
// This benchmarked faster than the log2 approach used for u64.
|
// 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 }
|
if u >= 100000000 {
|
||||||
else if u >= 10000000 { return 8 }
|
return 9
|
||||||
else if u >= 1000000 { return 7 }
|
} else if u >= 10000000 {
|
||||||
else if u >= 100000 { return 6 }
|
return 8
|
||||||
else if u >= 10000 { return 5 }
|
} else if u >= 1000000 {
|
||||||
else if u >= 1000 { return 4 }
|
return 7
|
||||||
else if u >= 100 { return 3 }
|
} else if u >= 100000 {
|
||||||
else if u >= 10 { return 2 }
|
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
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mul_shift_32(m u32, mul u64, ishift int) u32 {
|
fn mul_shift_32(m u32, mul u64, ishift int) u32 {
|
||||||
// QTODO
|
// QTODO
|
||||||
//assert ishift > 32
|
// assert ishift > 32
|
||||||
|
|
||||||
hi, lo := bits.mul_64(u64(m), mul)
|
hi, lo := bits.mul_64(u64(m), mul)
|
||||||
shifted_sum := (lo >> u64(ishift)) + (hi << u64(64-ishift))
|
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)
|
return u32(shifted_sum)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,9 +122,9 @@ fn mul_pow5_div_pow2(m u32, i u32, j int) u32 {
|
|||||||
|
|
||||||
fn pow5_factor_32(i_v u32) u32 {
|
fn pow5_factor_32(i_v u32) u32 {
|
||||||
mut v := i_v
|
mut v := i_v
|
||||||
for n := u32(0); ; n++ {
|
for n := u32(0); true; n++ {
|
||||||
q := v/5
|
q := v / 5
|
||||||
r := v%5
|
r := v % 5
|
||||||
if r != 0 {
|
if r != 0 {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
@ -145,8 +147,8 @@ fn multiple_of_power_of_two_32(v u32, p u32) bool {
|
|||||||
fn log10_pow2(e int) u32 {
|
fn log10_pow2(e int) u32 {
|
||||||
// The first value this approximation fails for is 2^1651
|
// The first value this approximation fails for is 2^1651
|
||||||
// which is just greater than 10^297.
|
// which is just greater than 10^297.
|
||||||
assert1(e >= 0, "e >= 0")
|
assert1(e >= 0, 'e >= 0')
|
||||||
assert1(e <= 1650, "e <= 1650")
|
assert1(e <= 1650, 'e <= 1650')
|
||||||
return (u32(e) * 78913) >> 18
|
return (u32(e) * 78913) >> 18
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,8 +156,8 @@ fn log10_pow2(e int) u32 {
|
|||||||
fn log10_pow5(e int) u32 {
|
fn log10_pow5(e int) u32 {
|
||||||
// The first value this approximation fails for is 5^2621
|
// The first value this approximation fails for is 5^2621
|
||||||
// which is just greater than 10^1832.
|
// which is just greater than 10^1832.
|
||||||
assert1(e >= 0, "e >= 0")
|
assert1(e >= 0, 'e >= 0')
|
||||||
assert1(e <= 2620, "e <= 2620")
|
assert1(e <= 2620, 'e <= 2620')
|
||||||
return (u32(e) * 732923) >> 20
|
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
|
// This approximation works up to the point that the multiplication
|
||||||
// overflows at e = 3529. If the multiplication were done in 64 bits,
|
// 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.
|
// it would fail at 5^4004 which is just greater than 2^9297.
|
||||||
assert1(e >= 0, "e >= 0")
|
assert1(e >= 0, 'e >= 0')
|
||||||
assert1(e <= 3528, "e <= 3528")
|
assert1(e <= 3528, 'e <= 3528')
|
||||||
return int( ((u32(e)*1217359)>>19) + 1)
|
return int(((u32(e) * 1217359) >> 19) + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
64 bit functions
|
||||||
64 bit functions
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
[deprecated]
|
|
||||||
// decimal_len_64 return the number of decimal digits of the input
|
// decimal_len_64 return the number of decimal digits of the input
|
||||||
|
[deprecated]
|
||||||
pub fn decimal_len_64(u u64) int {
|
pub fn decimal_len_64(u u64) int {
|
||||||
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
|
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
|
||||||
log2 := 64 - bits.leading_zeros_64(u) - 1
|
log2 := 64 - bits.leading_zeros_64(u) - 1
|
||||||
@ -190,25 +191,28 @@ fn shift_right_128(v Uint128, shift int) u64 {
|
|||||||
// (It is in the range [2, 59].)
|
// (It is in the range [2, 59].)
|
||||||
// Check this here in case a future change requires larger shift
|
// Check this here in case a future change requires larger shift
|
||||||
// values. In this case this function needs to be adjusted.
|
// 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))
|
return (v.hi << u64(64 - shift)) | (v.lo >> u32(shift))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mul_shift_64(m u64, mul Uint128, shift int) u64 {
|
fn mul_shift_64(m u64, mul Uint128, shift int) u64 {
|
||||||
hihi, hilo := bits.mul_64(m, mul.hi)
|
hihi, hilo := bits.mul_64(m, mul.hi)
|
||||||
lohi, _ := bits.mul_64(m, mul.lo)
|
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 {
|
if sum.lo < lohi {
|
||||||
sum.hi++ // overflow
|
sum.hi++ // overflow
|
||||||
}
|
}
|
||||||
return shift_right_128(sum, shift-64)
|
return shift_right_128(sum, shift - 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pow5_factor_64(v_i u64) u32 {
|
fn pow5_factor_64(v_i u64) u32 {
|
||||||
mut v := v_i
|
mut v := v_i
|
||||||
for n := u32(0); ; n++ {
|
for n := u32(0); true; n++ {
|
||||||
q := v/5
|
q := v / 5
|
||||||
r := v%5
|
r := v % 5
|
||||||
if r != 0 {
|
if r != 0 {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
@ -226,46 +230,43 @@ fn multiple_of_power_of_two_64(v u64, p u32) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
f64 to string with string format
|
f64 to string with string format
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: Investigate precision issues
|
// TODO: Investigate precision issues
|
||||||
// f32_to_str_l return a string with the f32 converted in a string in decimal notation
|
// f32_to_str_l return a string with the f32 converted in a string in decimal notation
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn f32_to_str_l(f f32) string {
|
pub fn f32_to_str_l(f f32) string {
|
||||||
s := f32_to_str(f,6)
|
s := f32_to_str(f, 6)
|
||||||
res := fxx_to_str_l_parse(s)
|
res := fxx_to_str_l_parse(s)
|
||||||
unsafe{s.free()}
|
unsafe { s.free() }
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn f32_to_str_l_no_dot(f f32) string {
|
pub fn f32_to_str_l_no_dot(f f32) string {
|
||||||
s := f32_to_str(f,6)
|
s := f32_to_str(f, 6)
|
||||||
res := fxx_to_str_l_parse_no_dot(s)
|
res := fxx_to_str_l_parse_no_dot(s)
|
||||||
unsafe{s.free()}
|
unsafe { s.free() }
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn f64_to_str_l(f f64) string {
|
pub fn f64_to_str_l(f f64) string {
|
||||||
s := f64_to_str(f,18)
|
s := f64_to_str(f, 18)
|
||||||
res := fxx_to_str_l_parse(s)
|
res := fxx_to_str_l_parse(s)
|
||||||
unsafe{s.free()}
|
unsafe { s.free() }
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn f64_to_str_l_no_dot(f f64) string {
|
pub fn f64_to_str_l_no_dot(f f64) string {
|
||||||
s := f64_to_str(f,18)
|
s := f64_to_str(f, 18)
|
||||||
res := fxx_to_str_l_parse_no_dot(s)
|
res := fxx_to_str_l_parse_no_dot(s)
|
||||||
unsafe{s.free()}
|
unsafe { s.free() }
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// f64_to_str_l return a string with the f64 converted in a string in decimal notation
|
// f64_to_str_l return a string with the f64 converted in a string in decimal notation
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn fxx_to_str_l_parse(s string) string {
|
pub fn fxx_to_str_l_parse(s string) string {
|
||||||
@ -275,13 +276,13 @@ pub fn fxx_to_str_l_parse(s string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_sgn_flag := false
|
m_sgn_flag := false
|
||||||
mut sgn := 1
|
mut sgn := 1
|
||||||
mut b := [26]byte{}
|
mut b := [26]byte{}
|
||||||
mut d_pos := 1
|
mut d_pos := 1
|
||||||
mut i := 0
|
mut i := 0
|
||||||
mut i1 := 0
|
mut i1 := 0
|
||||||
mut exp := 0
|
mut exp := 0
|
||||||
mut exp_sgn := 1
|
mut exp_sgn := 1
|
||||||
|
|
||||||
// get sign and decimal parts
|
// get sign and decimal parts
|
||||||
for c in s {
|
for c in s {
|
||||||
@ -291,8 +292,7 @@ pub fn fxx_to_str_l_parse(s string) string {
|
|||||||
} else if c == `+` {
|
} else if c == `+` {
|
||||||
sgn = 1
|
sgn = 1
|
||||||
i++
|
i++
|
||||||
}
|
} else if c >= `0` && c <= `9` {
|
||||||
else if c >= `0` && c <= `9` {
|
|
||||||
b[i1] = c
|
b[i1] = c
|
||||||
i1++
|
i1++
|
||||||
i++
|
i++
|
||||||
@ -300,14 +300,14 @@ pub fn fxx_to_str_l_parse(s string) string {
|
|||||||
if sgn > 0 {
|
if sgn > 0 {
|
||||||
d_pos = i
|
d_pos = i
|
||||||
} else {
|
} else {
|
||||||
d_pos = i-1
|
d_pos = i - 1
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
} else if c == `e` {
|
} else if c == `e` {
|
||||||
i++
|
i++
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
return "Float conversion error!!"
|
return 'Float conversion error!!'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b[i1] = 0
|
b[i1] = 0
|
||||||
@ -323,16 +323,16 @@ pub fn fxx_to_str_l_parse(s string) string {
|
|||||||
|
|
||||||
mut c := i
|
mut c := i
|
||||||
for c < s.len {
|
for c < s.len {
|
||||||
exp = exp * 10 + int(s[c]-`0`)
|
exp = exp * 10 + int(s[c] - `0`)
|
||||||
c++
|
c++
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate exp+32 chars for the return string
|
// 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
|
mut r_i := 0 // result string buffer index
|
||||||
|
|
||||||
|
// println("s:${sgn} b:${b[0]} es:${exp_sgn} exp:${exp}")
|
||||||
|
|
||||||
//println("s:${sgn} b:${b[0]} es:${exp_sgn} exp:${exp}")
|
|
||||||
|
|
||||||
if sgn == 1 {
|
if sgn == 1 {
|
||||||
if m_sgn_flag {
|
if m_sgn_flag {
|
||||||
res[r_i] = `+`
|
res[r_i] = `+`
|
||||||
@ -368,7 +368,7 @@ pub fn fxx_to_str_l_parse(s string) string {
|
|||||||
res[r_i] = `0`
|
res[r_i] = `0`
|
||||||
r_i++
|
r_i++
|
||||||
exp--
|
exp--
|
||||||
if dot_p {
|
if dot_p {
|
||||||
res[r_i] = `.`
|
res[r_i] = `.`
|
||||||
r_i++
|
r_i++
|
||||||
dot_p = false
|
dot_p = false
|
||||||
@ -380,14 +380,14 @@ pub fn fxx_to_str_l_parse(s string) string {
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
// remove the dot form the numbers like 2.
|
// remove the dot form the numbers like 2.
|
||||||
if r_i > 1 && res[r_i-1] == `.` {
|
if r_i > 1 && res[r_i-1] == `.` {
|
||||||
r_i--
|
r_i--
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
res[r_i] = 0
|
res[r_i] = 0
|
||||||
return unsafe { tos(res.data,r_i) }
|
return unsafe { tos(res.data, r_i) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// f64_to_str_l return a string with the f64 converted in a string in decimal notation
|
// f64_to_str_l return a string with the f64 converted in a string in decimal notation
|
||||||
@ -399,13 +399,13 @@ pub fn fxx_to_str_l_parse_no_dot(s string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_sgn_flag := false
|
m_sgn_flag := false
|
||||||
mut sgn := 1
|
mut sgn := 1
|
||||||
mut b := [26]byte{}
|
mut b := [26]byte{}
|
||||||
mut d_pos := 1
|
mut d_pos := 1
|
||||||
mut i := 0
|
mut i := 0
|
||||||
mut i1 := 0
|
mut i1 := 0
|
||||||
mut exp := 0
|
mut exp := 0
|
||||||
mut exp_sgn := 1
|
mut exp_sgn := 1
|
||||||
|
|
||||||
// get sign and decimal parts
|
// get sign and decimal parts
|
||||||
for c in s {
|
for c in s {
|
||||||
@ -415,8 +415,7 @@ pub fn fxx_to_str_l_parse_no_dot(s string) string {
|
|||||||
} else if c == `+` {
|
} else if c == `+` {
|
||||||
sgn = 1
|
sgn = 1
|
||||||
i++
|
i++
|
||||||
}
|
} else if c >= `0` && c <= `9` {
|
||||||
else if c >= `0` && c <= `9` {
|
|
||||||
b[i1] = c
|
b[i1] = c
|
||||||
i1++
|
i1++
|
||||||
i++
|
i++
|
||||||
@ -424,14 +423,14 @@ pub fn fxx_to_str_l_parse_no_dot(s string) string {
|
|||||||
if sgn > 0 {
|
if sgn > 0 {
|
||||||
d_pos = i
|
d_pos = i
|
||||||
} else {
|
} else {
|
||||||
d_pos = i-1
|
d_pos = i - 1
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
} else if c == `e` {
|
} else if c == `e` {
|
||||||
i++
|
i++
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
return "Float conversion error!!"
|
return 'Float conversion error!!'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b[i1] = 0
|
b[i1] = 0
|
||||||
@ -447,16 +446,16 @@ pub fn fxx_to_str_l_parse_no_dot(s string) string {
|
|||||||
|
|
||||||
mut c := i
|
mut c := i
|
||||||
for c < s.len {
|
for c < s.len {
|
||||||
exp = exp * 10 + int(s[c]-`0`)
|
exp = exp * 10 + int(s[c] - `0`)
|
||||||
c++
|
c++
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate exp+32 chars for the return string
|
// 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
|
mut r_i := 0 // result string buffer index
|
||||||
|
|
||||||
|
// println("s:${sgn} b:${b[0]} es:${exp_sgn} exp:${exp}")
|
||||||
|
|
||||||
//println("s:${sgn} b:${b[0]} es:${exp_sgn} exp:${exp}")
|
|
||||||
|
|
||||||
if sgn == 1 {
|
if sgn == 1 {
|
||||||
if m_sgn_flag {
|
if m_sgn_flag {
|
||||||
res[r_i] = `+`
|
res[r_i] = `+`
|
||||||
@ -492,7 +491,7 @@ pub fn fxx_to_str_l_parse_no_dot(s string) string {
|
|||||||
res[r_i] = `0`
|
res[r_i] = `0`
|
||||||
r_i++
|
r_i++
|
||||||
exp--
|
exp--
|
||||||
if dot_p {
|
if dot_p {
|
||||||
res[r_i] = `.`
|
res[r_i] = `.`
|
||||||
r_i++
|
r_i++
|
||||||
dot_p = false
|
dot_p = false
|
||||||
@ -506,12 +505,12 @@ pub fn fxx_to_str_l_parse_no_dot(s string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// remove the dot form the numbers like 2.
|
// remove the dot form the numbers like 2.
|
||||||
if r_i > 1 && res[r_i-1] == `.` {
|
if r_i > 1 && res[r_i - 1] == `.` {
|
||||||
r_i--
|
r_i--
|
||||||
}
|
}
|
||||||
|
|
||||||
res[r_i] = 0
|
res[r_i] = 0
|
||||||
return unsafe { tos(res.data,r_i) }
|
return unsafe { tos(res.data, r_i) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// dec_digits return the number of decimal digit of an u64
|
// dec_digits return the number of decimal digit of an u64
|
||||||
@ -538,12 +537,12 @@ pub fn dec_digits(n u64) int {
|
|||||||
} else {
|
} else {
|
||||||
if n <= 9_999_999 { // 7
|
if n <= 9_999_999 { // 7
|
||||||
if n <= 999_999 { // 6
|
if n <= 999_999 { // 6
|
||||||
return 6
|
return 6
|
||||||
} else {
|
} else {
|
||||||
return 7
|
return 7
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if n <= 99_999_999 { //8
|
if n <= 99_999_999 { // 8
|
||||||
return 8
|
return 8
|
||||||
} else {
|
} else {
|
||||||
if n <= 999_999_999 { // 9
|
if n <= 999_999_999 { // 9
|
||||||
@ -575,12 +574,12 @@ pub fn dec_digits(n u64) int {
|
|||||||
} else {
|
} else {
|
||||||
if n <= 99_999_999_999_999_999 { // 7
|
if n <= 99_999_999_999_999_999 { // 7
|
||||||
if n <= 9_999_999_999_999_999 { // 6
|
if n <= 9_999_999_999_999_999 { // 6
|
||||||
return 16
|
return 16
|
||||||
} else {
|
} else {
|
||||||
return 17
|
return 17
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if n <= 999_999_999_999_999_999 { //8
|
if n <= 999_999_999_999_999_999 { // 8
|
||||||
return 18
|
return 18
|
||||||
} else {
|
} else {
|
||||||
if n <= 9_999_999_999_999_999_999 { // 9
|
if n <= 9_999_999_999_999_999_999 { // 9
|
||||||
@ -590,5 +589,5 @@ pub fn dec_digits(n u64) int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ that can be found in the LICENSE file.
|
|||||||
This file contains string interpolation V functions
|
This file contains string interpolation V functions
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
module strconv
|
module strconv
|
||||||
|
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
enum Char_parse_state {
|
enum Char_parse_state {
|
||||||
@ -15,42 +16,40 @@ enum Char_parse_state {
|
|||||||
pad_ch
|
pad_ch
|
||||||
len_set_start
|
len_set_start
|
||||||
len_set_in
|
len_set_in
|
||||||
|
|
||||||
check_type
|
check_type
|
||||||
check_float
|
check_float
|
||||||
check_float_in
|
check_float_in
|
||||||
|
|
||||||
reset_params
|
reset_params
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn v_printf(str string, pt ... voidptr) {
|
pub fn v_printf(str string, pt ...voidptr) {
|
||||||
print(v_sprintf(str, pt))
|
print(v_sprintf(str, pt))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn v_sprintf(str string, pt ... voidptr) string{
|
pub fn v_sprintf(str string, pt ...voidptr) string {
|
||||||
mut res := strings.new_builder(pt.len * 16)
|
mut res := strings.new_builder(pt.len * 16)
|
||||||
|
|
||||||
mut i := 0 // main string index
|
mut i := 0 // main string index
|
||||||
mut p_index := 0 // parameter index
|
mut p_index := 0 // parameter index
|
||||||
mut sign := false // sign flag
|
mut sign := false // sign flag
|
||||||
mut allign := Align_text.right
|
mut allign := Align_text.right
|
||||||
mut len0 := -1 // forced length, if -1 free length
|
mut len0 := -1 // forced length, if -1 free length
|
||||||
mut len1 := -1 // decimal part for floats
|
mut len1 := -1 // decimal part for floats
|
||||||
def_len1 := 6 // default value for len1
|
def_len1 := 6 // default value for len1
|
||||||
mut pad_ch := byte(` `) // pad char
|
mut pad_ch := byte(` `) // pad char
|
||||||
|
|
||||||
// prefix chars for Length field
|
// prefix chars for Length field
|
||||||
mut ch1 := `0` // +1 char if present else `0`
|
mut ch1 := `0` // +1 char if present else `0`
|
||||||
mut ch2 := `0` // +2 char if present else `0`
|
mut ch2 := `0` // +2 char if present else `0`
|
||||||
|
|
||||||
mut status := Char_parse_state.norm_char
|
mut status := Char_parse_state.norm_char
|
||||||
for i < str.len {
|
for i < str.len {
|
||||||
if status == .reset_params {
|
if status == .reset_params {
|
||||||
sign = false
|
sign = false
|
||||||
allign = .right
|
allign = .right
|
||||||
len0 = -1
|
len0 = -1
|
||||||
len1 = -1
|
len1 = -1
|
||||||
pad_ch = ` `
|
pad_ch = ` `
|
||||||
status = .norm_char
|
status = .norm_char
|
||||||
ch1 = `0`
|
ch1 = `0`
|
||||||
ch2 = `0`
|
ch2 = `0`
|
||||||
@ -72,7 +71,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
// single char, manage it here
|
// single char, manage it here
|
||||||
if ch == `c` && status == .field_char {
|
if ch == `c` && status == .field_char {
|
||||||
v_sprintf_panic(p_index, pt.len)
|
v_sprintf_panic(p_index, pt.len)
|
||||||
d1 := unsafe {*(&byte(pt[p_index]))}
|
d1 := unsafe { *(&byte(pt[p_index])) }
|
||||||
res.write_b(d1)
|
res.write_b(d1)
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
@ -83,8 +82,8 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
// pointer, manage it here
|
// pointer, manage it here
|
||||||
if ch == `p` && status == .field_char {
|
if ch == `p` && status == .field_char {
|
||||||
v_sprintf_panic(p_index, pt.len)
|
v_sprintf_panic(p_index, pt.len)
|
||||||
res.write_string("0x")
|
res.write_string('0x')
|
||||||
res.write_string(ptr_str(unsafe {pt[p_index]}))
|
res.write_string(ptr_str(unsafe { pt[p_index] }))
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
@ -95,9 +94,9 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
mut fc_ch1 := `0`
|
mut fc_ch1 := `0`
|
||||||
mut fc_ch2 := `0`
|
mut fc_ch2 := `0`
|
||||||
if (i + 1) < str.len {
|
if (i + 1) < str.len {
|
||||||
fc_ch1 = str[i+1]
|
fc_ch1 = str[i + 1]
|
||||||
if (i + 2) < str.len {
|
if (i + 2) < str.len {
|
||||||
fc_ch2 = str[i+2]
|
fc_ch2 = str[i + 2]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ch == `+` {
|
if ch == `+` {
|
||||||
@ -108,13 +107,13 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
allign = .left
|
allign = .left
|
||||||
i++
|
i++
|
||||||
continue
|
continue
|
||||||
} else if ch in [`0`,` `] {
|
} else if ch in [`0`, ` `] {
|
||||||
if allign == .right {
|
if allign == .right {
|
||||||
pad_ch = ch
|
pad_ch = ch
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
continue
|
continue
|
||||||
} else if ch == `'` {
|
} else if ch == `\'` {
|
||||||
i++
|
i++
|
||||||
continue
|
continue
|
||||||
} else if ch == `.` && fc_ch1 >= `1` && fc_ch1 <= `9` {
|
} else if ch == `.` && fc_ch1 >= `1` && fc_ch1 <= `9` {
|
||||||
@ -125,10 +124,10 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
// manage "%.*s" precision field
|
// manage "%.*s" precision field
|
||||||
else if ch == `.` && fc_ch1 == `*` && fc_ch2 == `s` {
|
else if ch == `.` && fc_ch1 == `*` && fc_ch2 == `s` {
|
||||||
v_sprintf_panic(p_index, pt.len)
|
v_sprintf_panic(p_index, pt.len)
|
||||||
len := unsafe {*(&int(pt[p_index]))}
|
len := unsafe { *(&int(pt[p_index])) }
|
||||||
p_index++
|
p_index++
|
||||||
v_sprintf_panic(p_index, pt.len)
|
v_sprintf_panic(p_index, pt.len)
|
||||||
mut s := unsafe {*(&string(pt[p_index]))}
|
mut s := unsafe { *(&string(pt[p_index])) }
|
||||||
s = s[..len]
|
s = s[..len]
|
||||||
p_index++
|
p_index++
|
||||||
res.write_string(s)
|
res.write_string(s)
|
||||||
@ -195,7 +194,6 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if status == .check_type {
|
if status == .check_type {
|
||||||
|
|
||||||
if ch == `l` {
|
if ch == `l` {
|
||||||
if ch1 == `0` {
|
if ch1 == `0` {
|
||||||
ch1 = `l`
|
ch1 = `l`
|
||||||
@ -206,8 +204,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
i++
|
i++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
} else if ch == `h` {
|
||||||
else if ch == `h` {
|
|
||||||
if ch1 == `0` {
|
if ch1 == `0` {
|
||||||
ch1 = `h`
|
ch1 = `h`
|
||||||
i++
|
i++
|
||||||
@ -218,24 +215,23 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// signed integer
|
// signed integer
|
||||||
else if ch in [`d`,`i`] {
|
else if ch in [`d`, `i`] {
|
||||||
mut d1 := u64(0)
|
mut d1 := u64(0)
|
||||||
mut positive := true
|
mut positive := true
|
||||||
|
|
||||||
//println("$ch1 $ch2")
|
// println("$ch1 $ch2")
|
||||||
match ch1 {
|
match ch1 {
|
||||||
// h for 16 bit int
|
// h for 16 bit int
|
||||||
// hh fot 8 bit int
|
// hh fot 8 bit int
|
||||||
`h` {
|
`h` {
|
||||||
if ch2 == `h` {
|
if ch2 == `h` {
|
||||||
v_sprintf_panic(p_index, pt.len)
|
v_sprintf_panic(p_index, pt.len)
|
||||||
x := unsafe {*(&i8(pt[p_index]))}
|
x := unsafe { *(&i8(pt[p_index])) }
|
||||||
positive = if x >= 0 { true } else { false }
|
positive = if x >= 0 { true } else { false }
|
||||||
d1 = if positive { u64(x) } else { u64(-x) }
|
d1 = if positive { u64(x) } else { u64(-x) }
|
||||||
} else {
|
} else {
|
||||||
x := unsafe {*(&i16(pt[p_index]))}
|
x := unsafe { *(&i16(pt[p_index])) }
|
||||||
positive = if x >= 0 { true } else { false }
|
positive = if x >= 0 { true } else { false }
|
||||||
d1 = if positive { u64(x) } else { u64(-x) }
|
d1 = if positive { u64(x) } else { u64(-x) }
|
||||||
}
|
}
|
||||||
@ -258,20 +254,26 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
v_sprintf_panic(p_index, pt.len)
|
v_sprintf_panic(p_index, pt.len)
|
||||||
x := unsafe {*(&i64(pt[p_index]))}
|
x := unsafe { *(&i64(pt[p_index])) }
|
||||||
positive = if x >= 0 { true } else { false }
|
positive = if x >= 0 { true } else { false }
|
||||||
d1 = if positive { u64(x) } else { u64(-x) }
|
d1 = if positive { u64(x) } else { u64(-x) }
|
||||||
}
|
}
|
||||||
// default int
|
// default int
|
||||||
else {
|
else {
|
||||||
v_sprintf_panic(p_index, pt.len)
|
v_sprintf_panic(p_index, pt.len)
|
||||||
x := unsafe {*(&int(pt[p_index]))}
|
x := unsafe { *(&int(pt[p_index])) }
|
||||||
positive = if x >= 0 { true } else { false }
|
positive = if x >= 0 { true } else { false }
|
||||||
d1 = if positive { u64(x) } else { u64(-x) }
|
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
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
@ -279,7 +281,6 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
ch2 = `0`
|
ch2 = `0`
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// unsigned integer
|
// unsigned integer
|
||||||
else if ch == `u` {
|
else if ch == `u` {
|
||||||
mut d1 := u64(0)
|
mut d1 := u64(0)
|
||||||
@ -290,9 +291,9 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
// hh fot 8 bit unsigned int
|
// hh fot 8 bit unsigned int
|
||||||
`h` {
|
`h` {
|
||||||
if ch2 == `h` {
|
if ch2 == `h` {
|
||||||
d1 = u64(unsafe {*(&byte(pt[p_index]))})
|
d1 = u64(unsafe { *(&byte(pt[p_index])) })
|
||||||
} else {
|
} else {
|
||||||
d1 = u64(unsafe {*(&u16(pt[p_index]))})
|
d1 = u64(unsafe { *(&u16(pt[p_index])) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// l u64
|
// l u64
|
||||||
@ -306,34 +307,40 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
d1 = u64(*(&u64(pt[p_index])))
|
d1 = u64(*(&u64(pt[p_index])))
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
d1 = u64(unsafe {*(&u64(pt[p_index]))})
|
d1 = u64(unsafe { *(&u64(pt[p_index])) })
|
||||||
}
|
}
|
||||||
// default int
|
// default int
|
||||||
else {
|
else {
|
||||||
d1 = u64(unsafe {*(&u32(pt[p_index]))})
|
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}))
|
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
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// hex
|
// hex
|
||||||
else if ch in [`x`, `X`] {
|
else if ch in [`x`, `X`] {
|
||||||
v_sprintf_panic(p_index, pt.len)
|
v_sprintf_panic(p_index, pt.len)
|
||||||
mut s := ""
|
mut s := ''
|
||||||
match ch1 {
|
match ch1 {
|
||||||
// h for 16 bit int
|
// h for 16 bit int
|
||||||
// hh fot 8 bit int
|
// hh fot 8 bit int
|
||||||
`h` {
|
`h` {
|
||||||
if ch2 == `h` {
|
if ch2 == `h` {
|
||||||
x := unsafe {*(&i8(pt[p_index]))}
|
x := unsafe { *(&i8(pt[p_index])) }
|
||||||
s = x.hex()
|
s = x.hex()
|
||||||
} else {
|
} else {
|
||||||
x := unsafe {*(&i16(pt[p_index]))}
|
x := unsafe { *(&i16(pt[p_index])) }
|
||||||
s = x.hex()
|
s = x.hex()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -350,11 +357,11 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
s = x.hex()
|
s = x.hex()
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
x := unsafe {*(&i64(pt[p_index]))}
|
x := unsafe { *(&i64(pt[p_index])) }
|
||||||
s = x.hex()
|
s = x.hex()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x := unsafe {*(&int(pt[p_index]))}
|
x := unsafe { *(&int(pt[p_index])) }
|
||||||
s = x.hex()
|
s = x.hex()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,7 +370,14 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
s = s.to_upper()
|
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
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
@ -373,55 +387,89 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
// float and double
|
// float and double
|
||||||
if ch in [`f`, `F`] {
|
if ch in [`f`, `F`] {
|
||||||
v_sprintf_panic(p_index, pt.len)
|
v_sprintf_panic(p_index, pt.len)
|
||||||
x := unsafe {*(&f64(pt[p_index]))}
|
x := unsafe { *(&f64(pt[p_index])) }
|
||||||
positive := x >= f64(0.0)
|
positive := x >= f64(0.0)
|
||||||
len1 = if len1 >= 0 { len1 } else { def_len1 }
|
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),
|
||||||
res.write_string(if ch == `F` {s.to_upper()} else {s})
|
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
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
continue
|
continue
|
||||||
}
|
} else if ch in [`e`, `E`] {
|
||||||
else if ch in [`e`, `E`] {
|
|
||||||
v_sprintf_panic(p_index, pt.len)
|
v_sprintf_panic(p_index, pt.len)
|
||||||
x := unsafe {*(&f64(pt[p_index]))}
|
x := unsafe { *(&f64(pt[p_index])) }
|
||||||
positive := x >= f64(0.0)
|
positive := x >= f64(0.0)
|
||||||
len1 = if len1 >= 0 { len1 } else { def_len1 }
|
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),
|
||||||
res.write_string(if ch == `E` {s.to_upper()} else {s})
|
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
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
continue
|
continue
|
||||||
}
|
} else if ch in [`g`, `G`] {
|
||||||
else if ch in [`g`, `G`] {
|
|
||||||
v_sprintf_panic(p_index, pt.len)
|
v_sprintf_panic(p_index, pt.len)
|
||||||
x := unsafe {*(&f64(pt[p_index]))}
|
x := unsafe { *(&f64(pt[p_index])) }
|
||||||
positive := x >= f64(0.0)
|
positive := x >= f64(0.0)
|
||||||
mut s := ""
|
mut s := ''
|
||||||
tx := fabs(x)
|
tx := fabs(x)
|
||||||
if tx < 999_999.0 && tx >= 0.00001 {
|
if tx < 999_999.0 && tx >= 0.00001 {
|
||||||
//println("Here g format_fl [$tx]")
|
// println("Here g format_fl [$tx]")
|
||||||
len1 = if len1 >= 0 { len1+1 } else { def_len1 }
|
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 {
|
} else {
|
||||||
len1 = if len1 >= 0 { len1+1 } else { def_len1 }
|
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})
|
res.write_string(if ch == `G` { s.to_upper() } else { s })
|
||||||
status = .reset_params
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// string
|
// string
|
||||||
else if ch == `s` {
|
else if ch == `s` {
|
||||||
v_sprintf_panic(p_index, pt.len)
|
v_sprintf_panic(p_index, pt.len)
|
||||||
s1 := unsafe{*(&string(pt[p_index]))}
|
s1 := unsafe { *(&string(pt[p_index])) }
|
||||||
pad_ch = ` `
|
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
|
status = .reset_params
|
||||||
p_index++
|
p_index++
|
||||||
i++
|
i++
|
||||||
@ -435,7 +483,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if p_index != pt.len {
|
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()
|
return res.str()
|
||||||
@ -444,7 +492,7 @@ pub fn v_sprintf(str string, pt ... voidptr) string{
|
|||||||
[inline]
|
[inline]
|
||||||
fn v_sprintf_panic(idx int, len int) {
|
fn v_sprintf_panic(idx int, len int) {
|
||||||
if idx >= len {
|
if idx >= len {
|
||||||
panic('${idx+1} % conversion specifiers, but given only ${len} args')
|
panic('${idx + 1} % conversion specifiers, but given only $len args')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,12 +506,12 @@ fn fabs(x f64) f64 {
|
|||||||
// strings.Builder version of format_fl
|
// strings.Builder version of format_fl
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn format_fl_old(f f64, p BF_param) string {
|
pub fn format_fl_old(f f64, p BF_param) string {
|
||||||
unsafe{
|
unsafe {
|
||||||
mut s := ""
|
mut s := ''
|
||||||
//mut fs := "1.2343"
|
// mut fs := "1.2343"
|
||||||
mut fs := f64_to_str_lnd1(if f >= 0.0 {f} else {-f}, p.len1)
|
mut fs := f64_to_str_lnd1(if f >= 0.0 { f } else { -f }, p.len1)
|
||||||
//println("Dario")
|
// println("Dario")
|
||||||
//println(fs)
|
// println(fs)
|
||||||
|
|
||||||
// error!!
|
// error!!
|
||||||
if fs[0] == `[` {
|
if fs[0] == `[` {
|
||||||
@ -476,7 +524,7 @@ pub fn format_fl_old(f f64, p BF_param) string {
|
|||||||
fs = remove_tail_zeros_old(fs)
|
fs = remove_tail_zeros_old(fs)
|
||||||
tmp.free()
|
tmp.free()
|
||||||
}
|
}
|
||||||
mut res := strings.new_builder( if p.len0 > fs.len { p.len0 } else { fs.len })
|
mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
|
||||||
|
|
||||||
mut sign_len_diff := 0
|
mut sign_len_diff := 0
|
||||||
if p.pad_ch == `0` {
|
if p.pad_ch == `0` {
|
||||||
@ -496,7 +544,7 @@ pub fn format_fl_old(f f64, p BF_param) string {
|
|||||||
if p.positive {
|
if p.positive {
|
||||||
if p.sign_flag {
|
if p.sign_flag {
|
||||||
tmp := s
|
tmp := s
|
||||||
s = "+" + fs
|
s = '+' + fs
|
||||||
tmp.free()
|
tmp.free()
|
||||||
} else {
|
} else {
|
||||||
tmp := s
|
tmp := s
|
||||||
@ -505,7 +553,7 @@ pub fn format_fl_old(f f64, p BF_param) string {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tmp := s
|
tmp := s
|
||||||
s = "-" + fs
|
s = '-' + fs
|
||||||
tmp.free()
|
tmp.free()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -513,18 +561,17 @@ pub fn format_fl_old(f f64, p BF_param) string {
|
|||||||
dif := p.len0 - s.len + sign_len_diff
|
dif := p.len0 - s.len + sign_len_diff
|
||||||
|
|
||||||
if p.allign == .right {
|
if p.allign == .right {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.write_string(s)
|
res.write_string(s)
|
||||||
if p.allign == .left {
|
if p.allign == .left {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
s.free()
|
s.free()
|
||||||
fs.free()
|
fs.free()
|
||||||
tmp_res := res.str()
|
tmp_res := res.str()
|
||||||
@ -535,13 +582,13 @@ pub fn format_fl_old(f f64, p BF_param) string {
|
|||||||
|
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn format_es_old(f f64, p BF_param) string {
|
pub fn format_es_old(f f64, p BF_param) string {
|
||||||
unsafe{
|
unsafe {
|
||||||
mut s := ""
|
mut s := ''
|
||||||
mut fs := f64_to_str_pad(if f> 0 {f} else {-f},p.len1)
|
mut fs := f64_to_str_pad(if f > 0 { f } else { -f }, p.len1)
|
||||||
if p.rm_tail_zero {
|
if p.rm_tail_zero {
|
||||||
fs = remove_tail_zeros_old(fs)
|
fs = remove_tail_zeros_old(fs)
|
||||||
}
|
}
|
||||||
mut res := strings.new_builder( if p.len0 > fs.len { p.len0 } else { fs.len })
|
mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len })
|
||||||
|
|
||||||
mut sign_len_diff := 0
|
mut sign_len_diff := 0
|
||||||
if p.pad_ch == `0` {
|
if p.pad_ch == `0` {
|
||||||
@ -561,7 +608,7 @@ pub fn format_es_old(f f64, p BF_param) string {
|
|||||||
if p.positive {
|
if p.positive {
|
||||||
if p.sign_flag {
|
if p.sign_flag {
|
||||||
tmp := s
|
tmp := s
|
||||||
s = "+" + fs
|
s = '+' + fs
|
||||||
tmp.free()
|
tmp.free()
|
||||||
} else {
|
} else {
|
||||||
tmp := s
|
tmp := s
|
||||||
@ -570,20 +617,20 @@ pub fn format_es_old(f f64, p BF_param) string {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tmp := s
|
tmp := s
|
||||||
s = "-" + fs
|
s = '-' + fs
|
||||||
tmp.free()
|
tmp.free()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dif := p.len0 - s.len + sign_len_diff
|
dif := p.len0 - s.len + sign_len_diff
|
||||||
if p.allign == .right {
|
if p.allign == .right {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.write_string(s)
|
res.write_string(s)
|
||||||
if p.allign == .left {
|
if p.allign == .left {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -598,16 +645,15 @@ pub fn format_es_old(f f64, p BF_param) string {
|
|||||||
pub fn remove_tail_zeros_old(s string) string {
|
pub fn remove_tail_zeros_old(s string) string {
|
||||||
mut i := 0
|
mut i := 0
|
||||||
mut last_zero_start := -1
|
mut last_zero_start := -1
|
||||||
mut dot_pos := -1
|
mut dot_pos := -1
|
||||||
mut in_decimal := false
|
mut in_decimal := false
|
||||||
mut prev_ch := byte(0)
|
mut prev_ch := byte(0)
|
||||||
for i < s.len {
|
for i < s.len {
|
||||||
ch := unsafe {s.str[i]}
|
ch := unsafe { s.str[i] }
|
||||||
if ch == `.` {
|
if ch == `.` {
|
||||||
in_decimal = true
|
in_decimal = true
|
||||||
dot_pos = i
|
dot_pos = i
|
||||||
}
|
} else if in_decimal {
|
||||||
else if in_decimal {
|
|
||||||
if ch == `0` && prev_ch != `0` {
|
if ch == `0` && prev_ch != `0` {
|
||||||
last_zero_start = i
|
last_zero_start = i
|
||||||
} else if ch >= `1` && ch <= `9` {
|
} else if ch >= `1` && ch <= `9` {
|
||||||
@ -620,25 +666,25 @@ pub fn remove_tail_zeros_old(s string) string {
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
mut tmp := ""
|
mut tmp := ''
|
||||||
if last_zero_start > 0 {
|
if last_zero_start > 0 {
|
||||||
if last_zero_start == dot_pos+1 {
|
if last_zero_start == dot_pos + 1 {
|
||||||
tmp = s[..dot_pos] + s[i..]
|
tmp = s[..dot_pos] + s[i..]
|
||||||
}else {
|
} else {
|
||||||
tmp = s[..last_zero_start] + s[i..]
|
tmp = s[..last_zero_start] + s[i..]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tmp = s
|
tmp = s
|
||||||
}
|
}
|
||||||
if unsafe {tmp.str[tmp.len-1]} == `.` {
|
if unsafe { tmp.str[tmp.len - 1] } == `.` {
|
||||||
return tmp[..tmp.len-1]
|
return tmp[..tmp.len - 1]
|
||||||
}
|
}
|
||||||
return tmp
|
return tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
// max int64 9223372036854775807
|
// max int64 9223372036854775807
|
||||||
pub fn format_dec_old(d u64, p BF_param) string {
|
pub fn format_dec_old(d u64, p BF_param) string {
|
||||||
mut s := ""
|
mut s := ''
|
||||||
mut res := strings.new_builder(20)
|
mut res := strings.new_builder(20)
|
||||||
mut sign_len_diff := 0
|
mut sign_len_diff := 0
|
||||||
if p.pad_ch == `0` {
|
if p.pad_ch == `0` {
|
||||||
@ -655,26 +701,26 @@ pub fn format_dec_old(d u64, p BF_param) string {
|
|||||||
} else {
|
} else {
|
||||||
if p.positive {
|
if p.positive {
|
||||||
if p.sign_flag {
|
if p.sign_flag {
|
||||||
s = "+" + d.str()
|
s = '+' + d.str()
|
||||||
} else {
|
} else {
|
||||||
s = d.str()
|
s = d.str()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s = "-" + d.str()
|
s = '-' + d.str()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dif := p.len0 - s.len + sign_len_diff
|
dif := p.len0 - s.len + sign_len_diff
|
||||||
|
|
||||||
if p.allign == .right {
|
if p.allign == .right {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.write_string(s)
|
res.write_string(s)
|
||||||
if p.allign == .left {
|
if p.allign == .left {
|
||||||
for i1 :=0; i1 < dif; i1++ {
|
for i1 := 0; i1 < dif; i1++ {
|
||||||
res.write_b(p.pad_ch)
|
res.write_b(p.pad_ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res.str()
|
return res.str()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user