n0minal
n0minal

Reputation: 3223

Javascript Rounding issues

I tried using this:

//var value = "39.99";
//var value = "0.255";
var list = ["39.99", "0.255", "0.306", "0.645", "2.505", "5.726", "9.649", "9.999", "10.01", "0.155", "0.355", "10.05", "14.75", "14.02", "2.405", "14.54","2.485"];


var result;

for( i in list ){
    //result = processRounding(parseFloat(list[i]).toFixed(3));
    //result = parseFloat(list[i]).toFixed(2);
    result = test(parseFloat(list[i]).toFixed(3), 2);
    console.log("RESULT["+i+"]: "+ format("#,##0.00", result));
}

function test(value, precision) {
    var precision = precision || 0,
    neg = value < 0,
    power = Math.pow(10, precision),
    value = Math.round(value * power),
    integral = String((neg ? Math.ceil : Math.floor)(value / power)),
    fraction = String((neg ? -value : value) % power),
    padding = new Array(Math.max(precision - fraction.length, 0) + 1).join('0');

    return precision ? integral + '.' +  padding + fraction : integral;
}


function processRounding (value){
    //console.log( Math.ceil(value*100) + " " +  Math.ceil(value*100) / 2);
    var remainder = parseFloat(value % 1).toFixed(2);
    var floor     = parseInt(Math.floor(value));
    console.log(floor + " " + remainder);
    if(Math.floor(value) != 0 && Math.floor(value) > 10){
        if( parseFloat(remainder) > 0.50 || parseFloat(remainder) > 0.05 ){
            console.log("CEIL");
            value = Math.ceil(value*10)/10;
        }else{
            value = value;
        }          
    }else{
        if( parseFloat(remainder) > 0.50 || parseFloat(remainder) > 0.05 ){
            console.log("ROUND");
            value = Math.round(value*100)/100;
        }else{
            value = value;
        } 
    }

    return value;
}

[jsFiddle here]

But the problem I see is that when the value is something like "2.405" what it does is simple make it "2.40" regardless if I use either the function test or the function processRounding in my jsfiddle example.

Any Ideas on how to make the result into 2.41? Technically It should round up right since the last digit is "5".

UPDATE

using result = test(parseFloat(list[i]).toFixed(3), 2);

var list = ["39.99", "0.255", "0.306", "0.645", "2.505", "5.726", "9.649", "9.999", "10.01", "0.155", "0.355", "10.05", "14.75", "14.02", "2.405", "14.54","2.485"];

would result to this :

RESULT[0]: 39.99
RESULT[1]: 0.26 
RESULT[2]: 0.31 
RESULT[3]: 0.65 
RESULT[4]: 2.51 
RESULT[5]: 5.73 
RESULT[6]: 9.65 
RESULT[7]: 10.00 
RESULT[8]: 10.01 
RESULT[9]: 0.16 
RESULT[10]: 0.36
RESULT[11]: 10.05
RESULT[12]: 14.75
RESULT[13]: 14.02
RESULT[14]: 2.40
RESULT[15]: 14.54
RESULT[16]: 2.49 

Notice that in the list there is a "2.405" value which in the result[14] it is "2.40" it should be in 2.41 right?

Upvotes: 0

Views: 678

Answers (2)

Ben McCormick
Ben McCormick

Reputation: 25728

You're starting off by cutting the remainder off to 2 decimals: parseFloat(value % 1).toFixed(2);

That means when you have 2.405 the remainder is parsed as .40 and it won't be able to differentiate between 2.400 and 2.409

You're going to want to keep the full remainder if you want to round that correctly.

Roger Ng has a good solution. I just wanted to explain why yours has no chance of working from the start.

Upvotes: 0

Roger Ng
Roger Ng

Reputation: 779

I think you wish to have a round off function in JavaScript.

function trueRound(value, digits){
    return (Math.round((value*Math.pow(10,digits)).toFixed(digits-1))/Math.pow(10,digits)).toFixed(digits);
}

Possibly duplicated question: round off decimal using javascript

Upvotes: 3

Related Questions