Numbers and toFixed, toPrecision in Javascript?

Regarding the well-known problem 1.01+1.02 , which is 2.0300000000000002

one way is to use toFixed : for example,

 (1.01+1.02).toFixed(2) --->"2.03" 

But I saw a solution with toPrecision

 parseFloat((1.01+1.02).toPrecision(10))-->"2.03" 

But let's take a look at n in

  • toFixed(n)

  • toPrecision(n)

How do I know what n is?

  0.xxxxxxxxxxx + 0.yyyyyyyyyyyyy --------------------- 0.zzzzzzzzzzzzzzzzzzzzzzzzz ^ | -----??????------ 

each added number may have different decimal digits ...

eg:

1.0002+1.01+1.03333 โ†’ 3.0435300000000005

how would i calculate n here? What is the best practice for this (specific) problem?

+4
source share
4 answers

This returns the expected result:

 function add(){ // Initialize output and "length" properties var length = 0; var output = 0; // Loop through all arguments supplied to this function (So: 1,4,6 in case of add(1,4,6);) for(var i = 0; i < arguments.length; i++){ // If the current argument length as string is longer than the previous one (or greater than 0 in case of the first argument)) if(arguments[0].toString().length > length){ // Set the current length to the argument length (+1 is to account for the decimal point taking 1 character.) length = arguments[0].toString().length +1; } // Add the current character to the output with a precision specified by the longest argument. output = parseFloat((output+arguments[i]).toPrecision(length)); } // Do whatever you with with the result, here. Usually, you'd 'return output;' console.log(output); } add(); // Returns 0 add(1,2,3); // Returns 6 add(1.01,2.01,3.03); // Returns 6.05 add(1.01,2.0213,3.3333); // Returns 6.3646 add(11.01,2.0213,31.3333); // Returns 44.3646 

parseFloat even gets rid of parseFloat zero for you.

This function takes as many numbers as you want, and then adds them together, taking the string length of the numbers into account when adding them. The precision used in the addition is dynamically modified to match the โ€œcurrently addedโ€ argument length.

Fiddle

0
source

To add, as in this situation, I would check the number of decimal places in each operand.

In the simplest of situations, the number of decimal places in the operand with the largest number of decimal places is the value n.

Once you have this, use any method you want to trim. Then get rid of trailing zeros.

You may encounter trailing zeros in situations like 1.06 + 1.04, the first step will lead you to 1.10, then truncating the zero will give 1.1

In your last example, 1.0002 + 1.01 + 1.03333 the largest number of decimal places is 5, so you are left with 3.04353 and there are no zeros to truncate.

+1
source

If you are doing the calculations, you have several options:

  • multiply numbers by 100 to convert them to integers, then do the calculations, then convert again
  • do the calculations, don't worry about rounding errors, then round the result while displaying

If you are dealing with money / currencies, the first option is probably not a bad option. If you are just doing scientific math, I personally wonโ€™t worry about it and simply round off the results during the display, for example, to 6 significant digits, which are standard for my C ++ compiler (gcc; not sure if it is in C + + standards or not, but if you print 1.234567890 in gcc C ++, then output 1.23457 , and the problem is fixed)

0
source
 var a = 216.57421; a.toPrecision(1); // => '200' because 216 with 1 < 5; a.toPrecision(2); // => '220' because 216 with 6 >= 5; a.toFixed(1); // => 216.6 because 7 >= 5; a.toFixed(2); // => 216.57 because 4 < 5; 
0
source

All Articles