使用JavaScript获取数字的小数部分


247

我有类似3.2和的浮点数1.6

我需要将数字分成整数和小数部分。例如,的值3.2将被分为两个数字,即30.2

获取整数部分很容易:

n = Math.floor(n);

但是我在获取小数部分时遇到了麻烦。我已经试过了:

remainer = n % 2; //obtem a parte decimal do rating

但是它并不总是能正常工作。

先前的代码具有以下输出:

n = 3.1 => remainer = 1.1

我在这里想念的是什么?


1
请注意,这n = Math.floor(n);仅返回非负数的期望结果(整数部分)
tsemer

Simplfy使用% 1% 2
masterxilo

Answers:


367

使用1,而不是2

js> 2.3 % 1
0.2999999999999998

59
在0.2999999999999998等于0.3的世界中,这是可以接受的。对我而言,不是...因此,为了解决这一难题,我将避免使用Math.*%操作。
MarcelStör14年

62
为了避免出现浮点舍入问题,toFixed在某些情况下使用可能会有所帮助,例如(2.3 % 1).toFixed(4)== "0.3000"
Brian M. Hunt 2014年

12
(2.3 % 1).toFixed(4).substring(2)= "3000"如果您需要它而无需0.
Simon_Weaver

14
在当今世界,数字2.3出现了,而不是23,数量0.2999999999999998是多么不顾侮辱它看起来对人眼完全可以接受的。
Gershom

1
@GershomMaes在许多情况下,该数字是不可接受的。
亚当·莱格特

92
var decimal = n - Math.floor(n)

尽管这对负数无效,所以我们可能不得不这样做

n = Math.abs(n); // Change to positive
var decimal = n - Math.floor(n)

如果您已经有了整数部分,则无需Math.floor()再次调用-只需使用您计算出的整数部分即可。
tvanfosson

4
var n = 3.2, integr = Math.floor(n), decimal = n - integr;使用Math.floor()只有一次。 integr = 3; decimal = 0.20000000000000018;
Nurlan '16

2
为了使用负数,只需Math.floor与交换Math.trunc
伊戈尔·席尔瓦

这返回的是一个不精确的数字,例如我期望从100.80获得0.80,而不是0.79999 ...我通过添加decimal.toFixed(2)
Luis Febro

76

您可以转换为字符串,对吗?

n = (n + "").split(".");

17
这在除欧洲大陆以外的所有地方都可以正常使用,在欧洲大陆中,逗号是小数点分隔符。如果您打算使用此解决方案,请记住,如果您是跨国公司并且针对欧洲,则要考虑到这一点,因为此解决方案对他们来说做得不好。
cdmdotnet

8
我来自欧洲大陆,使用法国Firefox,它可以正常工作。通常,在法国,我们将逗号用作小数点分隔符。原因是在JavaScript中,将Number转换为字符串时不涉及文化,尽管我宁愿使用n.toString()代替,n + ""因为它更易读。
加百利Hautclocq

