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

我想在JavaScript中将浮点数转换为整数。实际上,我想知道如何进行两种标准转换:通过截断和舍入。有效地,不是通过转换为字符串和解析。

1510753 次浏览
var intvalue = Math.floor( floatvalue );var intvalue = Math.ceil( floatvalue );var intvalue = Math.round( floatvalue );
// `Math.trunc` was added in ECMAScript 6var intvalue = Math.trunc( floatvalue );

数学对象引用


示例

积极
// value=x        //  x=5          5<x<5.5      5.5<=x<6
Math.floor(value) //  5            5            5Math.ceil(value)  //  5            6            6Math.round(value) //  5            5            6Math.trunc(value) //  5            5            5parseInt(value)   //  5            5            5~~value           //  5            5            5value | 0         //  5            5            5value >> 0        //  5            5            5value >>> 0       //  5            5            5value - value % 1 //  5            5            5
负面
// value=x        // x=-5         -5>x>=-5.5   -5.5>x>-6
Math.floor(value) // -5           -6           -6Math.ceil(value)  // -5           -5           -5Math.round(value) // -5           -5           -6Math.trunc(value) // -5           -5           -5parseInt(value)   // -5           -5           -5value | 0         // -5           -5           -5~~value           // -5           -5           -5value >> 0        // -5           -5           -5value >>> 0       // 4294967291   4294967291   4294967291value - 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      900719925474099Math.ceil(value)  //  900719925474099      900719925474100      900719925474100Math.round(value) //  900719925474099      900719925474099      900719925474100Math.trunc(value) //  900719925474099      900719925474099      900719925474099parseInt(value)   //  900719925474099      900719925474099      900719925474099value | 0         //  858993459            858993459            858993459~~value           //  858993459            858993459            858993459value >> 0        //  858993459            858993459            858993459value >>> 0       //  858993459            858993459            858993459value - 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     -900719925474100Math.ceil(value)  // -900719925474099     -900719925474099     -900719925474099Math.round(value) // -900719925474099     -900719925474099     -900719925474100Math.trunc(value) // -900719925474099     -900719925474099     -900719925474099parseInt(value)   // -900719925474099     -900719925474099     -900719925474099value | 0         // -858993459           -858993459           -858993459~~value           // -858993459           -858993459           -858993459value >> 0        // -858993459           -858993459           -858993459value >>> 0       //  3435973837           3435973837           3435973837value - value % 1 // -900719925474099     -900719925474099     -900719925474099

对于截断:

var intvalue = Math.floor(value);

对于圆形:

var intvalue = Math.round(value);

注意:您不能使用Math.floor()作为truncate的替代品,因为Math.floor(-3.1) = -4而不是-3!!

截断的正确替换是:

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

在您的情况下,当您想要一个字符串结尾时(为了插入逗号),您也可以只使用#0函数,但是,这将执行舍入。

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

var intValue = parseInt(floatValue, 10);

编辑:作为警告(来自评论部分),请注意某些数值将被转换为指数形式,例如1e21,这会导致"1"的十进制表示不正确

按位不运算符可用于截断浮点数。您提到的其他操作可通过#0#1#2使用。

> ~~2.52> ~~(-1.4)-1

更多细节由James Padolsey提供。

按位或运算符

按位或运算符可用于截断浮点数,它适用于正数和负数:

function float2int (value) {return value | 0;}

搜索结果

float2int(3.1) == 3float2int(-3.1) == -3float2int(3.9) == 3float2int(-3.9) == -3

性能对比?

我创建了一个JSPerf测试来比较性能:

  • Math.floor(val)
  • val | 0按位<强>或
  • ~~val按位<强>非
  • parseInt(val)

这只适用于正数。在这种情况下,您可以安全地使用按位操作和Math.floor函数。

但是如果你需要你的代码积极和消极的工作,那么按位操作是最快的(OR是首选)。这个其他JSPerf测试比较相同的地方,很明显,因为四个中的数学现在是最慢的需要额外的符号检查。

说明

如注释所述,BITWISE运算符对有符号的32位整数进行操作,因此将转换大数,例如:

1234567890  | 0 => 123456789012345678901 | 0 => -539222987

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

intval = floatval - floatval%1;

此方法也适用于高值数字,其中“|0”或“~~”或“>>0”都无法正常工作:

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

位移位为0,相当于除以1

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

截断

// Math.trunc() is part of the ES6 specconsole.log(Math.trunc( 1.5 ));  // returns 1console.log(Math.trunc( -1.5 )); // returns -1// Math.floor( -1.5 ) would return -2, which is probably not what you wanted

