Rounding to the nearest hundredth of a decimal in

2020-08-10 08:13发布

问题:

I'm doing simple math in JavaScript using variables to represent the numbers. Here is an example of my code:

var ones = 0;
var fives = 0;
function results (){
    _fives = (fives * 5);
    var res = (_fives + ones);
    document.innerHTML = res;
}

This isn't the full code but basically I'm having the user enter the amount of bills and coins from 1 cent coins up to $100 bills. The code multiplies the amount of bills to the amount the bill is worth. This is no problem works just fine... For some reason on some of my results it shows a decimal like 1.899999999997 not sure how this is happening.

Is there a way to change this so it round to the nearest hundredth of a decimal?

For example instead of it showing 1.89999999997 it would just show 1.90 in reality this isn't a big issue. This is a personal thing that I can just round it myself however it would be nice to learn how to do this for future reference.

回答1:

UPDATE: MDN actually has a great example of decimal rounding that avoids floating point inaccuracies. Their method can be modified to always round up, based on the OP.


ORIGINAL (SOMEWHAT INCORRECT) ANSWER

//to round to n decimal places
function round(num, places) {
    var multiplier = Math.pow(10, places);
    return Math.round(num * multiplier) / multiplier;
}

EDIT: I didn't read the question completely. Since we're talking currency, we probably want to round it up:

//to round up to two decimal places
function money_round(num) {
    return Math.ceil(num * 100) / 100;
}


回答2:

Actually this method does NOT work in all cases. I'm doing something similar to round a measured value to a certain number of digits.

In my case I have a a mean and standard deviation of a measurement, something like 0.20812345967 +/- 0.0031647859. Now obviously the extra significant digits are meaningless, so I'd like to write it as 0.208 +/- 0.003. When I do the floating point math, I get 0.20800000000000002 +/- 0.003

Usually this rounds correctly, but because base ten decimal numbers sometimes can't be exactly stored in binary, you get crap like this.

Instead, I'm going to look for a string format solution



回答3:

I know that this is likely a day late and a dollar short, but I was also looking for something like this, and this question led me to look into the Math.round functionality

I come up with this which successfully rounds a given value to the nearest 5th, 100th. So 0.07 becomes 0.05. 23.45 becomes 23.45. 1006.32 becomes 1006.30.

<script>
function rounder() {
var exampleInput = $("#inputId").val();
$("#output").html(((Math.round(((Math.round(exampleInput*100)/5)*5)/5)*5)/100).toFixed(2));
}
</script>

Being a novice, I am certain that there is a way to make this code more efficient.



回答4:

This is known problem of JavaScript when you doing something like:

0.1 + 0.5 = 0.600000000001 or 0.599999999998

The solution for this problem is to use one of JavasSript library with fixed precision and rounding modes. You can try big-numbers. Here is code example:

// Initialization
var bn = new BigNumbers({
    precision: 20, // fixed precision 20 digits after decimal separator 
    roundingMode: BigNumbers.RoundingMode.HALF_UP // rounding mode is Half Up
});

var number1 = bn.of('15');
var number2 = bn.of('12');


var divideResult = number1.divide(number2); // result "1.25"
var multiplyResult = divideResult.multiply(1/2); // result "0.625"
var roundingToTwoDecimalResult = multiplyResult.toPrecision(2); // result "0.63"

The JavaScript tutorial for the same



回答5:

Rounding up tool for large decimals. Can be adjust to handle different decimals sizes by assigning 'decimal' a different value.

const roundToWholeNumber = (num, decimal = 100000) => {

    const _roundingHelper = (val, decimalPlace) => {

        return Math.round(val * decimalPlace) / decimalPlace;

    }

    while(decimal > 1){
        num = _roundingHelper(num, decimal)
        decimal = decimal / 10
    }

    return Math.round(num)   
}
roundToWholeNumber(5.44444555)


回答6:

I've actually been dealing with this as I've been working to implement a solution for rounding for a vectors project I am working on. I'm actually surprised this older (2011) javascripter.net resource hasn't made it, particularly as it is using Math.round( // ... mentioned previously.

I've added a bit to it, also make use of .toFixed() (though this will lop off any trailing zeroes, which I am not too worried about, at this stage, personally):


const round = (number, places) => {
   let rounder = '1';

   for (let i = 0; i < places; i++) {
       rounder += '0';
   }

   return (Math.round(number * rounder) / rounder).toFixed(places);
};

I'm sure there is some issue with the above in terms of efficiency or redundancy; but my point is that Math.round() still does what you need it to. Might need to throw a conversion in the above, after the iteration.

It's also a heck of a lot easier to read than some of the other proposed solutions.



回答7:

This is what I personally decided to use in one of the apps I'm working on!

const roundToHundredth = (value) => {
  return Number(value.toFixed(2));
};

console.log(roundToHundredth(1.98723232))
console.log(roundToHundredth(3.14159265359))
console.log(roundToHundredth(2.67528))