2
如果速度是至关重要的则n + ""是确实比较好(见jsperf.com/number-vs-number-tostring-vs-string-number
加布里埃尔Hautclocq

@cdmdotnet JS .用作小数点分隔符,因此,如果输入变量的类型为float,则可以在任何地方使用。如果您输入的是字符串,则只需处理该问题。我还必须注意,此答案返回数组中的字符串。一个更完整的解决方案是parseFloat('0.' + (n + '').split('.')[1])
totymedli

@cdmdotnet位置无关的解决方案在这里:stackoverflow.com/a/59469716/1742529
user1742529

32

0.2999999999999998如何接受?如果我是提问者,我希望得到.3。的答案。这里的错误精度是错误的,而我对floor,%等的实验表明Javascript喜欢这些操作的错误精度。因此,我认为使用转换为字符串的答案是正确的。

我会这样做:

var decPart = (n+"").split(".")[1];

具体来说,我使用的是100233.1,我想要的答案是“ .1”。


6
我一般都同意,但您不能依赖'。用作小数点分隔符的正则表达式是一个i18n字符
MarcelStör14年

1
@jomofrodo实际上,有些人可能需要非四舍五入的值。我不记得OP要求四舍五入的值,只是拆分值。
VVV

1
@VVV是的,有些人可能想要非四舍五入的值。但是仅仅因为您可能希望精确到小数点后9位并不意味着您的输入数据实际上就支持它。这就是为什么将其称为“错误精度”。如果输入为3.1,则答案可以达到的最高精度为十分之一,即.1.。如果您回答.09,则意味着您实际上已计算/测量的精度低至100精度,而实际上原始输入的精度仅为10精度。
jomofrodo 2014年

1
@MarcelStör可以轻松处理:var decPart =(n.toLocaleString(“ en”))。split(“。”)[1];
JEM

1
.toString()不考虑i18n。小数点分隔符将始终符合. MDNECMA规范
Andrewmat

18

这是我的操作方式,我认为这是最简单的方法:

var x = 3.2;
int_part = Math.trunc(x); // returns 3
float_part = Number((x-int_part).toFixed(2)); // return 0.2

15

一个简单的方法是:

var x = 3.2;
var decimals = x - Math.floor(x);
console.log(decimals); //Returns 0.20000000000000018

不幸的是,那并没有返回确切的值。但是,这很容易解决:

var x = 3.2;
var decimals = x - Math.floor(x);
console.log(decimals.toFixed(1)); //Returns 0.2

如果您不知道小数位数,可以使用此方法:

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


9

语言独立方式:

var a = 3.2;
var fract = a * 10 % 10 /10; //0.2
var integr = a - fract; //3

请注意,它仅对具有一个分形肛门长度的数字正确)


3
您能解释一下为什么您认为这与语言无关吗?它是JavaScript。
hotzst

4
@hotzst,没有语言特定的功能
Nurlan

1
语言无关,因为它只是纯数学。实用的解决方案。具有期望的分数长度:var factor = Math.pow(10, desiredFractionLength); var fract = a * factor % factor / factor;
muratgozel

6

您可以使用parseInt()函数来获取整数部分,而不是使用函数来获取小数部分

var myNumber = 3.2;
var integerPart = parseInt(myNumber);
var decimalPart = myNumber - integerPart;

