1547

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

6
  • 105
    如果您不知道,javascript中的所有数字都是浮点数。根据规范:
    – 一些
    评论 2009年2月28日2:40
  • 8
    4.3.20数字类型:数字类型是表示数字的一组值。在ECMAScript中,值集表示双精度64位格式的IEEE 754值,包括特殊的“非数字”(NaN)值、正无穷大和负无穷大。
    – 一些
    评论 2009年2月28日2:41
  • 13
    是的,Javascript没有独特的“整数”类型,但需要进行这种转换的情况仍然很常见。例如,在我的应用程序中,用户输入了一个数字(可能包括美分)。我不得不截断美分并显示w/逗号。步骤1是转换为int。 评论 2009年2月28日15:40
  • 1
    也很有用:所有方法的速度比较jsperf.com/math-floor-vs-math-round-vs-parseint/33 评论 2012年7月26日18:10
  • 1
    @卡尔:如果我接受字段的输入,我可能能够控制我接受的字符,但我可以用Javascript进行各种处理,而不仅仅是接受用户输入。即使那样,我也可能想要它来做一些事情,比如支持粘贴。 评论 2012年10月30日16:55

18个答案18

重置为默认值
2221
var intvalue=数学floor(floatvalue);var intvalue=数学.ceil(浮点值);var intvalue=数学.round(浮点值);//ECMAScript 6中添加了“Math.trunc”var intvalue=数学.trunc(浮点值);

数学对象引用


示例

积极的
//值=x//x=5 5<x<5.5 5.5<=x<6数学底线(值)//5 5 5数学细胞(值)//5 6 6数学四舍五入(数值)//5 5 6数学trunc(值)//5 5 5parseInt(值)//5 5 5~~值//5 5 5值|0//5 5 5值>>0//5 5 5值>>0//5 5 5value-值%1//5 5 5
否定
//值=x//x=-5-5>x>=-5.5-5.5>x>-6数学底线(值)//-5-6-6数学细胞(值)//-5-5-5数学四舍五入(值)//-5-5-6数学trunc(值)//-5-5-5parseInt(值)//-5-5-5值|0//-5-5-5-5~~值//-5-5-5值>>0//-5-5-5值>>>0//4294967291 4294967291 42949672 91value-值%1//-5-5-5-5
正数-较大的数字
//x=数量。最大安全整数/10//=900719925474099.1//值=x x=900719925474099 x=90071 99254704099.4 x=9007 19925474099.5数学下限(值)数学细胞(值)//900719925474099 90071992474100 900719925.474100数学四舍五入(值)数学trunc(值)parseInt(值)//900719925474099 90071992474099 90071995474099值|0//858993459 858993459 85899345~~值//858993459 858993459 858993459值>>0//858993459 858993459 85899345%值>>>0//858993459 858993459 85899345%value-值%1//900719925474099 900719924474099 9000719925447099 90071925474099
负数-较大的数字
//x=数量。最大安全整数/10*-1//-900719925474099.1//值=x//x=-900719925474099 x=-907199254704099.5 x=-90019925474099.6数学下限(值)//-900719925474099-9007199625474100-90071925474100数学细胞(值)//-900719925474099-9007199625474099-90071925474099数学四舍五入(值)//-900719925474099-90071925474099-9007199625474100数学trunc(值)//-900719925474099-9007199254740999-90071925474099parseInt(值)//-900719925474099-9007199625474099-90071925474099值|0//-858993459-858993459-858993 459~~value//-858993459-858993459-858993 459值>>0//-858993459-858993459-858993459值>>>0//3435973837 3435973837 3435978337value-值%1//-900719925474099-90071996254740999-90071925474099
6
  • 90
    如另一个答案中所述,可以使用var intValue=~~floatValue;。如果符号对您的口味来说太模糊,只需将其隐藏在函数中:函数toInt(value){return~~value;}.(如果您愿意的话,这也会将字符串转换为整数。)
    – 基恩
    评论 2013年4月19日19:08
  • 6
    如果这个答案有输入/输出示例,将投赞成票。 评论 2015年8月27日14:40
  • 11
    关于注释~~将值限制为32位有符号整数,而Math.floor/ceil/round最多可以处理53位(Number.MAX_SAFE_INTEGER 9007199254740991)。下面的答案中提到了这一点,但对于阅读这些评论的人来说,值得在这里重复一下。
    – 约翰
    评论 2016年3月28日15:27
  • 从以下几个地方阅读:数学trunc(val);评论,因为这是公认的答案 评论 2016年5月5日6:05
  • 1
    对于以下值,不能精确工作2.3 - 2.3 % 1
    – 拉皮斯
    评论 2018年11月6日23:31
