在JavaScript中,将浮点转换为整数的最佳方法是什么?
在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,这意味着空对象或数组通过了测试),
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);
});