By Jeroen


2012-07-27 21:03:42 8 Comments

I have a large amount of numeric values y in javascript. I want to group them by rounding them down to the nearest multiple of x and convert the result to a string.

How do I get around the annoying floating point precision?

For example:

0.2 + 0.4 = 0.6000000000000001

Two things I have tried:

>>> y = 1.23456789 
>>> x = 0.2 
>>> parseInt(Math.round(Math.floor(y/x))) * x; 
1.2000000000000002

and:

>>> y = 1.23456789 
>>> x = 0.2 
>>> y - (y % x)
1.2000000000000002

5 comments

@prahaladp 2013-04-09 15:01:55

Check out this link.. It helped me a lot.

http://www.w3schools.com/jsref/jsref_toprecision.asp

The toPrecision(no_of_digits_required) function returns a string so don't forget to use the parseFloat() function to convert to decimal point of required precision.

@prahaladp 2018-03-07 10:30:09

If you happened to be someone who downvoted me for this answer, could you please explain why ? (the solution provided seems to work )

@philipvr 2012-07-27 21:15:47

You could do something like this:

> +(Math.floor(y/x)*x).toFixed(15);
1.2

@Jeroen 2012-07-27 21:25:26

Doesn't work for all combinations y and x.

@dopatraman 2018-08-29 19:48:43

toFixed returns a string

@Rusty Fausak 2012-07-27 21:14:15

From this post: How to deal with floating point number precision in JavaScript?

You have a few options:

  • Use a special datatype for decimals, like decimal.js
  • Format your result to some fixed number of significant digits, like this: (Math.floor(y/x) * x).toFixed(2)
  • Convert all your numbers to integers

@Karl 2014-12-23 15:31:38

"Convert all your numbers to integers", I've wondered about this. As we know, JavaScript has one number type Number, an IEEE 754 float. If that's the case, then why does converting a float to an integer work, (and it does)? Does JavaScript actually have an integer data type that simply isn't accessible via a reserved word?

@rich remer 2015-12-08 05:12:10

IEEE 754 can exactly represent integers up to something like 2^50. So, if you're working within a known range, you can scale your values to take advantage of the 50 bits (or whatever) of precision, instead of wasting the precision normally reserved for large numbers.

@paul23 2017-12-08 02:58:53

@richremer a floating point has the property that the accuracy (for normal values) does not depend on the size. - So whether you convert it to integers (by say multiplying the values with some constant) the accuracy is equal.

@Hamza Alayed 2014-03-19 14:07:47

> var x = 0.1
> var y = 0.2
> var cf = 10
> x * y
0.020000000000000004
> (x * cf) * (y * cf) / (cf * cf)
0.02

Quick solution:

var _cf = (function() {
  function _shift(x) {
    var parts = x.toString().split('.');
    return (parts.length < 2) ? 1 : Math.pow(10, parts[1].length);
  }
  return function() { 
    return Array.prototype.reduce.call(arguments, function (prev, next) { return prev === undefined || next === undefined ? undefined : Math.max(prev, _shift (next)); }, -Infinity);
  };
})();

Math.a = function () {
  var f = _cf.apply(null, arguments); if(f === undefined) return undefined;
  function cb(x, y, i, o) { return x + f * y; }
  return Array.prototype.reduce.call(arguments, cb, 0) / f;
};

Math.s = function (l,r) { var f = _cf(l,r); return (l * f - r * f) / f; };

Math.m = function () {
  var f = _cf.apply(null, arguments);
  function cb(x, y, i, o) { return (x*f) * (y*f) / (f * f); }
  return Array.prototype.reduce.call(arguments, cb, 1);
};

Math.d = function (l,r) { var f = _cf(l,r); return (l * f) / (r * f); };

> Math.m(0.1, 0.2)
0.02

You can check the full explanation here.

@peterh says reinstate Monica 2017-12-04 21:35:11

My pleasure :-)

@peaceLion 2019-04-25 13:19:54

Math.m(0.07, 100) => 7.000000000000002

@whaatt 2012-07-27 21:14:16

Tackling this task, I'd first find the number of decimal places in x, then round y accordingly. I'd use:

y.toFixed(x.toString().split(".")[1].length);

It should convert x to a string, split it over the decimal point, find the length of the right part, and then y.toFixed(length) should round y based on that length.

@Jeroen 2012-07-27 21:26:17

This gets a bit problematic of x is an integer.

Related Questions

Sponsored Content

89 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6168503 View
  • 7693 Score
  • 89 Answer
  • Tags:   javascript arrays

86 Answered Questions

[SOLVED] How do JavaScript closures work?

31 Answered Questions

[SOLVED] Is floating point math broken?

27 Answered Questions

[SOLVED] What does "use strict" do in JavaScript, and what is the reasoning behind it?

41 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

58 Answered Questions

[SOLVED] How do I include a JavaScript file in another JavaScript file?

3 Answered Questions

33 Answered Questions

[SOLVED] For-each over an array in JavaScript?

16 Answered Questions

[SOLVED] Difference between decimal, float and double in .NET?

Sponsored Content