#211150 - 2016-02-29 05:56 PM
Multiplication bug on non-English user locales
|
Flavien
Getting the hang of it
Registered: 1999-07-21
Posts: 95
Loc: Geneva, Switzerland
|
This is a creepy one, I've managed to reproduce with just this one-liner:
? "0.000001024 * 48845580 = " 0.000001024 * 48845580 " (Expected result: 50.01787392)"
I've tested with many versions of KiXtart (from 4.02 to 4.66), on Windows 7 and 10: result is always 0 when the user language is not in English. The system language has no impact.
Workaround: Use a division instead of a multiplication, for example: 48845580 / 976562.5
|
Top
|
|
|
|
#211151 - 2016-02-29 06:17 PM
Re: Multiplication bug on non-English user locales
[Re: Flavien]
|
Allen
KiX Supporter
Registered: 2003-04-19
Posts: 4549
Loc: USA
|
What happens when you simply do the math and set it to a variable?
$value=0.000001024 * 48845580
? "0.000001024 * 48845580 = " + $value + " (Expected result: 50.01787392)"
and it would probably help to keep both numbers as double for the math to be consistent, ie 48845580.0
Edited by Allen (2016-02-29 06:22 PM)
|
Top
|
|
|
|
#211152 - 2016-02-29 06:42 PM
Re: Multiplication bug on non-English user locales
[Re: Allen]
|
Glenn Barnas
KiX Supporter
Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
|
Well, my guess would be that many non-English environments use "," as a decimal point, not the period (.), and that the format is thus invalid. Indeed, when I replace the "." with a "," on my US-English workstation, I get zero as a result, followed by an error (since the comma isn't at all valid here)."0.000001024 * 48845580 = " 0.000001024 * 48845580 " (Expected result: 50.01787392)" ?
"0,000001024 * 48845580 = " 0,000001024 * 48845580 " (Expected result: 50.01787392)" ? You'll have to try this on a non-English system. I tried on a W-7 system and could not get it to work using the "," but it did not fail using the "." either when set to Germany for both Language and Location.
Glenn
_________________________
Actually I am a Rocket Scientist!
|
Top
|
|
|
|
#211153 - 2016-02-29 07:13 PM
Re: Multiplication bug on non-English user locales
[Re: Glenn Barnas]
|
Flavien
Getting the hang of it
Registered: 1999-07-21
Posts: 95
Loc: Geneva, Switzerland
|
This is on a French locale:
? "cdbl(1024 / 1000000000) * 48845580: " cdbl(1024 / 1000000000) * 48845580
? "cdbl(1024) / 1000000000 * 48845580: " cdbl(1024) / 1000000000 * 48845580
? "cdbl(0.000001024) * 48845580: " cdbl(0.000001024) * 48845580
? "0,000001024 * 48845580: " 0,000001024 * 48845580
Result:
cdbl(1024 / 1000000000) * 48845580: 0
cdbl(1024) / 1000000000 * 48845580: 50,01787392
cdbl(0.000001024) * 48845580: 0
0,000001024 * 48845580: 0
ERROR : unexpected command!
Script: C:\Users\...\test.kix
Line : 4
Clearly a bug in KiXtart.
Another workaround is to use cdbl() instead of x.0, and don't do calculation in cdbl().
|
Top
|
|
|
|
#211306 - 2016-04-13 08:30 AM
Re: Multiplication bug on non-English user locales
[Re: Lonkero]
|
Flavien
Getting the hang of it
Registered: 1999-07-21
Posts: 95
Loc: Geneva, Switzerland
|
This problem arises when the user selects a digit separator that is not a dot (.), like a comma (,) as seen in French, Swiss and other European locales.
To make my scripts bullet proof for these non-dot separators, I had to:
1. Convert to double by using divisions, e.g. 6.1 = 61/10:
$windows_7_plus = cdbl(61) / 10
if cdbl(readvalue("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion")) >= $windows_7_plus
;Windows 7 and 2008R2+.
endif
2. Use this function to convert a double to a string:
function cdbl_to_string($cdbl, optional $decimals)
;Convert and round a double-precision floating-point value (cdbl) to a string with a dot (.) as numerical separator.
dim $index, $digit, $string, $decimal_set
$cdbl = round($cdbl, $decimals)
if $decimals > 0
$decimal_set = 0
else
$decimal_set = 1
endif
$string = cstr($cdbl)
;Replace any kind of separator (e.g. comma) with a dot (.).
for $index = len($string) to 1 step -1
dim $digit_ascii, $new_digit
$digit = substr($string, $index, 1)
$digit_ascii = asc(substr($string, $index, 1))
if ($digit_ascii < 48 or $digit_ascii > 57)
if $decimal_set = 0
$new_digit = "."
$decimal_set = 1
endif
else
$new_digit = $digit
endif
$cdbl_to_string = $new_digit + $cdbl_to_string
next
if $decimals > 0 and $decimal_set = 0
$cdbl_to_string = $cdbl_to_string + ".0"
endif
endfunction
|
Top
|
|
|
|
Moderator: ShaneEP, Arend_, Jochen, Radimus, Glenn Barnas, Allen, Ruud van Velsen, Mart
|
0 registered
and 686 anonymous users online.
|
|
|