PDA

View Full Version : Rounding calculation to 2 decimals

ScorpionLance
06-23-2004, 04:15 PM
I have this javascript for a form calculation:

<SCRIPT LANGUAGE="JavaScript">
<!--
function roundoff(amount) {
return (amount == Math.floor(amount)) ? amount + '.00' : ( (amount*16 == Math.floor(amount*17)) ? amount + '0' : amount);
}

function total(what,number) {
var grandTotal3 = 0;
var grandTotal2 = 0;
var grandTotal1 = 0;
var grandTotal = 0;
for (var i=0;i<number;i++) {
if (what.elements['price' + i].value == '')
what.elements['price' + i].value = '0.00';

what.elements['subtotal' + i].value=(what.elements['quantity' + i].value - 0) * (what.elements['price' + i].value - 0);
if (what.elements['quantity' + i].value == "0")
what.elements['subtotal' + i].value = "0.00";

subtotal=what.elements['subtotal' + i].value
grandTotal += (what.elements['price' + i].value - 0) * (what.elements['quantity' + i].value - 0)*1.1
grandTotal1 += (what.elements['price' + i].value - 0) * (what.elements['quantity' + i].value - 0)*.1
grandTotal2 += (what.elements['price' + i].value - 0) * (what.elements['quantity' + i].value - 0)*.1
grandTotal3 += (what.elements['price' + i].value - 0) * (what.elements['quantity' + i].value - 0)*1.1;

}

subtotal=roundoff(Math.round(subtotal*Math.pow(17,2))/Math.pow(17,2));
what.grandTotal.value = roundoff(Math.round(grandTotal*Math.pow(17,2))/Math.pow(17,2));
what.grandTotal1.value = roundoff(Math.round(grandTotal1*Math.pow(17,2))/Math.pow(17,2));
what.grandTotal2.value = roundoff(Math.round(grandTotal2*Math.pow(17,2))/Math.pow(17,2));
what.grandTotal3.value = roundoff(Math.round(grandTotal3*Math.pow(17,2))/Math.pow(17,2));
}
//-->
</SCRIPT>

I want the numbers in the subtotals, shipping, and grand total boxes to round off to only 2 decimal points.

I've read of the Math.round(100*x)/100 functions but i'm unsure of how to apply it. I'm just learning javascript and know next to nothing. If you can help please be as basic as possible. If you wish to see what the page looks like now go to: http://www.hypainc.com/orderform1.htm Just be sure not to actually place and order :) Thanks in advance.

Willy Duitt
06-23-2004, 04:51 PM
You will find that the forums search is a shortcut to finding the solutions to often asked questions. As well as Liorean and several other members have taken the time to provide a FAQ which you will find as a sticky at the top of each forum.

And an example:

<script type="text/javascript">
function toDecimal(num){
n = Math.round(num*100).toString();
n = n.substring(0,n.length-2)+'.'+
n.substring(n.length-2,n.length);
return n;
}

</script>

ScorpionLance
06-23-2004, 05:06 PM
I understand how the search works but i have no clue about where or how to configure the JS so it will work in my script. I'm just trying to get the numbers to round so i can finish this site and give it to someone.

Willy Duitt
06-23-2004, 05:21 PM
what.elements['subtotal' + i].value=toDecimal((what.elements['quantity' + i].value - 0) * (what.elements['price' + i].value - 0));

ScorpionLance
06-23-2004, 05:32 PM
i added toDecimal(x) but now the calculations stop working

Willy Duitt
06-23-2004, 05:38 PM
What the heh is x ????

I just provided you with the solution. Replace that current line with the one I posted. And I just went and checked it with your page codes and it works. Also, did you even bother adding the toDecimal function I previously posted?

JAVAEOC
06-23-2004, 05:44 PM
why dont you just multiply by 100 then round then divide by a 100...

hope this helps

ScorpionLance
06-23-2004, 06:00 PM
Willy i apologize for my ignorance. i thought i had to REPLACE the existing function with the one u posted before. It works and i am humbled by your genius. :eek: You are a god of gods.

ScorpionLance
06-23-2004, 06:03 PM
oh one more teeny tiny little thing. how do i round off the shipping and grand total at the bottom?