console.log(Math.round( 1.5 ));  // 2console.log(Math.round( 1.49 )); // 1console.log(Math.round( -1.6 )); // -2console.log(Math.round( -1.3 )); // -1

我只是想指出,在金钱上,你想舍入,而不是trunc。一分钱不太可能,因为4.999452*100舍入会给你5,一个更具代表性的答案。

最重要的是,不要忘记银行家四舍五入,这是一种对抗直接四舍五入带来的轻微正偏差的方法-您的财务应用程序可能需要它。

JavaScript中的高斯/银行家舍入

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

console.log(12.3 ^ 0); // 12console.log("12.3" ^ 0); // 12console.log(1.2 + 1.3 ^ 0); // 2console.log(1.2 + 1.3 * 2 ^ 0); // 3console.log(-1.2 ^ 0); // -1console.log(-1.2 + 1 ^ 0); // 0console.log(-1.2 - 1.3 ^ 0); // -2

按位运算的优先级低于数学运算的优先级,这很有用。试试https://jsfiddle.net/au51uj3r/

如果您使用的是angularjs,那么简单的解决方案如下在超文本标记语言模板绑定

\{\{val | number:0}}

它会将val转换为整数

点击此链接docs.angularjs.org/api/ng/filter/number

如果在JavaScript中查看原生Math对象,你会得到一大堆函数来处理数字和值等…

基本上,你想做的事情在JavaScript中非常简单和原生…

假设你有下面的数字:

const myValue = 56.4534931;

现在,如果你想把它四舍五入到最近的数字,只需这样做:

const rounded = Math.floor(myValue);

然后你得到:

56

如果你想把它四舍五入到最近的数字,只需:

const roundedUp = Math.ceil(myValue);

然后你得到:

57

Math.round只是将其舍入到更高或更低的数字取决于哪个更接近flot数字。

您还可以在浮点数后面使用~~,这将把浮点数转换为整数。

你可以像~~myValue一样使用它。

//Convert a float to integer
Math.floor(5.95)//5
Math.ceil(5.95)//6
Math.round(5.4)//5
Math.round(5.5)//6
Math.trunc(5.5)//5
//Quick Waysconsole.log(5.95| 0)console.log(~~5.95)console.log(5.95 >> 0)//5

性能

今天2020.11.28我在Chromev85、Safariv13.1.2和Firefox v80上对MacO HighSierra 10.13.6进行测试,以获取所选解决方案。

搜索结果

  • 对于所有浏览器,所有解决方案(B和K除外)都提供了非常相似的速度结果
  • 解决方案B和K很慢

输入图片描述

详情

我执行您可以运行的测试用例这里

下面的代码片段显示了解决方案之间的差异ABCDEFGH

function A(float) {return Math.trunc( float );}
function B(float) {return parseInt(float);}
function C(float) {return float | 0;}
function D(float) {return ~~float;}
function E(float) {return float >> 0;}
function F(float) {return float - float%1;}
function G(float) {return float ^ 0;}
function H(float) {return Math.floor( float );}
function I(float) {return Math.ceil( float );}
function J(float) {return Math.round( float );}
function K(float) {return float.toFixed(0);}
function L(float) {return float >>> 0;}





// ---------// TEST// ---------
[A,B,C,D,E,F,G,H,I,J,K,L].forEach(f=> console.log(`${f.name} ${f(1.5)} ${f(-1.5)} ${f(2.499)} ${f(-2.499)}`))
This snippet only presents functions used in performance tests - it not perform tests itself!

And here are example results for chrome

enter image description here

  1. Math.floor()函数返回小于或等于给定数字的最大整数。

        console.log('Math.floor : ', Math.floor(3.5));console.log('Math.floor : ', Math.floor(-3.5));

  2. Math.ceil()函数总是将一个数字四舍五入到下一个最大的整数。

        console.log('Math.ceil : ', Math.ceil(3.5));console.log('Math.ceil : ', Math.ceil(-3.5));

  3. Math.round()函数返回四舍五入到最接近的整数的数字的值。

        console.log('Math.round : ', Math.round(3.5));console.log('Math.round : ', Math.round(-3.5));

  4. Math.trunc()函数通过删除任何小数来返回数字的整数部分。

        console.log('Math.trunc : ', Math.trunc(3.5));console.log('Math.trunc : ', Math.trunc(-3.5));

如果你想要一个向下的四舍五入的答案:

var intvalue = Math.floor( floatvalue );var integer = Math.floor(4.56);Answer = 4

如果你想向上舍入:

var intvalue = Math.ceil( floatvalue );Answeer would be = 5