JavaScripts :: Miscellaneous :: Converting Binary to Decimal
Programmatic calculation don't always yield the expected result. Especially when dealing with decimal numbers, or monetary calculations. Your initial thoughts may lead you to believe a bug exists in the language you're programing or coding in. In actual fact, it's expected behavior known as binary floating point approximation. Most modern computers process information stored as 1's and 0's, in groups of 8, known as bits, bit units, or binary digits. Humans on the other hand, process information using the decimal numbering system.
In a nutshell, the programing language converts decimal values to binary values so the Computer's processor can understand, then we need to have the binary values converted back to decimal values so humans can understand. You'd think the programing language would do this for us, but it doesn't. Good news is, you've found a solution.
Try these simple calculations in JavaScript :
<script>alert(1.02 + 1.01)</script>
Returns: 2.0300000000000002
<script>alert(3.3 * 3)</script>
Returns: 9.899999999999998
<script>alert(3 * 0.3)</script>
Returns: 0.89999999999999
<script>alert(7 * 9.95)</script>
Returns: 69.64999999999999
Binary values only pose a problem when processing decimals. Integers or whole numbers can be correctly converted and processed. So the simple solution is to convert your decimals to whole numbers by multiplication, then divide the computed result.
Try the same computations above, with this simple decimal to integer solution applied, which cover most, not all, possibilities.
<script>alert(((1.02 * 100) + (1.01 * 100)) / 100)</script>
Returns: 2.03
<script>alert((3.3 * 100) * (3 * 100) / 10000)</script>
Returns: 9.9
<script>alert((3 * 100) * (0.3 * 100) / 10000)</script>
Returns: 0.9
<script>alert(7 * (9.95 * 100) / 100)</script>
Returns: 69.64999999999999
Well, the last one failed to make an impact.
<script>alert(9.95 * 100)</script>
Returns: 994.9999999999999
So here's a slightly more complex script which you can use for monetary calculations. This function takes any number, regardless of decimal places, coverts it to 2 decimal places, then removes the decimal place to emulate multiplying the number by 100. Because no mathematical processing takes place, the number returned will not off by 0.01, nor will it contain an unexpected number of digits. You can then apply your formula to the figure returned and divide the product by 100 to get an accurate result.
<script>
function make100X(n){
n = n.toString();
if(n.search(/\./) >= 0){
stringLength = n.length;
decimalPosi = n.search(/\./);
decimalPosi = stringLength - decimalPosi - 1
if(decimalPosi == 0){
n = n + "00";
} else if(decimalPosi == 1){
n = n + "0";
} else if(decimalPosi > 2){
n = n.substr(0, n.length - decimalPosi + 2);
}
} else {
n = n + "00";
}
return n = n.replace(/\./g, "");
}
alert((7 * make100X(9.95) / 100));
</script>
Returns: 69.65
Of course, some products are returned with only 1 decimal place, which isn't all that great when dealing with monetary figures. So you can use the following functions to convert any figure, be it an integer or a decimal with any number of places.
<script>
function formatAmount(n){
str = String(n);
DECI = new Array();
DECI = str.split(".");
if(DECI[1]){
DECI[1] = DECI[1].substr(0,2);
} else {
DECI[1] = "";
}
if(DECI[1].length == 1){
DECI[1] = DECI[1] + "0";
}
if(DECI[1].length == 0){
DECI[1] = DECI[1] + "00";
}
n = DECI[0] + "." + DECI[1];
return n;
}
alert(formatAmount(80));
alert(formatAmount(80.2));
alert(formatAmount(80.2123478599999));
</script>
Returns:
88.00
88.20
88.21
|