快速的取整方法(~~)

為什么80%的碼農都做不了架構師?>>> ??hot3.png

最近看一篇js裝逼小技巧————雙波浪號的妙用(將內容轉化為數字,或者小數取整),但是本身我的JavaScript水平比較低對其底層操作和其使用范圍不甚了解;通過翻閱資料現進行簡單的整理。 ###裝逼技巧地址&截圖### 地址

圖片

###~~的本質### ~~被稱為“雙按位非”操作符。你通常可以使用它作為代替Math.trunc()的更快的方法。 一個按位非操作符~首先將輸入input截取為32位,然后將其轉換為-(input+1)。因此雙按位非操作符將輸入轉換為-(-(input + 1)+1),使其成為一個趨向于0取整的好工具。對于數字的輸入,它很像Math.trunc()。失敗時返回0,這可能在解決Math.trunc()轉換錯誤返回NaN時是一個很好的替代。

// 單個 ~
console.log(~1337)// -1338
// 數字輸入
console.log(~~47.11)  // -> 47
console.`log`(~~1.9999) // -> 1
console.log(~~3)  // -> 3

然而, 盡管~~可能有更好的性能,有經驗的程序員通常堅持使用Math.trunc()。要明白為什么,這里有一個關于此操作符的分析。 ###適用的情況### 當CPU資源很珍貴時

~~可能在各平臺上都比Math.trunc()快,但是你應該在你所關心的所有平臺上測試這種猜想。同樣,你通常需要執行數百萬這樣的操作來看看在運行時有沒有明顯的影響。

當不需要關心代碼清晰度時

如果你想迷惑其他人,或者想在minifier/uglifier時取得更大功效,這是一種相對廉價的方式。 ###禁用的情況### 當你的代碼需要維護時

代碼可讀性始終是最重要的。無論你工作在一個團隊,或是貢獻給開源倉庫,或是單飛。

當你忘記~~永遠趨向于0時

新手程序員或許更關注~~的聰明之處,卻忘記了“只去掉小數部分”的意義。這在將浮點數轉換為數組索引或關聯有序的值時很容易導致差一錯誤 ,這時明顯需要一個不同的取整方法。 (代碼可讀性不高往往會導致此問題)

打個比方,如果你想得到離一個數“最近的整數”,你應該用Math.round()而不是~~,但是由于程序員的惰性和每次使用需要敲10個鍵的事實,人類的手指往往會戰勝冷冷的邏輯,導致錯誤的結果。

相比之下,Math.xyz()(舉例)函數的名字清楚的傳達了它們的作用,減少了可能出現的意外的錯誤。

當處理大數時

因為~首先將數組轉換為32位,~~的結果偽值在 ±2.15*10^12左右。如果你沒有明確的檢查輸入值的范圍,當轉換的值最終與原始值有很大差距時,用戶就可能觸發未知的行為:

a = 2147483647.123  // 比32位最大正數,再多一點
console.log(~~a)// ->  2147483647 (ok)
a += 10000  // ->  2147493647.123 (ok)
console.log(~~a)// -> -2147483648 (huh?)

一個特別容易中招的地方是在處理Unix時間戳時(從1970年1月1日 00:00:00 UTC開始以秒測量)。一個快速獲取的方法:

epoch_int = ~~(+new Date() / 1000) // Date() 以毫秒計量,所以我們縮小它 然而,當處理2038年1月19日 03:14:07 UTC 之后的時間戳時(有時稱為Y2038 limit), 可怕的事情發生了:

// 2040年1月1日 00:00:00.123 UTC的時間戳
epoch = +new Date('2040-01-01') / 1000 + 0.123  // ->  2208988800.123
// 回到未來!
epoch_int = ~~epoch // -> -2085978496
console.log(new Date(epoch_int * 1000)) // ->  Wed Nov 25 1903 17:31:44 UTC

// 這很搞笑,讓我們來取得正確結論

epoch_flr = Math.floor(epoch)   // ->  2208988800
console.log(new Date(epoch_flr * 1000)) // ->  Sun Jan 01 2040 00:00:00 UTC

