一種高效能定點數方案

2021-10-02 15:40:16 字數 1313 閱讀 8553

一種高效能定點數方案

1,原理

int32表示乙個浮點數,32位符號位,3111位表示整數,101表示小數部分。則小數可表示精度為1/(210),整數表示範圍為[-221 ~ 2^21],大概正負209萬左右。可根據需求調整整數和小數部分位數,也可使用int64來儲存獲得更大表示範圍和更高精度。

2,公式

設int自身值為raw,表示的浮點數為f,小數字數為bits,則有:f=raw*(2^-bits)

3,加減法

因為小數精度一致,無需做對齊,直接raw相加減

4,乘法

f1f2=raw1raw2*(2-2bits),即商的raw為raw1*raw2*(2-bits)。需關注溢位

5,除法

f1/f2=raw1/raw2,則結果的raw為raw1/raw2*(2^-bits)。需注意如除數不為0,需保證結果也不為0,即如果精度原因導致結果算出為0,也要使結果raw為1or-1,即取最小非0數。保證非0float相除,結果必非0這一特性

6,開方

向量歸一常用操作,長除法手動開方

7,擴充套件表示範圍

假如int32用10位表示小數,則精度為1/1024,整數範圍為2^21大概正負209萬。

某些場合下會有更高精度的需求,比如三角函式運算,orca演算法等,會要求精度達到1/100000以上,將小數字數擴充套件到20位可滿足精度,但整數範圍會降到2^11 即正負2048,範圍太小。可考慮使用int64來儲存,則小數字數20的情況下,整數的理論範圍是正負2 ^43。

使用int64儲存,需考慮運算時溢位,即兩個int64相乘應使用int128來儲存中間結果,但int128依賴語言,比如c++不是所有編譯器都支援int128,而c#沒有。

在不支援int128的環境下使用int64的乘法,思路如下:將整數和小數部分拆開,用多項式展開來避免int64相乘溢位。

比如:兩個int64相乘,假設小數精度為20位,raw1整數部分rawint1=raw1>>20,小數部分rawf1=raw1&(0xffffffff>>12),raw2同理,則有:結果raw=((rawint1<<20+rawf1)(rawint2<<20+rawf2))>>20

展開可得:

raw=(rawint1rawint2)<<20+rawint1rawf2+rawf1rawint2+(rawf1rawf2)>>20

分析可知最容易溢位的是rawint1rawint2,只要保證二者乘積小於2(63-20)即可,即任一定點數整數表示範圍不超過2(43/2),就必不會溢位,大概是正負290萬。即精度為1/(2^20)時,整數表示範圍為正負290萬。可以滿足對精度有高要求的計算,如orca避障演算法對於小數精度的要求(0.00001)

計組定點數運算一 加法

mooc 計算機組成原理 河南科技大學 方法一 兩同號數相加時,如果結果的符號與參與運算的的運算元符號相反,則表明有溢位 兩異號數相減時,如果結果的符號與被減數符號相反則表明有溢位。v 1 溢位 v 0 不溢位 例 方法二 採用雙符號位 每個運算元的補碼符號用兩個二進位制位表示,稱為變形補碼,用 0...

連線池 一種高效能的解決方案

最近在做乙個移動的開發專案,整個專案兼有後台和客戶端,客戶端是安裝在android終端上的,需要和伺服器端進行龐大的資料互動。之前雖然有做過一些web端的資料庫程式設計,但是還知識停留在了練習和學習的水平上,有很多現實的問題並沒有考慮非常多。但是這次接觸的是乙個商業專案,而且預估的使用者群是乙個非常...

一種高效能的伺服器處理框架

by obroot posted 2014年7月28日 0 comment 1 首先需要乙個記憶體池,目的在於 減少頻繁的分配和釋放,提高效能的同時,還能避免記憶體碎片的問題 能夠儲存變長的資料,不要很傻瓜地只能預分配乙個最大長度 基於slab演算法實現記憶體池是乙個好的思路 分配不同大小的多個塊,...