343

按位OR运算符

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

函数float2int(value){返回值|0;}

结果

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

性能比较?

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

  • 数学基础(val)
  • 值|0 按位
  • ~~val个 按位不是
  • 解析Int(val)

这只适用于正数。在这种情况下,您可以安全地使用位操作数学地板功能。

但是如果你需要你的代码既要积极又要消极,则按位操作是最快的(OR是首选操作)。另一个JSPerf测试相比之下,很明显,由于额外的符号检查数学现在是最慢的四个人中的一个。

注释

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

1234567890  | 0 => 123456789012345678901 | 0 => -539222987
11
  • @法比奥波罗尼:是的,非常简单,似乎按位运算符是最快的。尤其是OR操作符总是最快的,通常与NOT和Math操作匹配,尽管当您必须支持负数时,Math操作也是最慢的,因为它添加了对数字符号的额外检查。 评论 2013年1月10日13:54
  • 12
    @thefourtheye:除无符号右移外,所有按位运算都适用于有符号32位整数。因此,对浮点值使用逐位操作将把它们转换为整数,去掉小数点后的数字。 评论 2013年9月2日12:22
  • 4
    如果你只需要正数,数学地板()更快(至少根据我对你第一次跑步的感觉JSPerf测试在Google Chrome 30.0.1599.101版本上),更加健壮(因为它不依赖于数字如何以位表示,这可能会改变并可能破坏这种按位解决方案),而且最重要的是,更加明确。 评论 2013年10月19日16:29
  • 9
    请注意,按位运算符对32位数字进行运算。它们不适用于32位无法容纳的太大数字。
    – 凯特
    评论 2013年10月31日0:09
  • ~~更好,因为它是一元运算符。4.2|0+4等于4但是~~4.2+4等于8 评论 2015年1月13日18:10
101

注意:您不能使用数学地板()作为truncate的替代,因为数学地板(-3.1)=-4而不是-3!!

truncate的正确替换是:

函数截断(value){if(值<0){return Math.ceil(value);}return Math.floor(value);}
4
  • 1
    这取决于负数的期望行为。有些用法需要负数才能映射到更负值(-3.5->-4),有些用法则需要映射到更小的整数(-3.5->-3)。前者通常称为“地板”。“truncate”一词通常用于描述这两种行为。在我的情况下,我只打算喂它负数。但这条评论对那些关心负数行为的人来说是一个有用的警告。 评论 2009年10月16日14:35
  • 29
    @麦克赫尔姆:那么他们似乎没有正确理解“截断”这个词。截断的作用正如它的名字所暗示的那样:它截断数字。它永远(在一般意义上)不等同于地板或天花板。en.wikipedia.org/wiki/截短 评论 2012年4月16日7:18
  • 6
    数学trunc(值)在ECMAScript 6中添加
    – 4esn0k型
    评论 2014年7月31日5:49
  • 4
    地板向无穷大舍入,截断向零舍入。(天花板向+无穷大舍入)。 评论 2017年4月24日0:03
50