當原始輸入的數據類型不確定時

因為~~可以將任何非數字類型轉換為0:

console.log(~~[])   // -> 0
console.log(~~NaN)  // -> 0
console.log(~~null) // -> 0

一些程序員將其看作適當輸入驗證的替代品。然而,這將導致奇怪的邏輯問題,因此你不能辨別違法輸入還是真正的0。因此這并不推薦。 當很多人認為~~X == Math.floor(X)時

很多人由于很多原因錯誤的把”雙按位非”等同于Math.floor()。如果你不能準確地使用它,最終你很有可能會濫用它。

另一些人很細心的注意正數使用Math.floor()而負數使用Math.ceil(),但這又強制你在處理它的時候需要停下來想一想你處理的數是什么值。這又違背了使用~~快捷無陷阱的目的。

###結論###

  1. 謹慎使用。
  2. 在應用前檢查值。
  3. 仔細記錄被轉化值的相關假設。
  4. 審查代碼至少處理:
  • 邏輯錯誤,不合法的輸入作為合法的0傳入其他代碼模塊
  • 輸入轉換后范圍錯誤
  • 錯誤的舍入方向導致差一錯誤

轉載于:https://my.oschina.net/bbhan/blog/1498466

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/257858.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/257858.shtml
英文地址,請注明出處:http://en.pswp.cn/news/257858.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

git log友好顯示

查看commit 提交日志 $ git log $git log --prettyoneline $git reflog 顯示所有提交記錄,包括已經回退的提交,如圖:提交了abc 和 bb 然后回退到 abc   $git log 只顯示abc提交 可以使用 $git reset --hard commit號 回退到bb git reflog…

jprofiler_windows-x64_9_1注冊碼

L-Larry_Lau163.com#5481-ucjn4a16rvd98#6038 L-Larry_Lau163.com#36573-fdkscp15axjj6#25257 轉載于:https://www.cnblogs.com/sprinng/p/5104507.html

南理工計算機技術專業學位,南京理工大學計算機技術(專業學位)考研難嗎

很多考生在準備南京理工大學計算機技術(專業學位)考研難嗎?是考研報考的時候都會產生這樣的疑問:這個專業的研究生好嗎?適合我嗎?對我以后的人生和職業會有幫助嗎?考生在準備南京理工大學計算機技術(專業學位)專業考研…

《分布式系統:概念與設計》一2.3.2 體系結構模式

2.3.2 體系結構模式 體系結構模式構建在上述討論過的相對原始的體系結構元素之上,提供組合的、重復出現的結構,這些結構在給定的環境中能運行良好。它們未必是完整的解決方案,但當與其他模式組合時,它們會更好地引導設計者給出一…

javascript sort()實現元素json對象的排序

