Mohsen Alyafei
Mohsen Alyafei

Reputation: 5537

How to limit the rounding of a Float Number to only its “Decimal Part” without affecting its “Whole Part”

I am unable to find any post on stackoverflow that asked or answered this question.

The normal rounding method rounds the “Float Number” as a whole (i.e. both its fraction and whole parts are processed and impacted in the rounding process).

So, normally (rounding up fractions):

   12.9768 Rounded to 3 decimal places is 12.977
           Rounded to 2 decimal places is 12.98
           Rounded to 1 decimal place  is 13.0     <== Whole part also changed
           Rounded to 0 decimal place  is 13       <== Whole part also changed

In the above examples, the whole part is also affected once the fractional part reached a whole number.

This is fine and convenient for almost all situations and is of course what is intended in any standard number rounding method.

However, what I am looking for is rounding (using javascript) of only the fractional part of the number (to the number of places specified) but without affecting the Whole Part of the number, so (the above examples would become):

   12.9768 Rounded to 3 decimal places is 12.977
           Rounded to 2 decimal places is 12.98
           Rounded to 1 decimal place  is 12.9
           Rounded to 0 decimal place  is 12
           Rounded to 7 decimal places is 12.9768000

In the above, the fractional part will be rounded up to whatever required decimal places but the whole portion of the number will not be touched.

Trailing zeros are required so the output format will be a String Type.

This process limits the rounding to the fractional portion of the float number with a limit cap/limit in that the rounding will not carry to the Whole Part; i.e. the maximum fraction will always be 0.999 etc.

A situation that uses this is that in a shop, the price tags need to be shown as USD NN.mm, but whatever the accounting system does as part of the calculations it cannot create a whole number. So if the original purchase price is USD 22.45, and rounding due to any calculations must not cause the USD 22 to become 23. So, it could be anything up to 22.99. This is an example where the fraction is 2 decimals (i.e. in US cents) but if the fraction is not 2, a generic and flexible solution is needed for rounding only the fractional part without touching the whole part.

Thanks.

Upvotes: 1

Views: 260

Answers (4)

Tom Siegel
Tom Siegel

Reputation: 236

Try the following function... It basically cuts everything after the specified decimal place.

function precission(n, count) {
  var indicator = Math.pow(10, count) || 1;

  return ((n * indicator) | 0) / indicator;
}

If you want trailing zeros just use string.padEnd(count, "0")

Update:

var num = 12.9768;

function precission(n, count) {
  var indicator = Math.pow(10, count) || 1;
  var whole = n | 0;
  var decimal = n - whole;
  var rounded = Math.round(decimal * indicator) / indicator;

  return rounded >= 1 ? whole : whole + rounded;
}

console.log(precission(num, 0));
console.log(precission(num, 1)); //prints 12 because otherwise it would have been 13
console.log(precission(num, 2));
console.log(precission(num, 3));
console.log(precission(num, 6));

Is this what you are looking for?

Upvotes: 1

Mohsen Alyafei
Mohsen Alyafei

Reputation: 5537

This flow diagram could be one way to solve it:

enter image description here

Upvotes: 0

chux
chux

Reputation: 153348

Having little javascript experience, I'll try a pseudocode/javascript solution:

function MA_Round(n, precision) {
  // break into whole and fractional parts
  var whole =  Math.trunc(n);
  var frac =  n - whole;

  // Round fraction
  var pow10 = Math.pow(10, precision);
  var rvalue = Math.round(frac*pow10)/pow10;

  // Form limit of highest fractional value and apply
  var limit = 1.0 - 1.0/pow10;
  if (Math.abs(rvalue) > limit) rvalue = limit;

  // Form result
  return whole + rvalue;
}

Upvotes: 0

jitendrajagtap
jitendrajagtap

Reputation: 1

To get the whole number as it is use

 Math.floor(12.9768)

It will give you the whole number which is expected to you, for fractional part fetch as it is or you can do like

Math.floor(12.9768) + ( 12.9768 - Math.floor(12.9768) )

Upvotes: 0

Related Questions