双人间按位不运算符可用于截断浮点值。您提到的其他操作可以通过数学地板,数学.ceil、和数学.round.

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

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

  • 1
    这对生产代码来说可能是一件坏事(因为它很模糊),但这正是我需要的代码嗅觉我的<画布>JS中的字体渲染引擎。谢谢! 评论 2012年2月6日20:31
  • 11
    这也可以用n|0完成。 评论 2012年3月20日23:48
  • 20
    请注意,任何一种方法(~~n或n|0)都只适用于最大为2^31-1或2147483647的数字。2147483648或更高版本将返回错误的结果;例如,2147483647 |0返回-2147483648,4294967295 |0返回-1,这几乎肯定不是您想要的。 评论 2012年10月22日18:36
43

对于截断:

var intvalue=数学地板(值);

对于圆形:

var intvalue=数学.round(值);
2
  • 7
    Math.floor不截断负值。请参阅上面的答案。否则回答很好。 评论 2012年5月4日14:47
  • 如果您对性能感兴趣,我在这里放了一个小的测试用例:jsperf.com/dsafdgdfsaf/2(var |0在此获胜)。 评论 2012年6月15日23:54
42

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

var intValue=解析Int(floatValue,10);

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

7
  • 1
    当您只需要小数的整数部分,而不需要向上或向下舍入时,这实际上很有用,而这正是.round、.ceil和.floor所能做到的。 评论 2012年1月30日20:08
  • 2
    ……即使是简单地截断,这似乎也是最慢的方法。jsperf.com/float-to-int-conversion-comparison 评论 2012年10月11日10:34
  • 2
    总是将第二个值传递给parseInt,以指定您期望的基数。因此,parseInt(floatValue,10)总是以10为基数。 评论 2013年2月22日16:52
  • 4
    虽然这是一个古老的问题,但这个问题似乎是一个经常被问到的问题,所以我在这里把它作为一个警告。如果由于值的大小,使用“e”表示法表示该值,那么结果将是一个数字,而不是预期的数字。例如,parseInt(10000000000000000000,10);结果是1,而不是100 000 000 000 000 00 000 000。无论如何,这个问题显然不想”转换为字符串并进行解析“,虽然这相对较小…;) 评论 2013年11月28日2:04
  • 6
    @澳航94Heavy这种行为的原因是parseInt()需要一个一串不是数字作为其第一个参数。传递此整数时,它将转换为第2页然后解析Int分析字符串第2页,这导致1. 评论 2014年1月9日20:56
19

位移位0,相当于除以1

//>>或>>>2.0 >> 0; // 22.0 >>> 0; // 2
  • 4
    小纸币:>> 0似乎只对整数有效<2^31-1、和>>> 0对于整数<2^32-1。如果值较大,则返回0 评论 2014年4月23日10:02
  • @RomualdBrunet,是的,JavaScript清楚地定义了所有按位操作都是对32位数字的操作。这在规格中。 评论 2014年5月24日2:51
  • 这是因为Javascript只对上面答案中所述的32位(有符号)整数执行逐位操作。因此,任何似乎什么都不做的位操作(比如移位为0,OR为0,AND为1,double NOT)仍然需要Javascript解释器将值转换为32位int。 评论 2018年4月25日11:14
17

如果你想要一个向下取整的答案:

var intvalue=数学地板(浮点值);var整数=数学地板(4.56);答案=4

如果你想向上取整:

var intvalue=数学.ceil(浮点值);答案是=5
15

在您的示例中,当您希望在末尾添加一个字符串(以便插入逗号)时,也可以只使用固定数量()函数,但是,这将执行舍入。

1
  • 只是提醒返回值toFixed是一个字符串。$num1=12.2222.至固定(2) $num2=Number.parseFloat(12.2222).toFixed(2),$num1和$num2在字符串中为“12.22”。
    – 锡石
    评论 2023年2月27日7:05
13

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

控制台.log(12.3^0);//12控制台.log(“12.3”^0);//12控制台日志(1.2+1.3 ^0);//2控制台.log(1.2+1.3*2^0);//console.log(-1.2^0);//-1控制台.log(-1.2+1^0);//0console.log(-1.2-1.3^0);//-2

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

