在JavaScript中,将浮点转换为整数的最佳方法是什么?

在JavaScript中,将浮点转换为整数的最佳方法是什么?,javascript,variables,types,Javascript,Variables,Types,在JavaScript中,有几种不同的方法可以将浮点数转换为整数。我的问题是,哪种方法可以提供最佳性能、最兼容,或者被认为是最佳实践 以下是我知道的几种方法: var a = 2.5; window.parseInt(a); // 2 Math.floor(a); // 2 a | 0; // 2 我肯定还有其他人。建议?parseInt()可能是最好的建议a | 0并不是你真正想要的(如果a是未定义的或空值,它只会赋值0,这意味着空对象或数组通过了测试),

在JavaScript中,有几种不同的方法可以将浮点数转换为整数。我的问题是,哪种方法可以提供最佳性能、最兼容,或者被认为是最佳实践

以下是我知道的几种方法:

var a = 2.5;
window.parseInt(a); // 2
Math.floor(a);      // 2
a | 0;              // 2
我肯定还有其他人。建议?

parseInt()可能是最好的建议
a | 0
并不是你真正想要的(如果a是未定义的或空值,它只会赋值0,这意味着空对象或数组通过了测试),Math.floor通过某种类型的技巧工作(它基本上在后台调用parseInt())

你可以使用Number(a).toFixed(0)

甚至只是a.toFixed(0)

编辑:

这是四舍五入到0位,与截断略有不同,正如其他人所建议的,toFixed返回一个字符串,而不是原始整数。用于显示目的

var num = 2.7;  // typeof num is "Number"
num.toFixed(0) == "3"
根据:

parseInt有时用作将浮点数转换为整数的一种方法。它非常不适合该任务,因为如果它的参数是数值类型,它将首先转换为字符串,然后解析为数字

要将数字舍入为整数,最好选择Math.round、Math.ceil和Math.floor中的一个


如果不指定基数值,如
'010'
将被视为八进制(因此结果将是
8
而不是
10
)。

问题似乎是专门询问如何从浮点转换为整数。我的理解是,实现这一点的方法是使用
toFixed
。所以

var myFloat = 2.5;
var myInt = myFloat.toFixed(0);

有人知道
Math.floor()
的性能是否比
Number.toFixed()
差吗?

答案已经给出,但只是为了清楚起见

使用数学库进行此操作。圆形、天花板或地板功能

parseInt用于将字符串转换为int,这里不需要它

toFixed用于将浮点转换为字符串,这里也不需要它


由于数学函数不会对字符串进行任何转换或从字符串进行任何转换,因此它比任何其他错误的选择都要快。

您也可以这样做:

var string = '1';
var integer = a * 1;

显然,双位not是确定数字的最快方法:

var x = 2.5;
console.log(~~x); // 2
曾经是这里的一篇文章,但现在得到了404:

谷歌缓存了它:
http://74.125.155.132/search?q=cache:wpZnhsbJGt0J:james.padolsey.com/javascript/double-按位not/+双精度+按位not&cd=1&hl=en&ct=clnk&gl=us

但是回程机器拯救了这一天

来自Douglas Crockford的“Javascript:好的部分”:

Number.prototype.integer = function () {
    return Math[this < 0 ? 'ceil' : 'floor'](this);
}

使用位运算符。它可能不是转换为整数的最清晰的方式,但它适用于任何类型的数据类型

假设您的函数接受一个参数
value
,并且函数的工作方式是
value
必须始终是整数(并且接受0)。然后,以下任一项将
值指定为整数:

value = ~~(value)
value = value | 0;
value = value & 0xFF;   // one byte; use this if you want to limit the integer to
                        // a predefined number of bits/bytes
最好的一点是,这适用于字符串(您可能从文本输入中获得的内容等),这些字符串是数字
~(“123.45”)==123
。任何非数值都会导致
0
,即

~~(undefined) === 0
~~(NaN) === 0
~~("ABC") === 0
它确实可以将十六进制数用作字符串(带有
0x
前缀)


我想这里面有某种强迫。我将做一些性能测试,将它们与
parseInt()
Math.floor()
进行比较,但我喜欢有额外的便利,无
错误被抛出,非数字的
0
,所以我在
Chrome
上做了一个基准,当输入已经是数字时,最快的是
~~num
num | 0
,半速:
Math.floor
,最慢的是
parseInt
,请参阅

编辑:似乎已经有另一个人做了基准测试(更多结果)和附加测试:
num>>0
(最快为
|0
)和
num-num%1
(有时很快)

最佳方法取决于:

  • 舍入模式:您期望/需要(浮点到整数)的值
    对于具有小数部分的正数和/或负数。
    常见例子: float | trunc | floor | ceil | near (half up) ------+-------+-------+-------+--------------- +∞ | +∞ | +∞ | +∞ | +∞ +2.75 | +2 | +2 | +3 | +3 +2.5 | +2 | +2 | +3 | +3 +2.25 | +2 | +2 | +3 | +2 +0 | +0 | +0 | +0 | +0 NaN | NaN | NaN | NaN | NaN -0 | -0 | -0 | -0 | -0 -2.25 | -2 | -3 | -2 | -2 -2.5 | -2 | -3 | -2 | -2 -2.75 | -2 | -3 | -2 | -3 -∞ | -∞ | -∞ | -∞ | -∞

