Hello everyone! I'm new here but have been programming for the web in various languages for 15 years or so. I'm certainly no "expert" but can keep myself out of trouble (or in it?) most of the time.
This particular problem has plagued me for years; it is making me very, very, old. :-( It deals with the way Javascript's method of floating point precision takes the simplest math calculations and steals a penny - in the example below, a simple 636.35 is turned into 636.34 (636.34999999999999 !)
I know the truncate function below is not only lame, it turns the number into a string - but that is not the issue, as you can see the problem exists before truncate gets to it, and persists even if it is taken out of the script. I won't bore you will all the various methods I've tried, the most obvious being multiply everything by 100 then divide by 100 at the end - all failed
PLEASE can someone paste and test this code, offer a solution? Just load it, hit calculate, watch the alerts. I'm turning gray by the minute. :-( THANK YOU! -- Bill
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-
<html>
-
<head>
-
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-
<title>Javascript Floating Point Precision Problem</title>
-
</head>
-
-
<body>
-
<h2>Javascript Floating Point Precision Problem</h2>
-
<form name="po_form" id="po_form" onSubmit="return false;">
-
<input type="hidden" name="number_of_items" id="number_of_items" value="3">
-
<table>
-
<tr><td><input type="text" name="pn_1" id="pn_1" size="15" maxlength="20" value="3H00NT" tabindex="18"></td>
-
<td> <input type="text" name="description_1" id="description_1" size="18" maxlength="255" value="Fuser Roller for HP4200DT" tabindex="19"></td>
-
<td><input type="text" onChange="calcForm(this.form);" name="quantity_1" id="quantity_1" size="2" maxlength="12" value="1" tabindex="21"></td>
-
<td> $ <input type="text" onChange="calcForm(this.form);" name="price_1" id="price_1" size="6" maxlength="12" value="540.80" tabindex="22"></td>
-
<td> $ <input type="text" onChange="calcForm(this.form);" name="shipping_1" id="shipping_1" size="6" maxlength="12" value="0.00" tabindex="23"></td>
-
<td> <strong>$</strong> <input type="text" name="subtotal_1" id="subtotal_1" onFocus="blur();" size="6" maxlength="12" value="540.80" tabindex="5018"></td>
-
</tr>
-
<tr><td><input type="text" name="pn_2" id="pn_2" size="15" maxlength="20" value="3H0006" tabindex="24"></td>
-
<td> <input type="text" name="description_2" id="description_2" size="18" maxlength="255" value="Feed Roller" tabindex="25"></td>
-
<td><input type="text" onChange="calcForm(this.form);" name="quantity_2" id="quantity_2" size="2" maxlength="12" value="1" tabindex="27"></td>
-
<td> $ <input type="text" onChange="calcForm(this.form);" name="price_2" id="price_2" size="6" maxlength="12" value="48.75" tabindex="28"></td>
-
<td> $ <input type="text" onChange="calcForm(this.form);" name="shipping_2" id="shipping_2" size="6" maxlength="12" value="0.00" tabindex="29"></td>
-
<td> <strong>$</strong> <input type="text" name="subtotal_2" id="subtotal_2" onFocus="blur();" size="6" maxlength="12" value="48.75" tabindex="5024"></td>
-
</tr>
-
<tr><td><input type="text" name="pn_3" id="pn_3" size="15" maxlength="20" value="3H007B" tabindex="30"></td>
-
<td> <input type="text" name="description_3" id="description_3" size="18" maxlength="255" value="Roller" tabindex="31"></td>
-
<td><input type="text" onChange="calcForm(this.form);" name="quantity_3" id="quantity_3" size="2" maxlength="12" value="1" tabindex="33"></td>
-
<td> $ <input type="text" onChange="calcForm(this.form);" name="price_3" id="price_3" size="6" maxlength="12" value="46.80" tabindex="34"></td>
-
<td> $ <input type="text" onChange="calcForm(this.form);" name="shipping_3" id="shipping_3" size="6" maxlength="12" value="0.00" tabindex="35"></td>
-
<td> <strong>$</strong> <input type="text" name="subtotal_3" id="subtotal_3" onFocus="blur();" size="6" maxlength="12" value="46.80" tabindex="5030"></td>
-
</tr>
-
<tr>
-
<td colspan="4"> </td>
-
<td> TOTAL:</td>
-
<td> <strong>$</strong> <input type="text" name="po_total" id="po_total" onFocus="blur();" size="6" maxlength="12" value="636.34" tabindex="5500"> </td>
-
</tr>
-
<tr><td colspan="6"> <hr width="100%" size="1"></td></tr>
-
<tr>
-
<td><input type="submit" name="addLineItem" id="addLineItem" value="Add New Item" tabindex="2001" onClick="alert('Different function, ignore.'); return false;"></td>
-
<td> </td>
-
<td colspan="4">
-
<input type="button" id="recalcButton" onClick="calcForm(this.form);" value="Recalculate Total" tabindex="2002">
-
<input type="submit" name="submitButton" id="submitButton" onClick="checkForm(this.form); return false;" value="Submit PO" tabindex="2003">
-
</td>
-
</tr>
-
</table>
-
</form>
-
-
<script type="text/javascript">
-
-
function calcForm (form) {
-
-
var subtotal=quan=price=ship=total=0;
-
var sub,cancelled;
-
var tot = document.getElementById('po_total');
-
var num_items = document.getElementById('number_of_items').value;
-
-
for (i=1;i<=num_items;i++) {
-
subtotal = 0;
-
-
sub = document.getElementById('subtotal_' + i);
-
ship = document.getElementById('shipping_' + i);
-
q = document.getElementById('quantity_' + i);
-
p = document.getElementById('price_' + i);
-
subtotal = (q.value * p.value) + (ship.value * 1);
-
total += subtotal;
-
alert(subtotal + ' ' + total);
-
sub.value = truncate(subtotal);
-
-
}
-
tot.value = truncate(total);
-
}
-
-
function checkForm (form) {
-
calcForm(form);
-
alert('various checks, then submit form.');
-
}
-
-
function truncate(num) {
-
string = "" + num;
-
if (string.indexOf('.') == -1)
-
return string + '.00';
-
seperation = string.length - string.indexOf('.');
-
if (seperation > 3)
-
return string.substring(0,string.length-seperation+3);
-
else if (seperation == 2)
-
return string + '0';
-
return string;
-
}
-
</script>
-
-
</body>
-
</html>
-