1

I have this decimal number: 1.12346

I now want to keep only 4 decimals but I want to round down so it will return: 1.1234. Now it returns: 1.1235 which is wrong.

Effectively. I want the last 2 numbers: "46" do round down to "4" and not up to "5"

How is this possible to do?

    var nums = 1.12346;
    nums = MathRound(nums, 4);
    console.log(nums);

function MathRound(num, nrdecimals) {
    return num.toFixed(nrdecimals);
}
Andreas
  • 1,121
  • 4
  • 17
  • 34
  • So you don't want it to round, you want it to cut off. The only reason you would do this is to show it as a string, because otherwise all your maths would be wrong from then on out, so: is the idea that this becomes a string? – Mike 'Pomax' Kamermans Mar 28 '19 at 00:07
  • Yes I want it to round down to: 1.1234 and not 1.1235 like it does now. I want to keep it as a number and not a string. (You are right, in a way it would "cutoff" the other numbers after 4) – Andreas Mar 28 '19 at 00:08
  • To prevent an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem), what are you doing that makes you think you need to cut off numbers after the 4th decimal place? – Mike 'Pomax' Kamermans Mar 28 '19 at 00:10
  • The term "rounding" is not really accurate here because you still want to retain a fractional part. Multiply by 10000, call `Math.floor()`, and then divide by 10000. Note that you will probably still have to call `.toFixed()` because decimal places and binary floating point don't always get along. – Pointy Mar 28 '19 at 00:12

5 Answers5

2

This is the same question as How to round down number 2 decimal places?. You simply need to make the adjustments for additional decimal places.

Math.floor(1.12346 * 10000) / 10000

console.log(Math.floor(1.12346 * 10000) / 10000);

If you want this as a reusable function, you could do:

function MathRound (number, digits) {
  var adjust = Math.pow(10, digits); // or 10 ** digits if you don't need to target IE
  return Math.floor(number * adjust) / adjust;
}

console.log(MathRound(1.12346, 4));
caseyjhol
  • 3,090
  • 2
  • 19
  • 23
  • no need for Math.pow in modern JS, just use `10 ** digits` – Mike 'Pomax' Kamermans Mar 28 '19 at 00:20
  • @Mike'Pomax'Kamermans Good call, but that doesn't work in Internet Explorer. I'll add a comment, though. – caseyjhol Mar 28 '19 at 00:23
  • Like I said: modern JS. Internet explorer only has one supported version, and even that is considered legacy by the company that makes it, with a modern browser made by the same company that replaces it in every OS still supported by that same company. So: unless explicitly specified that it needs to work in IE, best to ignore that IE even still exists in 2019 going forward. – Mike 'Pomax' Kamermans Mar 28 '19 at 00:24
  • Normally I'd agree, but in a case like this where it's only marginally more difficult to type and has similar performance, I'm inclined to use code that works in every browser (especially since, depending on where you look, IE is still the 2nd or 3rd most used desktop browser). – caseyjhol Mar 28 '19 at 00:30
  • Fair enough. I'm more of the "Actively help the world forget IE even exists by only teaching modern JS" inclination, but it's a reasonable argument. – Mike 'Pomax' Kamermans Mar 28 '19 at 00:42
1

If you're doing this because you need to print/show a value, then we don't need to stay in number land: turn it into a string, and chop it up:

let nums = 1.12346;

// take advantage of the fact that
// bit operations cause 32 bit integer conversion
let intPart = (nums|0); 

// then get a number that is _always_ 0.something:
let fraction = nums - intPart ;

// and just cut that off at the known distance.
let chopped = `${fraction}`.substring(2,6);

// then put the integer part back in front.
let finalString = `${intpart}.${chopped}`;

Of course, if you're not doing this for presentation, the question "why do you think you need to do this" (because it invalidates subsequent maths involving this number) should probably be answered first, because helping you do the wrong thing is not actually helping, but making things worse.

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
  • Effectively, I will actually need the number as a number and not a string but it has to be in the format 4 decimals and rounded down for a reason to be accepted by a certain function and be Less than 1.12346 so 4 decimals and that criteria will then be 1.1234. But that seems to work also to chop it off like that. – Andreas Mar 28 '19 at 00:18
  • of course this will work, but then don't do this. Do what @caseyjhol showed. Multiply your number by 10000, floor it, and then divide it by 10000 again. – Mike 'Pomax' Kamermans Mar 28 '19 at 00:19
  • Yes, I actually I try to go with @Bibberty solution which seems to work also? – Andreas Mar 28 '19 at 00:20
  • They both work, but "times, floor, div" keeps it simpler, and keeps the quirks you might still run into (thanks to IEEE float rounding) more obvious. – Mike 'Pomax' Kamermans Mar 28 '19 at 00:21
1

I think this will do the trick. Essentially correcting the round up.

var nums = 1.12346;
    nums = MathRound(nums, 4);
    console.log(nums);

function MathRound(num, nrdecimals) {
    let n = num.toFixed(nrdecimals);
    return (n > num) ? n-(1/(Math.pow(10,nrdecimals))) : n;
}
Bibberty
  • 4,670
  • 2
  • 8
  • 23
  • Yes, that seems to do the trick and it is nice to keep everything in numbers like that. Thank you! – Andreas Mar 28 '19 at 00:16
0

var nums = 1.12346;
var dec = 10E3;
var intnums = Math.floor(nums * dec);
var trim = intnums / dec;
console.log(trim);
rafaelcastrocouto
  • 11,781
  • 3
  • 38
  • 63
0
var num = 1.2323232;
converted_num = num.toFixed(2);  //upto 2 precision points
o/p : "1.23"

To get the float num : 
converted_num = parseFloat(num.toFixed(2));
o/p : 1.23