1
  • 很好,但要小心。如果你有常数=-165.01295398373*10_000_000_000然后数学trunc(num)会给你一个正确的答案-1 650 129 539 837 300,但是数字^0给予1 190 253 196(注,编号MIN_SAFE_INTEGER=-9 007 199 254 740 991) 评论 2023年3月19日10:54
10

收件人截断:

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

收件人:

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

0
8
  1. 数学地板()函数返回小于或等于给定数字的最大整数。

    console.log(“数学地板:”,数学地板(3.5));console.log(“数学地板:”,数学地板(-3.5));

  2. 数学ceil()函数总是将一个数字向上舍入为下一个最大的整数。

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

  3. 数学round()函数返回舍入为最接近整数的数字的值。

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

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

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

7

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

intval=floatval-floatval%1;

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

>n=4294967295;>n |0-1>~~n个-1>n>>0-1>n-n%14294967295
1
  • 如果你提到另一个答案,请添加一个参考,或者简要描述一下它的想法。
    – 贝特尔
    评论 2013年7月11日14:06
6

//将浮点转换为整数数学基础(5.95)//5数学细胞(5.95)//6数学回合(5.4)//5数学圆(5.5)//6数学trunc(5.5)//5//快速方法控制台.log(5.95|0)控制台.log(~~5.95)控制台.log(5.95>>0)//5

5

性能

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

结果

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

在此处输入图像描述

细节

我执行您可以运行的测试用例酒店雇员和饭馆雇员

下面的片段介绍了解决方案之间的差异A类 B类 C类 D类 E类 F类 G公司 H(H) J型 K L(左)

功能A(浮动){return Math.trunc(浮点);}功能B(浮动){return parseInt(浮点);}功能C(浮动){返回浮点|0;}功能D(浮动){返回~~浮点;}功能E(浮动){返回浮动>>0;}功能F(浮动){返回浮点-浮点%1;}功能G(浮动){返回浮点^0;}功能H(浮动){return数学地板(浮点);}功能I(浮动){return Math.ceil(浮点);}功能J(浮动){return Math.round(浮点);}功能K(浮点){返回float.toFixed(0);}功能L(浮动){返回浮动>>>0;}// ---------//测试// ---------【A、B、C、D、E、F、G、H、I、J、K、L】.forEach(f=>控制台.log(`${f.name}${f(1.5)}${f(-1.5)}$}f(2.499)}$[{f(-2.499)}`))
此代码段仅显示性能测试中使用的函数-它本身不执行测试!

下面是铬的示例结果

在此处输入图像描述

如果查看本机数学在JavaScript中,您可以使用整组函数处理数字和值等。。。

基本上,你想做的事情是非常简单的,并且是JavaScript中的原生。。。

假设您有以下号码:

const myValue=56.4534931;

现在,如果您想将其四舍五入到最接近的数字,只需执行以下操作:

const四舍五入=数学底线(myValue);

你会得到:

56

如果要将其舍入到最接近的数字,只需执行以下操作:

const roundedUp=数学.ceil(myValue);

你会得到:

57

阿尔索数学.round只需将其四舍五入到更高或更低的数字,这取决于哪一个更接近浮点数。

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

你可以这样使用它~~myValue(我的价值)...

1
  • 请小心~~因为如果数字大于int32限制,它会将该值更改为int32限制值。
    – 马查多
    评论 2019年10月16日14:15
1

我只想指出的是,从金钱上来说,你想要的是回合,而不是回合。被罚一分钱的可能性要小得多,因为四舍五入的4.999452*100会给你5分,这是一个更具代表性的答案。

除此之外,别忘了四舍六入五成双,这是一种抵消直接取整带来的略微积极偏差的方法——您的财务应用程序可能需要它。

JavaScript中的高斯/银行家舍入

0

如果您正在使用angularjs,那么简单的解决方案如下所示

{{val|number:0}}

它将把val转换为整数

通过这个链接docs.angularjs.org/api/ng/filter/number文件

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.