自ES6以来,还有一种补充的静态方法,用于测试传递的值是否为
Number
类型,是否为安全整数范围内的整数(返回布尔值
true
false
)。
注意:对于:
NaN
Infinity
String
(即使它代表一个数字)也将返回
false

Polyfill示例:

请注意,与以下各项相比,上述polyfill的有效载荷可能通过发动机进行更好的预优化:
数学[n<0?'ceil':'floor'](n)

用法
Math.trunc(/*Number或String*/)

输入:(整数或浮点)
数字
(但很乐意尝试将字符串转换为数字)
输出:(整数)
数字
(但很乐意在字符串上下文中将数字转换为字符串)
范围
-2^52
+2^52
(超出此范围,我们应预计“舍入误差”(以及在某些情况下的科学/指数表示法)简单明了,因为我们在IEEE 754中输入的
数字已经失去了分数精度:因为
±2^52
±2^53
之间的数字已经是内部舍入整数(例如
4503599627370509.5
内部已经表示为
4503599627370510
)除了
±2^53
之外,整数也失去了精度(2的幂)。

通过将除法的(
%
)减去
1
~~(undefined) === 0
~~(NaN) === 0
~~("ABC") === 0
~~("0xAF") === 175
float | trunc | floor | ceil | near (half up) ------+-------+-------+-------+--------------- +∞ | +∞ | +∞ | +∞ | +∞ +2.75 | +2 | +2 | +3 | +3 +2.5 | +2 | +2 | +3 | +3 +2.25 | +2 | +2 | +3 | +2 +0 | +0 | +0 | +0 | +0 NaN | NaN | NaN | NaN | NaN -0 | -0 | -0 | -0 | -0 -2.25 | -2 | -3 | -2 | -2 -2.5 | -2 | -3 | -2 | -2 -2.75 | -2 | -3 | -2 | -3 -∞ | -∞ | -∞ | -∞ | -∞
Number.MIN_SAFE_INTEGER || (Number.MIN_SAFE_INTEGER=
  -(Number.MAX_SAFE_INTEGER=9007199254740991) //Math.pow(2,53)-1
);
Number.isSafeInteger || (Number.isSafeInteger = function(value){
  return typeof value === 'number' && 
                value === Math.floor(value) &&
                value  <   9007199254740992 &&
                value  >  -9007199254740992;
});
Math.trunc || (Math.trunc = function(n){
    return n < 0 ? Math.ceil(n) : Math.floor(n); 
});
n | n>>0 OR n<<0 OR | n>>>0 | n < 0 ? -(-n>>>0) : n>>>0 | n|0 OR n^0 OR ~~n | | | OR n&0xffffffff | | ----------------------------+-------------------+-------------+--------------------------- +4294967298.5 = (+2^32)+2.5 | +2 | +2 | +2 +4294967297.5 = (+2^32)+1.5 | +1 | +1 | +1 +4294967296.5 = (+2^32)+0.5 | 0 | 0 | 0 +4294967296 = (+2^32) | 0 | 0 | 0 +4294967295.5 = (+2^32)-0.5 | -1 | +4294967295 | +4294967295 +4294967294.5 = (+2^32)-1.5 | -2 | +4294967294 | +4294967294 etc... | etc... | etc... | etc... +2147483649.5 = (+2^31)+1.5 | -2147483647 | +2147483649 | +2147483649 +2147483648.5 = (+2^31)+0.5 | -2147483648 | +2147483648 | +2147483648 +2147483648 = (+2^31) | -2147483648 | +2147483648 | +2147483648 +2147483647.5 = (+2^31)-0.5 | +2147483647 | +2147483647 | +2147483647 +2147483646.5 = (+2^31)-1.5 | +2147483646 | +2147483646 | +2147483646 etc... | etc... | etc... | etc... +1.5 | +1 | +1 | +1 +0.5 | 0 | 0 | 0 0 | 0 | 0 | 0 -0.5 | 0 | 0 | 0 -1.5 | -1 | +4294967295 | -1 etc... | etc... | etc... | etc... -2147483646.5 = (-2^31)+1.5 | -2147483646 | +2147483650 | -2147483646 -2147483647.5 = (-2^31)+0.5 | -2147483647 | +2147483649 | -2147483647 -2147483648 = (-2^31) | -2147483648 | +2147483648 | -2147483648 -2147483648.5 = (-2^31)-0.5 | -2147483648 | +2147483648 | -2147483648 -2147483649.5 = (-2^31)-1.5 | +2147483647 | +2147483647 | -2147483649 -2147483650.5 = (-2^31)-2.5 | +2147483646 | +2147483646 | -2147483650 etc... | etc... | etc... | etc... -4294967294.5 = (-2^32)+1.5 | +2 | +2 | -4294967294 -4294967295.5 = (-2^32)+0.5 | +1 | +1 | -4294967295 -4294967296 = (-2^32) | 0 | 0 | 0 -4294967296.5 = (-2^32)-0.5 | 0 | 0 | 0 -4294967297.5 = (-2^32)-1.5 | -1 | +4294967295 | -1 -4294967298.5 = (-2^32)-2.5 | -2 | +4294967294 | -2
Math.intToInf || (Math.intToInf = function(n){
    return n < 0 ? Math.floor(n) : Math.ceil(n); 
});