我想在JavaScript中将一个浮点数转换为整数。实际上,我想知道如何进行标准的两种转换:截断和四舍五入。而且要高效,不通过转换为字符串并解析来完成。
var intvalue = Math.floor( floatvalue );
var intvalue = Math.ceil( floatvalue );
var intvalue = Math.round( floatvalue );
// `Math.trunc` was added in ECMAScript 6
var intvalue = Math.trunc( floatvalue );
// value=x // x=5 5<x<5.5 5.5<=x<6
Math.floor(value) // 5 5 5
Math.ceil(value) // 5 6 6
Math.round(value) // 5 5 6
Math.trunc(value) // 5 5 5
parseInt(value) // 5 5 5
~~value // 5 5 5
value | 0 // 5 5 5
value >> 0 // 5 5 5
value >>> 0 // 5 5 5
value - value % 1 // 5 5 5
负面// value=x // x=-5 -5>x>=-5.5 -5.5>x>-6
Math.floor(value) // -5 -6 -6
Math.ceil(value) // -5 -5 -5
Math.round(value) // -5 -5 -6
Math.trunc(value) // -5 -5 -5
parseInt(value) // -5 -5 -5
value | 0 // -5 -5 -5
~~value // -5 -5 -5
value >> 0 // -5 -5 -5
value >>> 0 // 4294967291 4294967291 4294967291
value - value % 1 // -5 -5 -5
正数 - 较大的数字// x = Number.MAX_SAFE_INTEGER/10 // =900719925474099.1
// value=x x=900719925474099 x=900719925474099.4 x=900719925474099.5
Math.floor(value) // 900719925474099 900719925474099 900719925474099
Math.ceil(value) // 900719925474099 900719925474100 900719925474100
Math.round(value) // 900719925474099 900719925474099 900719925474100
Math.trunc(value) // 900719925474099 900719925474099 900719925474099
parseInt(value) // 900719925474099 900719925474099 900719925474099
value | 0 // 858993459 858993459 858993459
~~value // 858993459 858993459 858993459
value >> 0 // 858993459 858993459 858993459
value >>> 0 // 858993459 858993459 858993459
value - value % 1 // 900719925474099 900719925474099 900719925474099
负数 - 更大的数字// x = Number.MAX_SAFE_INTEGER/10 * -1 // -900719925474099.1
// value = x // x=-900719925474099 x=-900719925474099.5 x=-900719925474099.6
Math.floor(value) // -900719925474099 -900719925474100 -900719925474100
Math.ceil(value) // -900719925474099 -900719925474099 -900719925474099
Math.round(value) // -900719925474099 -900719925474099 -900719925474100
Math.trunc(value) // -900719925474099 -900719925474099 -900719925474099
parseInt(value) // -900719925474099 -900719925474099 -900719925474099
value | 0 // -858993459 -858993459 -858993459
~~value // -858993459 -858993459 -858993459
value >> 0 // -858993459 -858993459 -858993459
value >>> 0 // 3435973837 3435973837 3435973837
value - value % 1 // -900719925474099 -900719925474099 -900719925474099
var intValue = ~~floatValue;
来进行负数安全截断。如果这种表示方法过于晦涩难懂,请将其隐藏在函数中:function toInt(value) { return ~~value; }
。(如果需要,这也可以将字符串转换为整数。) - KeenMath.trunc(val);
之所以这是被接受的答案,请注意。 - Old Badman Grey2.3 - 2.3%1
这样的精确值。 - Lapys按位或运算符可用于截断浮点数,对于正数和负数都有效:
function float2int (value) {
return value | 0;
}
结果
float2int(3.1) == 3
float2int(-3.1) == -3
float2int(3.9) == 3
float2int(-3.9) == -3
我创建了一个JSPerf测试,比较了以下代码的性能:
Math.floor(val)
val | 0
按位或~~val
按位非parseInt(val)
这些都仅适用于正数。在这种情况下,你可以放心地使用按位运算,以及Math.floor
函数。
但是,如果您的代码需要同时处理正数和负数,那么按位操作是最快的方法(按位或是首选)。另一个JSPerf测试对这些进行了比较,在这个测试中很明显,由于额外的符号检查,Math现在是四个中最慢的。
如评论所述,按位运算符对有符号32位整数进行操作,因此大数字将被转换,例如:
1234567890 | 0 => 1234567890
12345678901 | 0 => -539222987
Math.floor()
更快(至少根据我在 Google Chrome 30.0.1599.101 版本上运行你的第一个 JSPerf 测试 的结果),更健壮(因为它不依赖于数字以二进制形式表示的方式,而这种位运算解决方案可能会受到影响并被破坏),最重要的是,更明确。 - ma11hew28~~
is better because it's a unary operator. 4.2|0+4
equals 4
but ~~4.2+4
equals 8
- Janus TroelsenMath.floor()
来替换截断,因为Math.floor(-3.1) = -4
而不是-3
!function truncate(value)
{
if (value < 0) {
return Math.ceil(value);
}
return Math.floor(value);
}
Math.trunc(value)
是在 ECMAScript 6 中添加的。 - 4esn0kfloor
向负无穷取整, truncate
向零取整 (ceil
向正无穷取整)。 - Peter Cordes使用双位按位非运算符可以截断浮点数。其他你提到的操作可以通过Math.floor
、Math.ceil
和Math.round
实现。
> ~~2.5
2
> ~~(-1.4)
-1
对于截断:
var intvalue = Math.floor(value);
关于round函数:
var intvalue = Math.round(value);
var intValue = parseInt(floatValue, 10);
编辑:根据评论部分的警告,请注意某些数字值将转换为其指数形式,例如1e21
,这将导致"1"
的不正确十进制表示。
parseInt(1000000000000000000000, 10);
的结果是1,而不是1 000 000 000 000 000 000 000。无论如何,问题明确不想要“将其转换为字符串并解析”,尽管这相对较小... ;) - Qantas 94 HeavyparseInt()
期望它的第一个参数为字符串而不是数字。当您传递此整数时,它会被转换为1e21
,然后parseInt
解析字符串1e21
,其结果为1
。 - Olaf DietscheparseInt(0.0000005)
的结果是 5
而不是 0
,因为它首先被转换为 5e-7
。因此,在解析整数而不是字符串时要小心一些是很重要的。 - Rohan Chougule将二进制数左移0位等同于除以1
// >> or >>>
2.0 >> 0; // 2
2.0 >>> 0; // 2
>> 0
只适用于整数小于 _2^31-1_,而 >>> 0
只适用于整数小于 _2^32-1_。对于更大的值,这将返回0。 - Romuald Brunet在您的情况下,当您想要在最后插入逗号的字符串时,您也可以使用Number.toFixed()
函数,但是这将进行四舍五入操作。
$num1 = 12.2222.toFixed(2)
$num2 = Number.parseFloat(12.2222).toFixed(2)
,$num1和$num2都是字符串"12.22"。 - tinystonevar intvalue = Math.floor( floatvalue );
var integer = Math.floor(4.56);
Answer = 4
如果您想向上取整:
var intvalue = Math.ceil( floatvalue );
Answer would be = 5
还有一种可能的方法 — 使用异或运算:
console.log(12.3 ^ 0); // 12
console.log("12.3" ^ 0); // 12
console.log(1.2 + 1.3 ^ 0); // 2
console.log(1.2 + 1.3 * 2 ^ 0); // 3
console.log(-1.2 ^ 0); // -1
console.log(-1.2 + 1 ^ 0); // 0
console.log(-1.2 - 1.3 ^ 0); // -2
按位运算的优先级低于数学运算,这很有用。 在https://jsfiddle.net/au51uj3r/上试试。
const num = -165.01295398373 * 10_000_000_000_000
,那么 Math.trunc(num)
将会给你正确的 -1 650 129 539 837 300
,但是 num ^ 0
却会给出 1 190 253 196
。(注意,Number.MIN_SAFE_INTEGER = -9 007 199 254 740 991) - 8bitjoey