2012-03-15 84 views
9

我需要將值存儲在-10000至10000範圍內。在範圍邊界處,所需的精度不是很高(也許大約是64,我會看到它是如何適合的),大約爲零,精度需要爲1或更好。尋找一個半浮點或四分之一浮點庫

不幸的空間是非常有限有限,不超過12位,更少甚至會更好。所以嚴格來說,即使half floats已經出來。是否有一個開源庫處理短尾數和指數長度的一些非常短的浮點格式?像8位尾數和3位指數。

只需要從/到更大格式的轉換,不進行算術運算。

+0

對於3位指數,您將有128個最小精度。 – xanatos 2012-03-15 13:42:40

+0

是的,最有可能的是,我最終會用自己的位域來烹飪。但我有興趣看到別人找到的解決方案 - 如果有的話。 – hirschhornsalz 2012-03-15 13:43:45

+0

@xanatos:只有當你堅持2的基數。如果你切換到10的基數,他只需要9位尾數,2位基數。 (準確度39附近10000) – 2012-03-15 18:16:12

回答

3

也許μ-lawA-law可能對您有用。

+1

哦,有趣的想法。你應該擴大這個答案。很多。 – 2012-03-15 17:46:10

+0

如果他從0-12精確到最接近的1,精度2從13-25,精度3從26-38 ...精度39從9671-10139,它適合9位! (離開第十位標誌)我不知道如何做這個數學雖然。 – 2012-03-15 18:24:06

+0

非常有趣。我在舊代碼中只實現了4個範圍的東西。現在我將嘗試找到一個有效的概括或抽象,並查看哪個範圍/值的比例最適合。 – hirschhornsalz 2012-03-15 19:01:46

4

如果你沒有做任何計算,那麼幾乎不需要庫。 frexp,ldexp和一些有點扭曲應該做的工作。

2

我們使用libHalf,它附帶openexr。由於代碼質量不是很好(雖然它也沒有被嚴重破壞),我並不是很喜歡它。在提取的源代碼中查找名爲Half的目錄 - 它應該是獨立的。

1

從延Björnhager的回答推斷,我得到這個:

double from_storage(unsigned short bits) { //only lowest 10 bits read 
     double a = bits&0x1FF; 
     a /= 5.11967985; 
     a = a*a; 
     return double(bits&0x200 ? -a : a); 
} 

unsigned short to_storage(double a) { //only lowest 10 bits set/relevant 
     assert(a<=10000.0); 
     assert(a>=-10000.0); 
     if (a >= 0) { 
       a = std::pow(a, .5); // inverse of number in from_storage 
       a *= 5.11967985; 
       unsigned short b = ((unsigned short)(a)); 
       assert((b&0x200)==0); 
       return b; 
     } else { 
       a = std::pow(-a, .5); 
       a *= 5.11967985; 
       unsigned short b = ((unsigned short)(a)); 
       assert((b&0x200)==0); 
       return b | 0x200; 
     } 
} 

截至http://ideone.com/DLTUn證明。這可以將每個值保持在-10和10之間,最高值僅相差39。 (0和1之間也有3個值)。更有可能的人更可能會得到正面和負面的更多的「兩個讚美」的格式,這將減少一半的代碼to_storage

+1

感謝您的意見。我想我會用μ-Law的一個變體(它非常類似於四分之一浮點數)擴展到11或12位。我需要存儲這些值中的幾個10^9(越多越好),這就是我想節省每一點的主要原因。轉換速度是另一個值得關注的問題 - pow最有可能放慢速度,但是一些桌面驅動的方法可以做到。 – hirschhornsalz 2012-03-15 22:42:29

+0

@drhirsch:除了平滑的曲線外,它與μ-Law的工作方式相同。基於表格的方法可能會更快,但會更復雜。我認爲這個表格是更好的答案。 – 2012-03-15 23:16:44