Java十六进制浮点文字
我如何遇到十六進制浮點數
我正在Java :: Geci中開發一種新功能,以減少代碼重新格式化的可能性。 如果重新格式化,當前版本的代碼將覆蓋原本相同的代碼。 這很煩人,因為按下重新格式化鍵的快捷鍵相當容易,而且許多項目甚至要求開發人員將其編輯器設置為在保存時自動格式化代碼。 在這種情況下,不能使用Java :: Geci,因為一旦重新格式化了代碼,生成器就會認為生成的代碼與源文件中已經存在的代碼不同,會對其進行更新并發出代碼更改失敗的信號。單元測試。
我正在設計的解決方案首先將Java源文件進行比較,然后將其轉換為詞匯元素列表。 這樣,只要代碼保持不變,您甚至可以重新格式化插入換行符,空格等的代碼。 為此,我需要一個簡化的Java詞法分析器。 編寫詞法分析器沒什么大不了的,自從我在1987年首次閱讀《 龍書》以來,我出于不同的原因創建了多個詞法分析器。我真正需要的唯一是精確定義字符串,字符,數字文字,關鍵字和以此類推。 簡而言之:Java語言在詞匯級別上的定義是什么以及如何處理。 幸運的是,對此有一個精確的定義,即Java語言規范 ,它不僅精確而且可讀,并帶有示例。 因此,我開始閱讀相應的章節。
令我感到困惑的是,我可以看到Java語言中有可能用十六進制表示浮點數。 奇怪嗎 由于我從未見過它,所以我首先以為這是Java 12中引入的新內容,但我的調查表明它可能是在Java 1.5中引入的。那是我真正喜歡的第一個Java版本,但不是因為十六進制浮點數。 所以這就是我面對面遇到這只野獸的方式。 我開始懷疑這頭野獸是否可以在野外找到,還是只能在JLS文本范圍內被俘虜的東西。 所以…
我在Twitter上投票
如您所見,九個人面的人回答了這個問題,主要是說他們對這個功能一無所知。
在lambda和流之后,可能十六進制浮點數是Java語言中鮮為人知和使用最少的功能(開個玩笑……十六進制浮點數很重要,對嗎?)
即使我過去做過一些科學研究,也看不到十六進制浮點字面量的任何使用。
什么是浮點數?
我們將使用十六進制浮點數,但要了解我們必須首先知道什么是浮點數。
浮點數具有尾數和指數。 尾數具有整數和小數部分,例如iii.ffff 。 指數是整數。 例如,31.415926E-1是浮點數,是圓的直徑和周長之比的近似值。
Java內部將float存儲在32位上 ,將double float數存儲在64位上 。 實際比特根據IEEE 754標準使用。
這樣,這些位將符號存儲在單個位上,然后將指數存儲在8位或11位上,最后將尾數存儲在23位或52位上,分別用于32位或64位浮點/雙精度。 尾數是一個小數,其值在1到2之間。這可以用位流表示,其中第一位表示1,第二位表示1/2,依此類推。 但是,由于該數字始終以規范化存儲,因此該數字始終在[1和2之間],因此第一位始終為1。無需存儲它。 存儲尾數,以便最高有效位表示1/2,下一個1/2 2以此類推,但是當我們需要該值時,將其加1。
尾數是無符號的(因此我們有一個單獨的signum位)。 指數也是無符號的,但是計算出的實際移位數是從該值中減去127或1023以獲得有符號數。 它指定尾數實際上應向左或向右移動多少位。 因此,當我們寫31.415926E-1f ,指數將不是-1。 那是數字的十進制格式。
實際值為01000000010010010000111111011010 。 分解:
- 0號,數字為正。 到目前為止,一切都很好。
- 10000000 128,這意味著我們必須將尾數左移一位(該值乘以2)
- 10010010000111111011010是 。 該位流的十六進制表示為0x490FDA
這是
十六進制浮點文字
我們可以在Java中編寫與0x0.C90FDAP2f相同的數字。 這是相同數字的十六進制浮點表示形式。
尾數0xC9aFDA應該熟悉0x490FDA以上數字的十六進制表示0x490FDA 。 不同之處在于,第一個字符是C而不是4 。 那是額外的一位,始終為1,不存儲在二進制表示中。 C是1100而原始4是0100 。 指數是將數字推到正確位置所需的實際位移的帶符號十進制表示形式。
文字的格式并非無關緊要。 首先,您必須使用指數部分,并且指數的字符為p或P 這與十進制表示形式有很大不同。 (更新:如果指數是可選的,則您無法確定例如0.55是十進制浮點還是十六進制浮點。十六進制數字偶然可以僅包含十進制字符,而仍然是十六進制。)
經過一番思考,很明顯無法使用常規e或E來表示指數,因為該字符是合法的十六進制數字,并且在數字(如0x2e3情況下可能會模棱兩可。 這是十六進制整數還是。 這是整數,因為我們使用p而不是e 。
我只能猜測為什么指數部分是強制性的。 因為開發人員已經習慣使用e或E作為指數來十進制浮點數,所以很容易將0xC90F.0e+3誤讀為單個浮點數,即使需要十六進制浮點p而不是e 。 如果指數不是強制性的,則此示例將是浮點數與整數的合法和。 同時看起來像一個數字,那不是很好。
另一個有趣的事情是指數是十進制。 這也是因為某些十六進制數字已被用于其他目的。 浮點數和雙后綴。 如果要表示文字是浮點數,則可以將f或F附加到末尾。 如果要表示此文字為double,則可以將d或D附加到末尾。 這是默認設置,因此添加D是可選的。 如果指數是十六進制的,我們將不知道0x32.1P1f是浮點文字還是雙精度數,并且具有很多大小不同的值。 這樣,那個指數是十進制,它是一個浮點數。
Java和IEEE 754
Java在Java 1.2之前一直嚴格執行IEEE 754標準,該標準不僅定義了存儲在內存中的數字格式,而且還定義了應如何執行計算的規則。 Java 1.2版(包括1.2版)之后,發布了該標準以使實現更加自由,從而允許使用更多的位來存儲中間結果。 它曾經并且仍然可以在Intel CPU平臺上使用,并且在諸如FORTRAN之類的其他語言的數值計算中被大量使用。 這是允許實現使用更高精度的邏輯步驟。
為了保持向后兼容性,同時在語言中添加了strictfp修飾符。 在類,接口或方法上使用此修飾符時,這些代碼中的浮點計算將嚴格遵循IEEE 754標準。
帶走
- Java中有十六進制浮點文字。 記住它以及strictfp是什么,因為有人可能在Java采訪中問您有關它的問題。 在企業編程中沒有實際用途。
- 除非使代碼更具可讀性,否則不要使用它們。 我幾乎無法想象會發生這種情況的任何情況。 因此,簡而言之:不要僅僅因為可以就使用它們。
- 在Twitter @verhas上關注我,以獲取有關新文章的通知。
關注@verhas
我認為僅此而已。 在本文發表時,我可能會和一萬人一起在蘇黎世湖中游泳。 這是一個大事件。
哦……是的:如果您曾經在Java中使用十六進制浮點文字來使其更具可讀性,請在注釋中分享知識。 我敢于以讀者的名義說:我們很感興趣。
更新:約瑟夫·達西(Joseph Darcy)(Oracle的工程師,OpenJDK開發人員,馬拉松運動員,快步手,偶爾的攝影師,還有很多其他事情。)在Twitter上提供了反饋。 我將他的回復復制到這里,因為它絕對有價值,并為讀者增加了價值,從而使讀者受益:
十進制字符串和二進制浮點值的特定設置之間的映射通常是不明顯的。 十六進制浮點文字在需要時(例如在測試中)提供了直接的文本到二進制fp映射。 參見https://blogs.oracle.com/darcy/hexadecimal-floating-point-literals
翻譯自: https://www.javacodegeeks.com/2019/07/java-hexadecimal-floating-point-literal.html
總結
以上是生活随笔為你收集整理的Java十六进制浮点文字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lombok 生成代码_使用Projec
- 下一篇: 任正非称从来没有说“打倒美国