mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
ftoa: some fixes for rounding, new functions
This commit is contained in:
parent
b9c0d2d362
commit
34fd148f2f
@ -65,12 +65,18 @@ const(
|
||||
|
||||
// max 46 char
|
||||
// -3.40282346638528859811704183484516925440e+38
|
||||
fn (d Dec32) get_string_32(neg bool, i_n_digit int) string {
|
||||
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)
|
||||
out_len_original := out_len
|
||||
|
||||
mut fw_zeros := 0
|
||||
if pad_digit > out_len {
|
||||
fw_zeros = pad_digit -out_len
|
||||
}
|
||||
|
||||
mut buf := [byte(0)].repeat(out_len + 5 + 1 +1) // sign + mant_len + . + e + e_sign + exp_len(2) + \0
|
||||
mut i := 0
|
||||
|
||||
@ -86,7 +92,7 @@ fn (d Dec32) get_string_32(neg bool, i_n_digit int) string {
|
||||
|
||||
if n_digit < out_len {
|
||||
//println("orig: ${out_len_original}")
|
||||
out += ten_pow_table_32[out_len - n_digit] + 1 // round to up
|
||||
out += ten_pow_table_32[out_len - n_digit - 1] * 5 // round to up
|
||||
out /= ten_pow_table_32[out_len - n_digit]
|
||||
out_len = n_digit
|
||||
}
|
||||
@ -111,6 +117,11 @@ fn (d Dec32) get_string_32(neg bool, i_n_digit int) string {
|
||||
i++
|
||||
}
|
||||
|
||||
for fw_zeros > 0 {
|
||||
buf[i++] = `0`
|
||||
fw_zeros--
|
||||
}
|
||||
|
||||
/*
|
||||
x=0
|
||||
for x<buf.len {
|
||||
@ -341,5 +352,32 @@ pub fn f32_to_str(f f32, n_digit int) string {
|
||||
}
|
||||
|
||||
//println("${d.m} ${d.e}")
|
||||
return d.get_string_32(neg, n_digit)
|
||||
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 := u1.u
|
||||
|
||||
neg := (u>>(mantbits32+expbits32)) != 0
|
||||
mant := u & ((u32(1)<<mantbits32) - u32(1))
|
||||
exp := (u >> mantbits32) & ((u32(1)<<expbits32) - u32(1))
|
||||
|
||||
//println("${neg} ${mant} e ${exp-bias32}")
|
||||
|
||||
// Exit early for easy cases.
|
||||
if (exp == maxexp32) || (exp == 0 && mant == 0) {
|
||||
return get_string_special(neg, exp == 0, mant == 0)
|
||||
}
|
||||
|
||||
mut d, ok := f32_to_decimal_exact_int(mant, exp)
|
||||
if !ok {
|
||||
//println("with exp form")
|
||||
d = f32_to_decimal(mant, exp)
|
||||
}
|
||||
|
||||
//println("${d.m} ${d.e}")
|
||||
return d.get_string_32(neg, n_digit, n_digit)
|
||||
}
|
||||
|
@ -77,13 +77,19 @@ const(
|
||||
maxexp64 = 2047
|
||||
)
|
||||
|
||||
fn (d Dec64) get_string_64(neg bool, i_n_digit int) string {
|
||||
fn (d Dec64) get_string_64(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_64(out)
|
||||
out_len_original := out_len
|
||||
|
||||
mut buf := [byte(0)].repeat(out_len + 6 + 1 +1) // sign + mant_len + . + e + e_sign + exp_len(2) + \0
|
||||
mut fw_zeros := 0
|
||||
if pad_digit > out_len {
|
||||
fw_zeros = pad_digit - out_len
|
||||
}
|
||||
|
||||
mut buf := [byte(0)].repeat(out_len + 6 + 1 +1 + fw_zeros) // sign + mant_len + . + e + e_sign + exp_len(2) + \0
|
||||
mut i := 0
|
||||
|
||||
if neg {
|
||||
@ -96,11 +102,12 @@ fn (d Dec64) get_string_64(neg bool, i_n_digit int) string {
|
||||
disp = 1
|
||||
}
|
||||
|
||||
// rounding last used digit
|
||||
if n_digit < out_len {
|
||||
//println("orig: ${out_len_original}")
|
||||
out += ten_pow_table_64[out_len - n_digit] + 1 // round to up
|
||||
out /= ten_pow_table_64[out_len - n_digit]
|
||||
out += ten_pow_table_64[out_len - n_digit - 1] * 5 // round to up
|
||||
out /= ten_pow_table_64[out_len - n_digit ]
|
||||
out_len = n_digit
|
||||
//println("orig: ${out_len_original} new len: ${out_len}")
|
||||
}
|
||||
|
||||
y := i + out_len
|
||||
@ -123,6 +130,11 @@ fn (d Dec64) get_string_64(neg bool, i_n_digit int) string {
|
||||
i++
|
||||
}
|
||||
|
||||
for fw_zeros > 0 {
|
||||
buf[i++] = `0`
|
||||
fw_zeros--
|
||||
}
|
||||
|
||||
/*
|
||||
x=0
|
||||
for x<buf.len {
|
||||
@ -384,5 +396,30 @@ pub fn f64_to_str(f f64, n_digit int) string {
|
||||
d = f64_to_decimal(mant, exp)
|
||||
}
|
||||
//println("${d.m} ${d.e}")
|
||||
return d.get_string_64(neg, n_digit)
|
||||
return d.get_string_64(neg, n_digit, 0)
|
||||
}
|
||||
|
||||
// f64_to_str return a string in scientific notation with max n_digit after the dot
|
||||
pub fn f64_to_str_pad(f f64, n_digit int) string {
|
||||
mut u1 := Uf64{}
|
||||
u1.f = f
|
||||
u := 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}")
|
||||
|
||||
// Exit early for easy cases.
|
||||
if (exp == maxexp64) || (exp == 0 && mant == 0) {
|
||||
return get_string_special(neg, exp == 0, mant == 0)
|
||||
}
|
||||
|
||||
mut d, ok := f64_to_decimal_exact_int(mant, exp)
|
||||
if !ok {
|
||||
//println("to_decimal")
|
||||
d = f64_to_decimal(mant, exp)
|
||||
}
|
||||
//println("DEBUG: ${d.m} ${d.e}")
|
||||
return d.get_string_64(neg, n_digit, n_digit)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user