或者您可以使用如下正则表达式:

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]}`)
       }
   }
}

小数部分即将到来0.20000000000000018...这真的很难做,因为0.2 < 0.20000000000000018返回true。3.2 应该返回0.2:P进行了许多不规则操作并使用.toFixed(2)返回字符串:P
Himanshu Bansal

@HimanshuBansal是JavaScript问题对此有一个stackeoverflow问题)。您可以使用我建议的第二种方法。
Sheki

好吧,我有一点点不同的问题陈述... Kinda使用了两种方法:P来解决它。^^
Himanshu Bansal

@HimanshuBansal很高兴我的帖子帮助您解决了问题!
Sheki

5

不管小数点分隔符的区域设置如何,下面的方法都起作用...,条件是仅一个字符用于分隔符。

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);

这不是很漂亮,但是很准确。


当然,这是一个字符串,因此如果您希望将其作为数字,则可能需要首先解析parseInt()。您不应该需要parseFloat()...除非我在这里缺少基数为8而不是基数为10的数字...我隐约记得几年前的事情
cdmdotnet

5

如果精度很重要,并且您需要一致的结果,则以下命题将以字符串形式返回任何数字的小数部分,包括前导“ 0”。如果您需要它作为浮点数,则只需var f = parseFloat( result )在末尾添加即可。

如果小数部分等于零,则将返回“ 0.0”。空,NaN和未定义的数字未经过测试。

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");

这是jsPerf链接:https ://jsperf.com/decpart-of-number/

我们可以看到,命题2是最快的。


不要使用任何这些。一旦数字渲染转换为工程设计,它们就会中断。它们也不对语言环境敏感。
Spongman '19

您能解释一下“数字渲染转向工程”吗?同样,本地化也不相关,因为我们只需要数字的小数部分,而不是表示数字的本地化字符串。
加百利Hautclocq

4

您可以将其转换为字符串,并使用replace方法将整数部分替换为零,然后将结果转换回数字:

var number = 123.123812,
    decimals = +number.toString().replace(/^[^\.]+/,'0');

此解决方案在以逗号为小数点分隔符的欧洲大陆不起作用?
普雷斯顿,2015年

@preston您可以将正则表达式中的点替换为您喜欢的任何其他分隔符(例如/^[^,]/),但随后应将结果保留为字符串(删除+运算符),以避免出现NaN结果。
gion_13

4

根据您稍后将给出的用法,但是此简单的解决方案也可以为您提供帮助。

我并不是说这是一个很好的解决方案,但是对于某些具体案例

var a = 10.2
var c = a.toString().split(".")
console.log(c[1] == 2) //True
console.log(c[1] === 2)  //False

但这将比@Brian M.Hunt提出的解决方案花费更长的时间

(2.3 % 1).toFixed(4)

1
这在除欧洲大陆以外的所有地方都可以正常使用,在欧洲大陆中,逗号是小数点分隔符。如果您打算使用此解决方案,请记住,如果您是跨国公司并且针对欧洲,则要考虑到这一点,因为此解决方案对他们来说做得不好。
cdmdotnet

1

我有一种情况,我知道所有有问题的数字只有一个小数,并且想将小数部分作为整数,所以我最终使用了这种方法:

var number = 3.1,
    decimalAsInt = Math.round((number - parseInt(number)) * 10); // returns 1

这对于整数也很好用,在这些情况下返回0。


1

我在用:

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]);
}

输入:-556.123444444

结果:123444444



1

一个不错的选择是将数字转换为字符串,然后将其分割。

// 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

在一行代码中

let [firstNumber, secondNumber] = [+number.toString().split('.')[0], +number.toString().split('.')[1]];

0

看了其中几个之后,我现在正在使用...

var rtnValue = Number(7.23);
var tempDec = ((rtnValue / 1) - Math.floor(rtnValue)).toFixed(2);


0

尽管我回答这个问题很晚,但是请看一下代码。

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)

0

浮点十进制符号和数字格式可以取决于国家(.,),因此保留了浮点部分的独立解决方案是:

getFloatDecimalPortion = function(x) {
    x = Math.abs(parseFloat(x));
    let n = parseInt(x);
    return Number((x - n).toFixed(Math.abs((""+x).length - (""+n).length - 1)));
}

–这是国际化的解决方案,而不是取决于位置的:

getFloatDecimalPortion = x => parseFloat("0." + ((x + "").split(".")[1]));

解决方案的分步说明:

  1. parseFloat() 用于保证输入的正确性
  2. Math.abs() 用于避免负数问题
  3. n = parseInt(x) 获取小数部分
  4. x - n 用于减去小数部分
  5. 现在,我们的数字的小数部分为零,但是JavaScript可以为我们提供额外的浮动部分数字,这是我们不想要的
  6. 因此,通过调用toFixed()原始浮点数的浮点部分中的位数来限制其他位数x。计算为原始数字的长度xn其字符串表示形式的数字之间的差。

-1

使用这个:

function isNatural(n) {
    n = +n
    if (isNaN(n)) return 'NaN';
    return (n >= 0.0) && (Math.floor(n) === n) && n !== Infinity;
  }

Math.frac = function frac(x, m) {
    x = +x
    if (isNaN(x)) return NaN;
    if (isNatural(x) === true) return 0;
    m = +m || 1

      if (isNatural(x) === false && m === 1){
        var a = x.toString()
        var b = a.split('.')[1]
        var c = '0.' + b
        var d = +c
        return d;
      }

      if (isNatural(x) === false && m === 2){
        var a = x.toString()
        var b = a.split('.')[1]
        var c = +b
        return c;
      }

      if (isNatural(x) === false && m === 3){
        var a = x.toString()
        var b = a.split('.')[1]
        var c = '0.' + b
        var d = +c * 100
        return d;
      }    
  }

Math.frac这里的功能有3种模式:

Math.frac(11.635) //0.635
Math.frac(11.635, 1) //0.635 - default mode is 1
Math.frac(11.635, 2) //635
Math.frac(11.635, 3) //63,5 (%)

这很简单 :)


-9
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

4
在我看来,这看起来像不是javascript!
Ch'marr

1
这不是Java脚本
Amrut

在JS中,它应该类似于:var a = 3.2; var b = parseInt(a,10); var c = a-b;
2015年7
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.