I have float numbers like 3.2
and 1.6
.
I need to separate the number into the integer and decimal part. For exampl开发者_JAVA百科e, a value of 3.2
would be split into two numbers, i.e. 3
and 0.2
Getting the integer portion is easy:
n = Math.floor(n);
But I am having trouble getting the decimal portion. I have tried this:
remainder = n % 2; //obtem a parte decimal do rating
But it does not always work correctly.
The previous code has the following output:
n = 3.1 // gives remainder = 1.1
What I am missing here?
Use 1
, not 2
.
js> 2.3 % 1
0.2999999999999998
var decimal = n - Math.floor(n)
Although this won't work for minus numbers so we might have to do
n = Math.abs(n); // Change to positive
var decimal = n - Math.floor(n)
You could convert to string, right?
n = (n + "").split(".");
How is 0.2999999999999998 an acceptable answer? If I were the asker I would want an answer of .3. What we have here is false precision, and my experiments with floor, %, etc indicate that Javascript is fond of false precision for these operations. So I think the answers that are using conversion to string are on the right track.
I would do this:
var decPart = (n+"").split(".")[1];
Specifically, I was using 100233.1 and I wanted the answer ".1".
Here's how I do it, which I think is the most straightforward way to do it:
var x = 3.2;
int_part = Math.trunc(x); // returns 3
float_part = Number((x-int_part).toFixed(2)); // return 0.2
A simple way of doing it is:
var x = 3.2;
var decimals = x - Math.floor(x);
console.log(decimals); //Returns 0.20000000000000018
Unfortunately, that doesn't return the exact value. However, that is easily fixed:
var x = 3.2;
var decimals = x - Math.floor(x);
console.log(decimals.toFixed(1)); //Returns 0.2
You can use this if you don't know the number of decimal places:
var x = 3.2;
var decimals = x - Math.floor(x);
var decimalPlaces = x.toString().split('.')[1].length;
decimals = decimals.toFixed(decimalPlaces);
console.log(decimals); //Returns 0.2
Language independent way:
var a = 3.2;
var fract = a * 10 % 10 /10; //0.2
var integr = a - fract; //3
note that it correct only for numbers with one fractioanal lenght )
You can use parseInt()
function to get the integer part than use that to extract the decimal part
var myNumber = 3.2;
var integerPart = parseInt(myNumber);
var decimalPart = myNumber - integerPart;
Or you could use regex like:
splitFloat = function(n){
const regex = /(\d*)[.,]{1}(\d*)/;
var m;
if ((m = regex.exec(n.toString())) !== null) {
return {
integer:parseInt(m[1]),
decimal:parseFloat(`0.${m[2]}`)
}
}
}
The following works regardless of the regional settings for decimal separator... on the condition only one character is used for a separator.
var n = 2015.15;
var integer = Math.floor(n).toString();
var strungNumber = n.toString();
if (integer.length === strungNumber.length)
return "0";
return strungNumber.substring(integer.length + 1);
It ain't pretty, but it's accurate.
If precision matters and you require consistent results, here are a few propositions that will return the decimal part of any number as a string, including the leading "0.". If you need it as a float, just add var f = parseFloat( result )
in the end.
If the decimal part equals zero, "0.0" will be returned. Null, NaN and undefined numbers are not tested.
1. String.split
var nstring = (n + ""),
narray = nstring.split("."),
result = "0." + ( narray.length > 1 ? narray[1] : "0" );
2. String.substring, String.indexOf
var nstring = (n + ""),
nindex = nstring.indexOf("."),
result = "0." + (nindex > -1 ? nstring.substring(nindex + 1) : "0");
3. Math.floor, Number.toFixed, String.indexOf
var nstring = (n + ""),
nindex = nstring.indexOf("."),
result = ( nindex > -1 ? (n - Math.floor(n)).toFixed(nstring.length - nindex - 1) : "0.0");
4. Math.floor, Number.toFixed, String.split
var nstring = (n + ""),
narray = nstring.split("."),
result = (narray.length > 1 ? (n - Math.floor(n)).toFixed(narray[1].length) : "0.0");
Here is a jsPerf link: https://jsperf.com/decpart-of-number/
We can see that proposition #2 is the fastest.
A good option is to transform the number into a string and then split it.
// Decimal number
let number = 3.2;
// Convert it into a string
let string = number.toString();
// Split the dot
let array = string.split('.');
// Get both numbers
// The '+' sign transforms the string into a number again
let firstNumber = +array[0]; // 3
let secondNumber = +array[1]; // 2
In one line of code
let [firstNumber, secondNumber] = [+number.toString().split('.')[0], +number.toString().split('.')[1]];
Depending the usage you will give afterwards, but this simple solution could also help you.
Im not saying its a good solution, but for some concrete cases works
var a = 10.2
var c = a.toString().split(".")
console.log(c[1] == 2) //True
console.log(c[1] === 2) //False
But it will take longer than the proposed solution by @Brian M. Hunt
(2.3 % 1).toFixed(4)
I am using:
var n = -556.123444444;
var str = n.toString();
var decimalOnly = 0;
if( str.indexOf('.') != -1 ){ //check if has decimal
var decimalOnly = parseFloat(Math.abs(n).toString().split('.')[1]);
}
Input: -556.123444444
Result: 123444444
You could convert it to a string and use the replace
method to replace the integer part with zero, then convert the result back to a number :
var number = 123.123812,
decimals = +number.toString().replace(/^[^\.]+/,'0');
n = Math.floor(x);
remainder = x % 1;
Math functions are faster, but always returns not native expected values. Easiest way that i found is
(3.2+'').replace(/^[-\d]+\./, '')
The best way to avoid mathematical imprecision is to convert to a string, but ensure that it is in the "dot" format you expect by using toLocaleString:
function getDecimals(n) {
// Note that maximumSignificantDigits defaults to 3 so your decimals will be rounded if not changed.
const parts = n.toLocaleString('en-US', { maximumSignificantDigits: 18 }).split('.')
return parts.length > 1 ? Number('0.' + parts[1]) : 0
}
console.log(getDecimals(10.58))
You can simply use parseInt()
function to help, example:
let decimal = 3.2;
let remainder = decimal - parseInt(decimal);
document.write(remainder);
I had a case where I knew all the numbers in question would have only one decimal and wanted to get the decimal portion as an integer so I ended up using this kind of approach:
var number = 3.1,
decimalAsInt = Math.round((number - parseInt(number)) * 10); // returns 1
This works nicely also with integers, returning 0 in those cases.
Although I am very late to answer this, please have a look at the code.
let floatValue = 3.267848;
let decimalDigits = floatValue.toString().split('.')[1];
let decimalPlaces = decimalDigits.length;
let decimalDivider = Math.pow(10, decimalPlaces);
let fractionValue = decimalDigits/decimalDivider;
let integerValue = floatValue - fractionValue;
console.log("Float value: "+floatValue);
console.log("Integer value: "+integerValue);
console.log("Fraction value: "+fractionValue)
I like this answer https://stackoverflow.com/a/4512317/1818723 just need to apply float point fix
function fpFix(n) {
return Math.round(n * 100000000) / 100000000;
}
let decimalPart = 2.3 % 1; //0.2999999999999998
let correct = fpFix(decimalPart); //0.3
Complete function handling negative and positive
function getDecimalPart(decNum) {
return Math.round((decNum % 1) * 100000000) / 100000000;
}
console.log(getDecimalPart(2.3)); // 0.3
console.log(getDecimalPart(-2.3)); // -0.3
console.log(getDecimalPart(2.17247436)); // 0.17247436
P.S. If you are cryptocurrency trading platform developer or banking system developer or any JS developer ;) please apply fpFix everywhere. Thanks!
2021 Update
Optimized version that tackles precision (or not).
// Global variables.
const DEFAULT_PRECISION = 16;
const MAX_CACHED_PRECISION = 20;
// Helper function to avoid numerical imprecision from Math.pow(10, x).
const _pow10 = p => parseFloat(`1e+${p}`);
// Cache precision coefficients, up to a precision of 20 decimal digits.
const PRECISION_COEFS = new Array(MAX_CACHED_PRECISION);
for (let i = 0; i !== MAX_CACHED_PRECISION; ++i) {
PRECISION_COEFS[i] = _pow10(i);
}
// Function to get a power of 10 coefficient,
// optimized for both speed and precision.
const pow10 = p => PRECISION_COEFS[p] || _pow10(p);
// Function to trunc a positive number, optimized for speed.
// See: https://stackoverflow.com/questions/38702724/math-floor-vs-math-trunc-javascript
const trunc = v => (v < 1e8 && ~~v) || Math.trunc(v);
// Helper function to get the decimal part when the number is positive,
// optimized for speed.
// Note: caching 1 / c or 1e-precision still leads to numerical errors.
// So we have to pay the price of the division by c.
const _getDecimals = (v = 0, precision = DEFAULT_PRECISION) => {
const c = pow10(precision); // Get precision coef.
const i = trunc(v); // Get integer.
const d = v - i; // Get decimal.
return Math.round(d * c) / c;
}
// Augmenting Number proto.
Number.prototype.getDecimals = function(precision) {
return (isFinite(this) && (precision ? (
(this < 0 && -_getDecimals(-this, precision))
|| _getDecimals(this, precision)
) : this % 1)) || 0;
}
// Independent function.
const getDecimals = (input, precision) => (isFinite(input) && (
precision ? (
(this < 0 && -_getDecimals(-this, precision))
|| _getDecimals(this, precision)
) : this % 1
)) || 0;
// Tests:
const test = (value, precision) => (
console.log(value, '|', precision, '-->', value.getDecimals(precision))
);
test(1.001 % 1); // --> 0.0009999999999998899
test(1.001 % 1, 16); // --> 0.000999999999999
test(1.001 % 1, 15); // --> 0.001
test(1.001 % 1, 3); // --> 0.001
test(1.001 % 1, 2); // --> 0
test(-1.001 % 1, 16); // --> -0.000999999999999
test(-1.001 % 1, 15); // --> -0.001
test(-1.001 % 1, 3); // --> -0.001
test(-1.001 % 1, 2); // --> 0
After looking at several of these, I am now using...
var rtnValue = Number(7.23);
var tempDec = ((rtnValue / 1) - Math.floor(rtnValue)).toFixed(2);
Floating-point decimal sign and number format can be dependent from country (.,
), so independent solution, which preserved floating point part, is:
getFloatDecimalPortion = function(x) {
x = Math.abs(parseFloat(x));
let n = parseInt(x);
return Number((x - n).toFixed(Math.abs((""+x).length - (""+n).length - 1)));
}
– it is internationalized solution, instead of location-dependent:
getFloatDecimalPortion = x => parseFloat("0." + ((x + "").split(".")[1]));
Solution desription step by step:
parseFloat()
for guaranteeing input cocrrectionMath.abs()
for avoiding problems with negative numbersn = parseInt(x)
for getting decimal partx - n
for substracting decimal part- We have now number with zero decimal part, but JavaScript could give us additional floating part digits, which we do not want
- So, limit additional digits by calling
toFixed()
with count of digits in floating part of original float numberx
. Count is calculated as difference between length of original numberx
and numbern
in their string representation.
This function splits float number into integers and returns it in array:
function splitNumber(num)
{
num = (""+num).match(/^(-?[0-9]+)([,.][0-9]+)?/)||[];
return [ ~~num[1], +(0+num[2])||0 ];
}
console.log(splitNumber(3.02)); // [ 3, 0.2 ]
console.log(splitNumber(123.456)); // [ 123, 0.456 ]
console.log(splitNumber(789)); // [ 789, 0 ]
console.log(splitNumber(-2.7)); // [ -2, 0.7 ]
console.log(splitNumber("test")); // [ 0, 0 ]
You can extend it to only return existing numbers and null
if no number exists:
function splitNumber(num)
{
num = (""+num).match(/^(-?[0-9]+)([,.][0-9]+)?/);
return [ num ? ~~num[1] : null, num && num[2] ? +(0 + num[2]) : null ];
}
console.log(splitNumber(3.02)); // [ 3, 0.02 ]
console.log(splitNumber(123.456)); // [ 123, 0.456 ]
console.log(splitNumber(789)); // [ 789, null ]
console.log(splitNumber(-2.7)); // [ -2, 0.7 ]
console.log(splitNumber("test")); // [ null, null ]
You can also truncate the number
function decimals(val) {
const valStr = val.toString();
const valTruncLength = String(Math.trunc(val)).length;
const dec =
valStr.length != valTruncLength
? valStr.substring(valTruncLength + 1)
: "";
return dec;
}
console.log("decimals: ", decimals(123.654321));
console.log("no decimals: ", decimals(123));
The following function will return an array which will have 2 elements. The first element will be the integer part and the second element will be the decimal part.
function splitNum(num) {
num = num.toString().split('.')
num[0] = Number(num[0])
if (num[1]) num[1] = Number('0.' + num[1])
else num[1] = 0
return num
}
//call this function like this
let num = splitNum(3.2)
console.log(`Integer part is ${num[0]}`)
console.log(`Decimal part is ${num[1]}`)
//or you can call it like this
let [int, deci] = splitNum(3.2)
console.log('Intiger part is ' + int)
console.log('Decimal part is ' + deci)
For example for add two numbers
function add(number1, number2) {
let decimal1 = String(number1).substring(String(number1).indexOf(".") + 1).length;
let decimal2 = String(number2).substring(String(number2).indexOf(".") + 1).length;
let z = Math.max(decimal1, decimal2);
return (number1 * Math.pow(10, z) + number2 * Math.pow(10, z)) / Math.pow(10, z);
}
float a=3.2;
int b=(int)a; // you'll get output b=3 here;
int c=(int)a-b; // you'll get c=.2 value here
精彩评论