如何在 JavaScript 中将浮点数转换为整数?

我想在 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

按位或运算符

可以使用按位或运算符截断浮点数,它既可以用于正数也可以用于负数:

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 现在是这四个中最慢的。

注意

如评论中所述,BITWISE 运算符对带符号的 32 位整数进行运算,因此将转换大数,例如:

1234567890  | 0 => 1234567890
12345678901 | 0 => -539222987

注意:您不能使用Math.floor()来代替截断,因为Math.floor(-3.1) = -4而不是-3

截断的正确替代是:

function truncate(value)
{
    if (value < 0) {
        return Math.ceil(value);
    }

    return Math.floor(value);
}

可以使用双按位非运算符截断浮点数。您提到的其他操作可通过Math.floorMath.ceilMath.round

> ~~2.5
2
> ~~(-1.4)
-1

更多细节由 James Padolsey 提供。

对于截断:

var intvalue = Math.floor(value);

对于回合:

var intvalue = Math.round(value);

您可以使用parseInt方法不进行舍入。由于 0x(十六进制)和 0(八进制)前缀选项,用户输入时要小心。

var intValue = parseInt(floatValue, 10);

位移 0 等于除以 1

// >> or >>>
2.0 >> 0; // 2
2.0 >>> 0; // 2

在您的情况下,当您想要一个字符串结尾(以便插入逗号)时,也可以只使用Number.toFixed()函数,但是,它将执行舍入操作。

这里有很多建议。到目前为止,按位 OR 似乎是最简单的。这是另一个简短的解决方案,它也可以使用模运算符处理负数。比按位 OR 可能更容易理解:

intval = floatval - floatval%1;

此方法还适用于高值数字,其中 '| 0','~~' 或 '>> 0' 均不能正常工作:

> n=4294967295;
> n|0
-1
> ~~n
-1
> n>>0
-1
> n-n%1
4294967295

另一种可能的方式 - 使用 XOR 操作:

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/