在JavaScript中将浮点数转换为整数的最快方法是什么?

22

假设我有 x = 12.345。 在 JavaScript 中,哪个函数 floatToInt(x) 运行时间最快,以便 floatToInt(12.345) 返回12


2
只需使用 Math.round(或 Math.floor,取决于您的需要)。 - Bergi
你的转换速度真的值得让代码变得不易读吗? - jfriend00
1
你已经对你的代码进行了性能测试,并发现整数转换是主要瓶颈吗?我问这个问题是因为大多数时候人们花时间“加速”,实际上他们正在处理问题的错误部分,从而浪费时间,而且往往会使他们的代码变得更加复杂,却没有太多或任何改进。 - jfriend00
1
@Bergi - 你现在处于森林中,看不到树木。我只是问了一个简单的问题,只是想要一个简单的答案,没有比这更复杂的了。不过还是感谢你的贡献! - vimfluencer
显示剩余5条评论
7个回答

44

很棒的问题!我前几天实际上就处理了这个问题!可能看起来只需编写parseInt,但等等!我们可以更高端一些。

因此,我们可以为许多事情使用位运算符,而这似乎是一个很好的情况!假设我有你问题中的数字12.345,我可以使用位运算符〜,它翻转数字中的所有位并在过程中将数字转换为int!JS 真是太棒了。

现在我们有了数字的反向位表示,如果我们再次'~'它,我们得到..........鼓声响起.........没有小数的数字!不幸的是,它不能四舍五入。

var a = 12.345;
var b = ~~a; //boom!

我们可以使用Math.round()来实现。但是你可以在JSperf上尝试一下,看看你能得到的轻微速度提升!希望这有所帮助!


1
如果在没有文档或支持证据的情况下回答一个“最快”的问题,并且没有展示出你的方法在多个浏览器中确实更快,那么这种回答会少了很多东西。它可能更快,但你应该展示一些证据表明它确实在多个浏览器中更快。 - jfriend00
2
那么,你写了一个回答来回答一个问题,该问题要求展示“最快”的方法,但在使用别人的测试时没有显示出有意义的差异,而且你没有时间进行自己的测试?你还没有展示你的答案除了将其转换为int的“不同”方法之外的任何其他东西。我甚至更惊讶的是,OP上钩了,似乎认为这是一种好的编码方式。 - jfriend00
1
@jfriend00:注意测试代码在每次初始化(“setup code”)后会多次运行(在具有动态长度的循环中),因此您不应该改变testNumbers,它将仅由整数组成在第一次运行之后。您需要将“slice”移动到定时区域内。但是这个想法很好,如果您不信任Math.random,则应该能够做一些类似于这样的事情。 - Bergi
3
我理解您的意思,您对设置代码提出的观点很有道理。为了避免改变testNumbers数组,我将代码更改为只分配给一个resultArray,因此不需要.slice(),并且它始终在随机数字上运行:https://jsperf.com/float-to-int-conversion-comparison/30。 - jfriend00
5
小心! 当 x = 10000000000 时,Math.floor(x) === x,但是 ~~x === 1410065408。当 -0.5 时,Math.floor(-0.5) === -1,但是 ~~(-0.5) === 0 - Toxiro
显示剩余13条评论

14

我认为这是一个很好的例子。

var intvalue = Math.floor( floatvalue );
var intvalue = Math.ceil( floatvalue ); 
var intvalue = Math.round( floatvalue );

8

只需执行:~~(x + 0.5)

祝好,Z。


6

使用零进行算术 OR 运算可以解决问题。

> 12 === (0 | 12.245)
true

2
在我的测试中,我发现性能的经验法则是:
  1. 按位运算~~num、num|0、num^0、num&0xFFFFFFFF
  2. Math 方法
  3. num - (num % 1)
  4. parseInt
位运算符的问题在于,在过程中数字将转换为32位整数,如果这对您的用例来说没问题,那么可以继续使用。请参阅MDN关于按位或按位非按位与按位异或或它们各自的ECMAScript文档parseInt函数通常比其他替代方案慢得多,很可能是因为它期望参数为字符串。
使用模运算符的解决方案应该谨慎使用,因为由于浮点数问题,有时可能会出问题,但它几乎与Math方法一样快。

2

parseInt(x)可以完成这项工作。
如果您正在运行检查以查看返回的值是否实际上是整数,而不知道输入内容。

x = 12.245; // Issa number
x = 'School'; // Not a number
y = parseInt(x)
if isNaN(y)
    console.log('Not a number');
else
    console.log('Issa number');
// Issa number

然而,使用y = ~~x则是完全不同的情况。

x = 12.245; // Issa number
x = 'School'; // Issa number
y = ~~x;
if isNaN(y)
    console.log('Not a number');
else
    console.log('Issa number');


0

如果您不关心舍入的细节,Math.trunc() 是简单、标准和易读的。我没有测试过性能,但它肯定比Math.round()parseInt()更好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接