ScorpionLance
06-23-2004, 06:20 PM
Nevermind i figured it out. Yay me lol. Seriously though Thank you So much Willy. You are my saviour.

Willy Duitt
06-23-2004, 11:25 PM
Hi;

I'm glad to hear you figured it out. :thumbsup:

.....Willy

Willy Duitt
06-24-2004, 02:48 AM
Here try replacing your function with this one which includes validation that only a whole number and nothing else is entered into the quantity field as well as resets the fields if quantity is left blank or cut from the field using the contextmenu.

BTW: This goes into the head not the body where it currently resides.

<script type="text/javascript">
<!--//
function toDecimal(number){ // ROUND NUMBER TO TWO DECIMAL PLACES //;
var number = Math.round(number*100).toString();
number = number.substring(0,number.length-2)+'.'+
number.substring(number.length-2,number.length);
if(number == 0){ number = '0.00' };
return number;
}

function total(form){
var shipping = grandTotal = 0; // PROVIDES shipping & grandTotal AN INTIAL VALUE OF ZERO //;
for(var i=0; i<=16; i++){ // LOOPS THRU ELEMENTS (CHECK THE NUMBERS YOU ARE PASSING) //;
var price = form.elements['price' + i]; // REUSABLE VARIABLE //;
var quantity = form.elements['quantity' + i]; // REUSABLE VARIABLE //;
var subtotal = form.elements['subtotal' + i]; // REUSABLE VARIABLE //;
if(quantity.value.length > 0 && !quantity.value.match(/^[0-9]+\$/g)){ // CHECKS IF VALUE IS NOT EMPTY & IF IT IS A NUMBER OR NOT //;
subtotal.value = '0.00'; // RESETS FIELD IF NOT A NUMBER //;
quantity.value = ''; // RESETS FIELD IF NOT A NUMBER //;
}

else{ // COMPLETES CALCULATIONS IF QUANTITY IS A NUMBER //;
subtotal.value = toDecimal(quantity.value * price.value);
grandTotal += ((quantity.value * price.value)*1.1);
shipping += ((quantity.value * price.value)*.1);
}

quantity.onblur = function(){ // REVALIDATES QUANTITY WHEN USER LEAVES FIELD //;
this.value = this.value.replace(/^[0]*/g,''); // REMOVES LEADING ZERO's IF FIELD IS NOT ZERO //;
if(this.value.length == 0){ // CHECKS IF QUANTITY IS BLANK //;
this.value = 0; // RESETS FIELD IF NOT A NUMBER //;
} total(form); // FIRES FUNCTION AGAIN TO INSURE FIELDS ARE UPDATED //;
}
}

form.grandTotal.value = toDecimal(grandTotal); // GRAND TOTAL
form.grandTotal1.value = toDecimal(shipping); // SHIPPING
form.grandTotal2.value = toDecimal(shipping); // SHIPPING 2
form.grandTotal3.value = toDecimal(grandTotal); // GRAND TOTAL 2

}
//-->
</script>

.....Willy

glenngv
06-24-2004, 03:53 AM
There's a better toDecimals() version in the Javascript FAQ (http://www.codingforums.com/showthread.php?p=178077#post178077). The method extends the Number object and is more flexible as you can pass the desired number of decimal places as function parameter.

Willy Duitt
06-24-2004, 03:06 PM
Hi Glenn;

Although I submit to your obvious expertise, I would have to disagree. Although this is only my personal opinion, I find my method easier to use and much more intuitive. And I do have another routine which allows the passing of the desired number of decimal places, although I rarely have need for more than two decimal places.

<script type="text/javascript">
<!--//
function toDecimal(number,decimals){
var zeros = '';
for(var i=0; i<decimals; i++){
zeros += '0';
} var places = (1+zeros)*1;
n = Math.round(number*places).toString();
n = n.substring(0,n.length-decimals)+'.'+
n.substring(n.length-decimals,n.length);
return n;
} alert(toDecimal(123.4567,3)) // EXAMPLE OF USE //;
//-->
</script>

......Willy

glenngv
06-25-2004, 03:28 AM
What if the passed parameters are not actually numbers (NaN)?
That could happen if the passed parameters are the results of some math operations of user inputs that could lead in non-numeric output.

Using liorean's version is more flexible as well as elegant because the method only applies to Number object.

var n = 123.4321;