30

I have a floating point number:

var f = 0.1457;

Or:

var f = 4.7005

How do I get just the fraction remainder as integer?

I.e. in the first example I want to get:

var remainder = 1457;

In the second example:

var remainder = 7005;
Richard Knop
  • 81,041
  • 149
  • 392
  • 552
  • Your question is not well-defined. For a fp number, the number of digits after the decimal points depends on how you display it (the actual representation is not in base-10, so must be rounded to be displayed in base-10). – sleske Jan 12 '11 at 09:50
  • 2
    How do you intend to display `var f = 0.0145;`? `145` or `0145`? – Salman A Jan 12 '11 at 09:55
  • 1
    Out of interest what would you want displayed in the case of 0.123456 and 0.1? – Chris Jan 12 '11 at 09:56
  • What are you intending to do with this result? Would you want `1.156479` to give `156479` and `2.12` to give `12`? Is this purely for display purposes? In which case you probably don't want to approach this mathematically. In the examples I give the 1st dp is different in significance by 100000. Or will you always be working to 4dp? – El Ronnoco Jan 12 '11 at 09:57
  • @Richard, Please consider marking the second answer as correct, since it better. ;-) – Ionică Bizău Mar 12 '15 at 20:43

10 Answers10

105
function frac(f) {
    return f % 1;
}
starball
  • 20,030
  • 7
  • 43
  • 238
Martina
  • 1,634
  • 1
  • 10
  • 6
  • 1
    this is really cool, but how this works ? can you please explain ? – avi Oct 29 '13 at 11:55
  • 2
    @avi, `%` is the [modulo operation](http://en.wikipedia.org/wiki/Modulo_operation), and the remainder of any number divided by one is the fractional component of that number. – davetapley Mar 10 '14 at 23:26
  • 2
    Wondering this is voted up - it doesn't work reliable. a = 34.5697; fracPart = a % 1; alert(fracPart); // 0.5696999999999974 – user2345998 Nov 18 '14 at 09:49
  • 1
    for negative and positive numbers, replace the % with f.mod(1), use this function: Number.prototype.mod = function(n) { return ((this%n)+n)%n; } – Marcel Ennix Apr 04 '15 at 19:20
  • 2
    I don't understand why this answer has been upvoted. It doesn't return the requested result, "the fraction remainder as integer." E.g. for 4.7005 it returns 0.7005 instead of 7005. This answer is a good start but isn't correct yet. – LarsH Jan 18 '17 at 18:54
  • 10
    @LarsH -- People are landing on this page from Google looking for obtaining the fraction of a number in JS. The question's details, in this case, are largely irrelevant. – John Weisz Feb 06 '17 at 17:03
  • 1
    It may not work as expected, e.g. 730.4583333333321 % 1 gives 0.4583333333321207 – infografnet Jul 26 '19 at 18:59
  • 2
    @infografnet, that looks like normal error for floating point numbers. they have some surprising characteristics. :) – Gordon Dec 18 '19 at 01:01
  • Fixed some of these errors in a new answer: https://stackoverflow.com/a/75076971/12137312 – lys Jan 10 '23 at 23:43
10

While this is not what most people will want, but TS asked for fract as integer, here it is:

function fract(n){ return Number(String(n).split('.')[1] || 0); }
fract(1.23) // = 23
fract(123) // = 0
fract(0.0008) // = 8
metalim
  • 1,479
  • 1
  • 12
  • 22
6

This will do it (up to the 4 digits that you want, change the multipler (10000) to larger or smaller if you want smaller or larger number):

Math.ceil(((f < 1.0) ? f : (f % Math.floor(f))) * 10000)
Jimmy Chandra
  • 6,472
  • 4
  • 26
  • 38
  • What will this return for 0.0000? – Richard Knop Jan 12 '11 at 09:56
  • @Richard Knop: Should give 0. f will be less than 1.0 so it will just take f and multiply by 10000 which will of course be 0. As far as I can see it does the same as the codenoob's answer but is harder to read. :) – Chris Jan 12 '11 at 10:34
  • 2
    While this solution is what TS wanted, it is not what he asked in the subject, and clearly not what other people coming here will want. – metalim Jan 29 '16 at 12:49
  • When f = 34.56, this will return 5601. If the multiplier is 1000, 561; 100 returns 57. – Dan Marshall Mar 13 '18 at 16:06
  • `f % Math.floor(f)` is the same as `f % 1` except the latter also works on negative numbers – Gordon Dec 18 '19 at 01:03
4

parseInt(parseFloat(amount).toString().split('.')[1], 10)

JJB1980
  • 41
  • 1
3

You can subtract the floor of the number, giving you just the fractional part, and then multiply by 10000, i.e.:

