How to get a fraction from a float number?
Asked Answered
B

11

31

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;
Boleslaw answered 12/1, 2011 at 9:43 Comment(5)
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).Satisfactory
How do you intend to display var f = 0.0145;? 145 or 0145?Establishment
Out of interest what would you want displayed in the case of 0.123456 and 0.1?Straightedge
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?Greenwich
@Richard, Please consider marking the second answer as correct, since it better. ;-)Halliehallman
S
8

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)
Socha answered 12/1, 2011 at 9:49 Comment(5)
What will this return for 0.0000?Boleslaw
@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. :)Straightedge
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.Linoel
When f = 34.56, this will return 5601. If the multiplier is 1000, 561; 100 returns 57.Shandrashandrydan
f % Math.floor(f) is the same as f % 1 except the latter also works on negative numbersNeom
T
106
function frac(f) {
    return f % 1;
}
Torrid answered 14/3, 2013 at 15:53 Comment(9)
this is really cool, but how this works ? can you please explain ?Dietz
@avi, % is the modulo operation, and the remainder of any number divided by one is the fractional component of that number.Suitable
Wondering this is voted up - it doesn't work reliable. a = 34.5697; fracPart = a % 1; alert(fracPart); // 0.5696999999999974Vassallo
for negative and positive numbers, replace the % with f.mod(1), use this function: Number.prototype.mod = function(n) { return ((this%n)+n)%n; }Ecotype
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.Arguello
@Arguello -- 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.Bibby
It may not work as expected, e.g. 730.4583333333321 % 1 gives 0.4583333333321207Edla
@infografnet, that looks like normal error for floating point numbers. they have some surprising characteristics. :)Neom
Fixed some of these errors in a new answer: https://mcmap.net/q/458678/-how-to-get-a-fraction-from-a-float-numberUnlade
L
12

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
Linoel answered 29/1, 2016 at 12:58 Comment(0)
S
8

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)
Socha answered 12/1, 2011 at 9:49 Comment(5)
What will this return for 0.0000?Boleslaw
@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. :)Straightedge
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.Linoel
When f = 34.56, this will return 5601. If the multiplier is 1000, 561; 100 returns 57.Shandrashandrydan
f % Math.floor(f) is the same as f % 1 except the latter also works on negative numbersNeom
C
5

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"
Conjuration answered 15/11, 2017 at 22:53 Comment(0)
U
4

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

Urbas answered 3/9, 2015 at 6:48 Comment(1)
It returns NaN for integers, instead of 0.Kosiur
M
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;
Mcconaghy answered 12/1, 2011 at 9:50 Comment(2)
Nice simple answer except you've given precision to three DP instead of four.Straightedge
It does work for negative numbers, but in a way that's useful for maths rather than for displaying to the user plnkr.co/edit/6rfp7EVFvjJ8z1s2Y0is?p=previewChiliasm
O
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.

Originative answered 29/10, 2012 at 7:8 Comment(1)
This is a great answer, because I really wanted to just get the fractional part (ie 0.xxx)Seng
T
0
var strNumber = f.toString();
var remainder = strNumber.substr(strNumber.indexOf('.') + 1, 4);
remainder = Number(reminder);
Temptation answered 30/8, 2013 at 20:31 Comment(0)
U
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
Unlade answered 10/1, 2023 at 23:41 Comment(0)
C
0
function fractionAsStr(num)
{
  num += '';
  let i = num.indexOf('.'); 
  return (i == -1) ?
    '' : num.substr(i + 1);
}

let numbers = [-2, -1.3768587,
  0, 0.04555, .000555,
  1, 2.3445534];

for (let num of numbers)
  console.log(
    `${num} ➞ '${fractionAsStr(num)}'`);

/*
Output:
"-2 ➞ ''"
"-1.3768587 ➞ '3768587'"
"0 ➞ ''"
"0.04555 ➞ '04555'"
"0.000555 ➞ '000555'"
"1 ➞ ''"
"2.3445534 ➞ '3445534'"
*/
Cardiff answered 7/10, 2023 at 6:31 Comment(0)
S
-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)
Subconscious answered 9/10, 2020 at 8:32 Comment(2)
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)?Smilax
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 : prnt.sc/uw2s9cSubconscious

© 2022 - 2024 — McMap. All rights reserved.