mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
strconv: fix float_prec := 1.9999999999999999 + 0.0000000000000000005
being 0.5 (fix #16448) (#16495)
This commit is contained in:
parent
bffe7bd7ab
commit
6cd1723deb
@ -289,7 +289,7 @@ fn converter(mut pn PrepNumber) u64 {
|
|||||||
s0 = q0
|
s0 = q0
|
||||||
pn.exponent++
|
pn.exponent++
|
||||||
}
|
}
|
||||||
// C.printf("mantissa before normalization: %08x%08x%08x binexp: %d \n", s2,s1,s0,binexp)
|
// C.printf(c"mantissa before normalization: %08x%08x%08x binexp: %d \n", s2,s1,s0,binexp)
|
||||||
// normalization, the 28 bit in s2 must the leftest one in the variable
|
// normalization, the 28 bit in s2 must the leftest one in the variable
|
||||||
if s2 != 0 || s1 != 0 || s0 != 0 {
|
if s2 != 0 || s1 != 0 || s0 != 0 {
|
||||||
for (s2 & mask28) == 0 {
|
for (s2 & mask28) == 0 {
|
||||||
@ -333,20 +333,20 @@ fn converter(mut pn PrepNumber) u64 {
|
|||||||
s0=0x0
|
s0=0x0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// C.printf("mantissa before rounding: %08x%08x%08x binexp: %d \n", s2,s1,s0,binexp)
|
// C.printf(c"mantissa before rounding: %08x%08x%08x binexp: %d \n", s2,s1,s0,binexp)
|
||||||
// s1 => 0xFFFFFFxx only F are rapresented
|
// s1 => 0xFFFFFFxx only F are rapresented
|
||||||
nbit := 7
|
nbit := 7
|
||||||
check_round_bit := u32(1) << u32(nbit)
|
check_round_bit := u32(1) << u32(nbit)
|
||||||
check_round_mask := u32(0xFFFFFFFF) << u32(nbit)
|
check_round_mask := u32(0xFFFFFFFF) << u32(nbit)
|
||||||
if (s1 & check_round_bit) != 0 {
|
if (s1 & check_round_bit) != 0 {
|
||||||
// C.printf("need round!! cehck mask: %08x\n", s1 & ~check_round_mask )
|
// C.printf(c"need round!! check mask: %08x\n", s1 & ~check_round_mask )
|
||||||
if (s1 & ~check_round_mask) != 0 {
|
if (s1 & ~check_round_mask) != 0 {
|
||||||
// C.printf("Add 1!\n")
|
// C.printf(c"Add 1!\n")
|
||||||
s2, s1, s0 = add96(s2, s1, s0, 0, check_round_bit, 0)
|
s2, s1, s0 = add96(s2, s1, s0, 0, check_round_bit, 0)
|
||||||
} else {
|
} else {
|
||||||
// C.printf("All 0!\n")
|
// C.printf(c"All 0!\n")
|
||||||
if (s1 & (check_round_bit << u32(1))) != 0 {
|
if (s1 & (check_round_bit << u32(1))) != 0 {
|
||||||
// C.printf("Add 1 form -1 bit control!\n")
|
// C.printf(c"Add 1 form -1 bit control!\n")
|
||||||
s2, s1, s0 = add96(s2, s1, s0, 0, check_round_bit, 0)
|
s2, s1, s0 = add96(s2, s1, s0, 0, check_round_bit, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -354,17 +354,18 @@ fn converter(mut pn PrepNumber) u64 {
|
|||||||
s0 = u32(0)
|
s0 = u32(0)
|
||||||
// recheck normalization
|
// recheck normalization
|
||||||
if s2 & (mask28 << u32(1)) != 0 {
|
if s2 & (mask28 << u32(1)) != 0 {
|
||||||
// C.printf("Renormalize!!")
|
// C.printf(c"Renormalize!!\n")
|
||||||
q2, q1, q0 = lsr96(s2, s1, s0)
|
q2, q1, q0 = lsr96(s2, s1, s0)
|
||||||
binexp--
|
binexp++
|
||||||
|
// dump(binexp)
|
||||||
s2 = q2
|
s2 = q2
|
||||||
s1 = q1
|
s1 = q1
|
||||||
s0 = q0
|
s0 = q0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// tmp := ( u64(s2 & ~mask28) << 24) | ((u64(s1) + u64(128)) >> 8)
|
// tmp := ( u64(s2 & ~mask28) << 24) | ((u64(s1) + u64(128)) >> 8)
|
||||||
// C.printf("mantissa after rounding : %08x%08x%08x binexp: %d \n", s2,s1,s0,binexp)
|
// C.printf(c"mantissa after rounding : %08x %08x %08x binexp: %d \n", s2,s1,s0,binexp)
|
||||||
// C.printf("Tmp result: %016x\n",tmp)
|
// C.printf(c"Tmp result: %016x\n",tmp)
|
||||||
// end rounding
|
// end rounding
|
||||||
// offset the binary exponent IEEE 754
|
// offset the binary exponent IEEE 754
|
||||||
binexp += 1023
|
binexp += 1023
|
||||||
|
30
vlib/strconv/converter_test.v
Normal file
30
vlib/strconv/converter_test.v
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
module main
|
||||||
|
|
||||||
|
fn test_issue_16448() {
|
||||||
|
float_prec := 1.9999999999999999 + 0.0000000000000000005
|
||||||
|
assert float_prec > 1.99
|
||||||
|
assert float_prec < 2.01
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing all the numbers between -100E6..100E6 takes over a minute with clang on i3
|
||||||
|
// while for just -1E5..1E5, it takes less than a second.
|
||||||
|
// const r = i64(100_000_001)
|
||||||
|
// const r = i64(17_000_001)
|
||||||
|
const r = i64(100_001)
|
||||||
|
|
||||||
|
fn test_renormalisation_inside_converter() {
|
||||||
|
for i in -r .. r {
|
||||||
|
s := '${i}.9999999999999999999'
|
||||||
|
fs := s.f64()
|
||||||
|
ifs := i64(fs)
|
||||||
|
if i % 10000 == 0 {
|
||||||
|
eprintln('>>> s: ${s:30s} | fs: ${fs:20.6f} | ifs: ${ifs:20}')
|
||||||
|
}
|
||||||
|
if i < 0 && ifs != i - 1 {
|
||||||
|
panic('invalid negative f64 value, i: ${i} | s: ${s} | fs: ${fs} | ifs: ${ifs}')
|
||||||
|
}
|
||||||
|
if i > 0 && ifs != i + 1 {
|
||||||
|
panic('invalid positive f64 value, i: ${i} | s: ${s} | fs: ${fs} | ifs: ${ifs}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user