Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript - how to prevent toFixed from rounding off decimal numbers

I'm very new to html, javascript, and css so please forgive if my question sounds idiotic to you. My question is how can I prevent the function toFixed() from rounding of the decimal number.

Here's my link: http://jsfiddle.net/RWBaA/4/

What I'm trying to do is I'm checking the input if its a valid decimal number whenever the user types in the textbox. At the same time I also want to check if the input is a valid currency which means it can only add two more numbers at the right of the decimal point. The problem is when the user enters the 3rd number after the decimal point the 2nd number after the decimal point is rounded off to the nearest hundredths if the the 3rd number is >= 5.

Test Input :

  Input         Output  
123456.781 -> 123456.78

123456.786 -> 123456.79

Why my code does not allow arrow keys in chrome?

Please help. If you have a better solution you are free to suggest. Thanks in advance.

like image 801
TheOnlyIdiot Avatar asked May 30 '12 00:05

TheOnlyIdiot


People also ask

How do I use toFixed without rounding?

The idea is to convert the number into string (via toString()) and use the RegExp to truncate the extra zeros (without rounding). Next, we find out the position of decimal dot (if any), and pad up the zeros for exactly n decimal places.

Does JavaScript toFixed round?

Note. The toFixed() method will round the resulting value if necessary. The toFixed() method will pad the resulting value with 0's if there are not enough decimal places in the original number. The toFixed() method does not change the value of the original number.

Does toFixed round or truncate?

The toFixed() method converts a number to a string. The toFixed() method rounds the string to a specified number of decimals.

Does toFixed round down?

toFixed is rounding them down. toFixed returns a string.


4 Answers

That's even simpler:

function truncateToDecimals(num, dec = 2) {
  const calcDec = Math.pow(10, dec);
  return Math.trunc(num * calcDec) / calcDec;
}

So:

truncateToDecimals(123456.786) -> 123456.78
like image 188
David Avatar answered Oct 21 '22 07:10

David


Round the number (down) to the nearest cent first:

val = Math.floor(100 * val) / 100;

EDIT It's been pointed out that this fails for e.g. 1.13. I should have known better myself!

This fails because the internal floating point representation of 1.13 is very slightly less than 1.13 - multiplying that by 100 doesn't produce 113 but 112.99999999999998578915 and then rounding that down takes it to 1.12

Having re-read the question, it seems that you're really only trying to perform input validation (see below), in which case you should use normal form validation techniques and you shouldn't use .toFixed() at all. That function is for presenting numbers, not calculating with them.

$('#txtAmount').on('keypress', function (e) {
    var k = String.fromCharCode(e.charCode);
    var v = this.value;
    var dp = v.indexOf('.');

    // reject illegal chars
    if ((k < '0' || k > '9') && k !== '.') return false;

    // reject any input that takes the length
    // two or more beyond the decimal point
    if (dp >= 0 && v.length > dp + 2) {
        return false;
    }

    // don't accept >1 decimal point, or as first char
    if (k === '.' && (dp >= 0 || v.length === 0)) {
        return false;
    }
});
like image 35
Alnitak Avatar answered Oct 21 '22 08:10

Alnitak


you can give this a try, it won't round your decimals

/**
 * @param {any} input 
 * @param {number} decimals 
 */
var toFixed = function(input, decimals) {
  var arr = ("" + input).split(".");
  if (arr.length === 1) return input;
  var int = arr[0],
      max = arr[1].length,
      dec = arr[1].substr(0, decimals > max ? max : decimals);
  return decimals === 0 ? int : [int, "." , dec].join("");
}
like image 7
Santiago Hernández Avatar answered Oct 21 '22 09:10

Santiago Hernández


Additionally, to prevent toFixed() from rounding off decimal numbers and to make your number into two decimal places you can use this,

val = (Math.floor(100 * val) / 100).toFixed(2);
like image 5
Quiams Avatar answered Oct 21 '22 09:10

Quiams