看以下代碼: var s [ { name: "Robin Van PurseStrings", age: 30 } ,{ name: "Theo Walcott", age: 24 } ,{ name: "Bacary Sagna", age: 28 } ].sort(function(obj1, obj2) {// 實現增序排列:前者的 age 小于后者…

html5手機簽名,html5手寫簽名

var canvas, board;canvas document.getElementById(myCanvas);canvas.height 300;canvas.width 400;board canvas.getContext(2d);board.lineWidth 1; //設置畫筆粗細board.strokeStyle "#f00";board.lineJoin "round"; //設置畫筆軌跡基于圓點拼接…

調查:Java程序員最傷心,C++程序員最年老

說起我們對編程世界現有的刻板印象,你一定聽說過類似于沒有人喜歡用Java編碼或者使用C 都是老人家,等等這樣的話。為了分析這些刻板印象背后的真相,Trestle Technology的數據工程師寫了一個工具。 不知道你有沒有聽說過微軟的Project Oxford&…

mysql一些寫常用命令

參見pcttcnc2007博客騰飛 1.mysql的status信息命令: mysql> show global status; 2.可以列出mysql服務器運行各種狀態值,另外,查詢mysql服務器配置信息語句: mysql> show variables; 3.連接數 經 常會遇見”mysql: error 1040: too man…

計算機不小心刪除怎么找回桌面,如何將桌面上誤刪的文件找回

在如今工作電腦化的趨勢下,用戶都會在桌面上創建各種各樣的文件等,這些文件都是需要在工作中經常要進行各種操作的重要文件,那么頻繁的操作也會出現各種的意外情況等,如果不小心刪除了重要的文件該怎么恢復呢?想要恢復…

《編程原本 》一3.3 程序變換

3.3 程序變換 power0是有關算法的一個令人滿意的實現,它適用于運算的代價高于函數遞歸調用開銷的情況.本節要推導出一個迭代算法,它執行運算的次數和power0一樣.這里將要做一系列程序變換,這些變換也可以用在其他許多情況中.5 在本書后面的部分,通常將只給出算法的最終版本或幾…

Effective C++ .07 virtual析構函數的提供

主要講了, 1. virtual析構函數的作用與調用順序 2. 使用時機,并不是使用了繼承就要把基類的析構函數變為虛函數(virtual),只有當用于多態目的時才進行一個virtual析構函數的定義。 3. 不要繼承那些沒有將析構函數定義為…

OnClickListener沖突的問題

OnClickListener沖突的問題 (2011-11-26 15:28:27) 轉載▼標簽: 雜談 分類: android學習記錄 import anfroid.view.View.OnClickListenerimport anfroid.content.DialogInterface.OnClickListener 這兩個東西要同時用的話,要使用以下方式&…

html 響應式 同一行,一行CSS實現各種響應式元素 – Fluidity

一行CSS實現各種響應式元素 – Fluidity3月 31, 2014評論SponsorFLUIDITY是一個極微小的CSS樣式表,壓縮版只有一行代碼,大小只有115個字節,它能實現圖像、文本、Canvas、Table表格以及iFrame框架的響應式功能。好用且實用!這個響應…

玩C一定用得到的19款Java開源Web爬蟲

網絡爬蟲(又被稱為網頁蜘蛛,網絡機器人,在FOAF社區中間,更經常的稱為網頁追逐者),是一種按照一定的規則,自動地抓取萬維網信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動索引、模擬程序或者蠕蟲。 今天將為…

一元二次方程

轉載于:https://www.cnblogs.com/569114a/p/4179164.html

cookie html5,HTML5——存儲(cookie、localStorage、sessionStorage)的區別

cookie本來用于客戶端和服務端通信,但是因為它有本地存儲的功能,于是被“借用”了。使用方法document.cookie 獲取和修改即可缺點存儲量太少,只有4kb所有http請求都帶著,會影響獲取資源的效率。API簡單,需要封裝才能使…

數據中心存在不當投資嗎?

不正當的投資是一種危害:在一些項目建設中,投入大量的資金是錯誤的,因為這些項目的需求是不可持續的或高估的。那么數據中心屬于這一類嗎? 投資不當的問題 不當投資會與經濟的繁榮與蕭條齊頭并進。例如,抑制按揭貸款利率可能會導…

問題:循環元素,被選中元素個數,全選

一段時間不寫js都有點忘記了&#xff0c;這里看幾個常見的js&#xff0c;涉及到循環&#xff0c;計算元素個數&#xff0c;checkbox選中等問題&#xff0c;首先是html元素 <div class"content border p05"><div><input type"checkbox" id&q…

LeetCodeOJ. String to Integer (atoi)

試題請參見: https://oj.leetcode.com/problems/string-to-integer-atoi/ 題目概述 Implement atoi to convert a string to an integer.Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the…

html如何設置滾動動畫,JavaScript 實現頁面滾動動畫

在做前端 UI 效果時&#xff0c;讓元素根據滾動位置實現動畫效果是一個非常流行的設計&#xff0c;通常我們會使用第三方插件或庫來實現。在本教程中&#xff0c;我將教大家使用純 JavaScript 和 CSS 來實現。先預覽一下實現的效果&#xff1a;我們使用 CSS 來實現動畫&#xf…