我想在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 = Math.floor(value);

对于圆形:

var intvalue = Math.round(value);

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

truncate的正确替换为:

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

    return Math.floor(value);
}

在您的例子中,当您希望在末尾插入字符串(以便插入逗号)时,也可以只使用Number.toFixed()函数,但这将执行舍入。


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

var intValue = parseInt(floatValue, 10);

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


双位not运算符可用于截断浮点数。您提到的其他操作可通过Math.floor、Math.ceil和Math.round获得。

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

更多细节由詹姆斯·帕多尔西提供。


按位OR运算符

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

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

后果

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

性能比较?

我创建了一个JSPerf测试,用于比较以下各项之间的性能:

数学下限(val)val |0位“或”~~val按位NOTparseInt(val)

这只适用于正数。在这种情况下,可以安全地使用按位运算以及Math.floor函数。

但是如果你需要你的代码同时处理正和负,那么按位操作是最快的(OR是首选)。另一个JSPerf测试与之进行了比较,很明显,由于额外的符号检查,Math现在是四个测试中速度最慢的。

Note

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

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

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

intval = floatval - floatval%1;

此方法也适用于“|0”、“~~”或“>>0”都不能正常工作的高值数字:

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

比特移位0,等于除以1

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

要截断:

//Math.ctrunk()是ES6规范的一部分console.log(数学截断(1.5));//返回1console.log(数学截断(-1.5));//返回-1//数学floor(-1.5)将返回-2,这可能不是您想要的

要舍入:

console.log(数学舍入(1.5));//2.console.log(数学舍入(1.49));//1.console.log(数学舍入(-1.6));//-2.console.log(数学舍入(-1.3));//-1.


我只想指出,在金钱上,你想要圆,而不是截断。因为4.999452*100四舍五入会给你5,一个更具代表性的答案,所以少一分钱的可能性要小得多。

最重要的是,不要忘了银行家的舍入,这是一种抵消直接舍入带来的轻微正偏差的方法——您的金融应用可能需要它。

JavaScript中的高斯/银行家舍入


还有一种可能的方法-使用XOR运算:

console.log(12.3^0);//12console.log(“12.3”^0);//12console.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);//0console.log(-1.2-1.3^0);//-2.

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


如果您使用angularjs,那么简单的解决方案如下HTML模板绑定

{{val |编号: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一样使用它。。。


//将浮点数转换为整数数学楼层(5.95)//5数学ceil(5.95)//6数学舍入(5.4)//5数学舍入(5.5)//6数学截断(5.5)//5//快速方法console.log(5.95|0)控制台日志(~~5.95)控制台日志(5.95>>0)//5


表演

今天2020.11.28我在Chrome v85、Safari v13.1.2和Firefox v80上对MacOs HighSierra 10.13.6进行了测试,以确定所选的解决方案。

后果

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

细节

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

下面的代码片段显示了解决方案之间的差异A.BCDEFGH我JKL

函数A(浮动){return Mathtrunc(浮点);}函数B(浮动){return parseInt(float);}函数C(浮点){返回浮点值|0;}功能D(浮动){return ~~浮点数;}函数E(浮点){返回浮点数>>0;}函数F(浮动){return float-float%1;}函数G(浮动){返回浮点^0;}函数H(浮动){return Math.floor(float);}函数I(浮点){return Math.ceil(浮点);}函数J(浮动){return Math.round(float);}函数K(浮点){return float.toFixed(0);}函数L(浮点){返回浮点>>>0;}// ---------//测试// ---------[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)}`))此代码段仅显示性能测试中使用的函数-它本身不执行测试!

下面是铬的示例结果


函数返回小于或等于给定数字的最大整数。console.log('数学楼层:',数学楼层(3.5));console.log('数学楼层:',数学楼层(-3.5));Math.ceil()函数始终将数字舍入到下一个最大整数。console.log('Math.ceil:',Math.ceil(3.5));console.log('Math.ceil:',Math.ceil(-3.5));函数的作用是返回舍入到最接近整数的数值。console.log('Math.round:',Math.round(3.5));console.log('Math.round:',Math.round(-3.5));函数的作用是通过删除任何小数来返回数字的整数部分。console.log('Math.trunc:',Math.ttrunc(3.5));console.log('Math.trunc:',Math.ttrunc(-3.5));


如果您想要向下四舍五入的答案:

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

如果要向上舍入:

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