var remainder = (f-Math.floor(f))*10000;
lmirosevic
  • 15,787
  • 13
  • 70
  • 116
  • Nice simple answer except you've given precision to three DP instead of four. – Chris Jan 12 '11 at 09:55
  • 1
    It does work for negative numbers, but in a way that's useful for maths rather than for displaying to the user http://plnkr.co/edit/6rfp7EVFvjJ8z1s2Y0is?p=preview – z0r Oct 27 '14 at 04:49
2

I would argue that, assuming we want to display these values to the user, treating these numbers as strings would be the best approach. This gets round the issue of fractional values such as 0.002.

I came accross this issue when trying to display prices with the cents in superscript.

let price = 23.43; // 23.43
let strPrice = price.toFixed(2) + ''; // "23.43"
let integer = strPrice.split(".")[0] // "23"
let fractional = strPrice.split(".")[1] // "43"
sce8cbm
  • 21
  • 2
1

This also depends on what you want to do with the remainder (as commenters already asked). For instance, if the base number is 1.03, do you want the returned remainder as 3 or 03 -- I mean, do you want it as a number or as a string (for purposes of displaying it to the user). One example would be article price display, where you don't want to conver 03 to 3 (for instance $1.03) where you want to superscript 03.

Next, the problem is with float precision. Consider this:

var price = 1.03;
var frac = (price - Math.floor(price))*100;
// frac = 3.0000000000000027

So you can "solve" this by slicing the string representation without multiplication (and optional zero-padding) in such cases. At the same time, you avoid floating precision issue. Also demonstrated in this jsfiddle.

This post about floating precision might help as well as this one.

Community
  • 1
  • 1
miha
  • 3,287
  • 3
  • 29
  • 44
0
var strNumber = f.toString();
var remainder = strNumber.substr(strNumber.indexOf('.') + 1, 4);
remainder = Number(reminder);
0

Similar method to Martina's answer with a basic modulo operation but solves some of the issues in the comments by returning the same number of decimal places as passed in.

Modifies a method from an answer to a different question on SO which handles the scientific notation for small floats.

Additionally allows the fractional part to be returned as an integer (ie OP's request).

function sfract(n, toInt) {
    toInt = false || toInt;
    let dec = n.toString().split('e-');
    let places = dec.length > 1
        ? parseInt(dec[1], 10)
        : Math.floor(n) !== n ? dec[0].split('.')[1].length : 0;
    let fract = parseFloat((n%1).toFixed(places));
    return toInt ? fract * Math.pow(10,places) : fract;
};

Tests

function sfract(n, toInt) {
    toInt = false || toInt;
    let dec = n.toString().split('e-');
    let places = dec.length > 1
        ? parseInt(dec[1], 10)
        : Math.floor(n) !== n ? dec[0].split('.')[1].length : 0;
    let fract = parseFloat((n%1).toFixed(places));
    return toInt ? fract * Math.pow(10,places) : fract;
};

console.log(sfract(0.0000005)); // 5e-7
console.log(sfract(0.0000005, true)); // 5
console.log(sfract(4444)); // 0
console.log(sfract(4444, true)); // 0
console.log(sfract(44444.0000005)); // 5e-7
console.log(sfract(44444.00052121, true)); // 52121
console.log(sfract(34.5697)); // 0.5697
console.log(sfract(730.4583333333321, true)); // 4583333333321
lys
  • 949
  • 2
  • 9
  • 33
-2

@Udara Seneviratne

const findFraction = (num) => {

  return parseInt( // 5.---------------- And finally we parses a "string" type and returns an integer
    
    // 1. We convert our parameter "num" to the "string" type (to work as with an array in the next step)
    // result: "1.012312"
    num.toString() 

    // 2. Here we separating the string as an array using the separator: " . "
    // result: ["1", "012312"]
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split
    .split('.')

    // 3. With help a method "Array.splice" we cut the first element of our array
    // result: ["012312"]
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
    .splice(1.1)

    // 4. With help a method "Array.shift" we remove the first element from an array and returns that
    // result: 012312 (But it's still the "string" type)
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift
    .shift()       

  )
}

// Try it
console.log("Result is = " + findFraction (1.012312))
// Type of result
console.log("Type of result = " + typeof findFraction (1.012312))
// Some later operation
console.log("Result + some number is = " + findFraction (1.012312) + 555)
  • Welcome to StackOverflow. Do you mean `.splice(1, 1)` (comma instead of dot) and `(findFraction (1.012312) + 555)` (brackets around this expression so that it is added and not appended)? – fcdt Oct 09 '20 at 09:10
  • Thank you! If I correctly understood you: As for the .splice (1, 1) — that's just the syntax of the Array.splice (arg1, arg2, arg3) method. The comma is just a separator between the arguments. And we crop one element at index-1. This removes "1" in ["1", "012312"]. As for (findFraction (1.012312) + 555) — my mistake. It's working without console.log, but in console.log need to convert a string to the Number type operator, it will work like this: console.log("Result + some number is = " + Number(findFraction (1.012312) + 555)) without console.log : https://prnt.sc/uw2s9c – Jack Kosovskiy Oct 09 '20 at 11:07