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