What is the “double tilde” (~~) operator in JavaScript?
我在一些代码中看到了这个,我不知道它会做什么:
1 2 3 4 5 6 7
| var jdn = function(y, m, d) {
var tmp = (m <= 2 ? -1 : 0);
return ~~((1461 * (y + 4800 + tmp)) / 4) +
~~((367 * (m - 2 - 12 * tmp)) / 12) -
~~((3 * ((y + 4900 + tmp) / 100)) / 4) +
d - 2483620;
}; |
~~操作员是做什么的?
- 你现在可能已经知道了,但它返回了千年到某个给定日期之间的天数。
- 当我在《代码战争》上看到它的时候,我发现谷歌不支持Tildes。谢谢你,鸭子,走!
- 简单来说,它将"9"转换为数字9。如果您在控制台中执行以下操作,它必须比Math.Floor()更快,即使使用IE8也是如此:typeof ~'9'/number
- 嘿,斯宾塞,你用什么在Duckduckgo上搜索这个?我刚试过duckduckgo.com/?Q=coffeescript+~但效果不好
- 没有评论是一回事,但我最讨厌的是有人给这个名字命名为jdn。我甚至不知道那代表什么。
- 这应该考虑:youtube.com/watch?V=65 RBBWZQDU
- 由于不断的传播和循环不变性,人们常常对什么是快速产生错误的印象。
- math.trunc(),而不是math.floor()。
~~是一个双非位运算符。
它被用作Math.floor()的快速替代品。
- +我不知道它使价值达到了极限,但我想这是有道理的。(然而,在javascript中,位运算符的速度是否比算术运算符慢,从而使该方法变慢?)
- @ghoppe:值得注意的是,它不同于.floor(),因为它实际上只删除小数点右边的任何内容。当与负数相对使用时,这会产生差异。而且,它总是返回一个数字,并且永远不会给您一个数字。如果不能转换成数字,你会得到0。
- @乍得-它可能比Math.floor()更快,后者必须查找数学全局对象并执行函数调用。
- 文章链接到的测试在文本标题中有Math.floor,但在代码中有Math.round,所以没有提到Math.floor的速度。
- @Guffa很好的一件事就是测试页面可以编辑。:)我刚测试过,在Safari 5上,~~的速度是Math.floor的两倍。
- @戈普:是的,这两个非操作实际上比单层方法更快。当我在我的电脑上的firefox中测试它时,它们只运行了0.2微秒,而不是0.5微秒。这意味着在它被发现之前你需要经常使用它。在一个类似于操作中的函数中,它只是一个微优化,只会使代码更难执行。
- @哈哈,看情况。如果它是一个更新接口元素的函数,那么每微秒都会计数。例如,如果它是用于动态验证的函数,我希望表单尽可能地具有响应性。
- @Ghope:屏幕每秒最多更新100次,因此您必须使用10000次左右的函数才能看到差异。
- @Guffa屏幕更新率与计算速度有什么关系?有人可能在内部将其用于循环或鼠标事件。
- @Shane Reustle:阅读上面的评论以跟踪讨论。
- 链接到页面似乎不再与这个主题有任何关系(强调没有答案的重要性,只需链接到世界野生网站上的另一个页面)。
- 链接不起作用。
- 我使用这个技术遇到了一个整数溢出问题,使用了非常大的数字(在base-62编码期间,将数字与导航计时API除以62的结果)。例如,在firefox、chrome和ie中,~~(2419354838.709677)=-1875612458,而math.floor(2419354838.709677)==2419354838。
- @没错,红色可能值得编辑一下答案,是吗?
- 不要用~~!在IE10中,它比为同样的事情执行其他位操作慢8倍!最好使用零右移(>>0),它是最快的,看起来更像有符号到无符号转换(>>>0)。
- @Jacobwan是的,这不是一个依赖于浏览器的问题。JS中的位操作产生有符号的32位整数,因此如果输入大于2^31-1,就应该避免这种情况。
- 类似于math.trunc(),但不是math.floor()。
- 错了!看起来代码示例是通过一个小型化器完成的。它被用来节省空间。~~比math.floor()短
- 虽然~~是math.floor()的更快别名,但-~是math.ceil()的别名
它隐藏了代码的意图。
它是两个单颚化符运算符,因此它执行两次按位补码(按位非)。这些操作相互抵消,所以唯一剩下的效果是在应用第一个运算符之前完成的转换,即将值转换为整数。
有些人将其作为Math.floor的快速替代品,但速度差异并不是那么显著,在大多数情况下,它只是微观优化。除非您有一段真正需要优化的代码,否则应该使用描述其功能的代码,而不是使用非操作的副作用的代码。
更新2011-08:
随着浏览器中javascript引擎的优化,操作人员和函数的性能会发生变化。在当前的浏览器中,在某些浏览器中使用~~而不是Math.floor的速度要快一些,在某些浏览器中根本不快。如果您真的需要额外的性能,您需要为每个浏览器编写不同的优化代码。
参见:Tilde vs Floor
- +1因为"它隐藏了代码的意图",我花了10分钟的时间来了解~~做了什么。不管怎样,我也不得不承认,它已经在我的黑暗面很强大,它已经诱惑我使用~~代替Math.floor,永远在我的新代码中使用。())
- 请注意,像jspef这样的微测试(必须)运行测试代码的次数足够让运行时优化(如在V8中)启动。这项测试表明(如果使用得非常频繁)Math.floor()在铬合金上的速度可以和~~一样快,但速度并不总是相同的。现在很难说一点代码是否比另一点"更快"(考虑到不同的浏览器和调用场景)。
- 为什么Chrome22比Chrome8慢得多??
- @Mattsach:只有在同一台计算机上进行测试,或者有足够多的人进行了测试,这些数字才具有可比性。Chrome有如此多的版本,以至于很少有人能用每个版本测试代码。
- 记住math.floor()的存在是有原因的。不要使用~~因为它比math.floor快2微秒,如果你不知道它在哪里可能导致溢出或其他意想不到的结果。
- 对于铬来说,这个差距已经明显缩小了。jspef.com/math-floor-vs-math-round-vs-parseint/183
1 2 3 4
| ~(5.5) // => -6
~(-6) // => 5
~~5.5 // => 5 (same as Math.floor(5.5))
~~(-5.5) // => -5 (NOT the same as Math.floor(-5.5), which would give -6 ) |
有关详细信息,请参阅:
- http://dreaminginjavascript.wordpress.com/2008/07/04/28/
- ~(-5.5)=>4,~(4)=>-5,~~(-5.5)=>-5。因此,与Math.floor不同
- @ZZZZBOV,我更新了帖子,澄清了对于负数,~~与Math.floor()不同。
- 数学楼层(-5.5),即-6。bcos math.floor将返回小于或等于给定数字的最大整数。数学楼层(-5.00000001)也给出-6。
区别很简单:
长版
如果您希望具有更好的可读性,请使用Math.floor。但如果你想把它最小化,可以使用tilde ~~。
互联网上有很多消息称Math.floor更快,但有时~~。我不建议您考虑速度,因为在运行代码时不会注意到它。也许在测试等方面,但没有人能在这里看到不同之处。更快的方法是使用~~以更快的加载时间。
短版
~~较短/占用空间较小。Math.floor提高了可读性。有时蒂尔德更快,有时Math.floor更快,但不明显。
- 正确的。这主要是一种风格选择,比如布尔(foo),(foo)之间的选择。对:错),或者!!foo当要将变量强制转换为布尔值时。
- math.trunc(),而不是math.floor()。