2009-03-01 178 views
6

假設我在[0,1]範圍內有一個浮點數,我想量化並將其存儲在一個無符號字節中。聽起來像一個沒有腦子,但實際上它是相當複雜:將浮點範圍轉換/量化到整數範圍

顯而易見的解決方案是這樣的:

unsigned char QuantizeFloat(float a) 
{ 
    return (unsigned char)(a * 255.0f); 
} 

這工作在迄今爲止,我得到的所有號碼從0到255,但分佈的整數是不均勻的。如果a正好是1.0f,該函數僅返回255。不是一個好的解決方案

如果我做適當的四捨五入我只是轉移了問題:

unsigned char QuantizeFloat(float a) 
{ 
    return (unsigned char)(a * 255.0f + 0.5f); 
} 

在這裏,結果0只覆蓋了浮動範圍比其他任何數量的一半。

我該如何做一個量化與平均分佈的浮點範圍?理想情況下,如果我量化均勻分佈的隨機浮點數,我希望得到平均分佈的整數。

任何想法?


btw:另外我的代碼是在C這個問題是語言不可知的。對於非C人員:只要假設floatint轉換會截斷浮點數。因爲我們在這裏有一些困惑:我需要一個映射,將最小的輸入float(0)映射到最小的unsigned char,並將我的範圍(1.0f)的最高浮點映射到最高的無符號字節(255)。

回答

10

a * 256f如何檢查減少256到255?因此,像:

return (unsigned char) (min(255, (int) (a * 256f))); 

(對於你的平臺上一個合適的最小功能 - 我不記得它的C函數)。

基本上你想的範圍分成256個等分,其中是應該做的。 1.0的邊界情況變爲256並且要求舍入僅僅是因爲域在兩端都是包含性的。

+0

哇 - 是的,就是這麼簡單! – 2009-03-01 16:15:50

1

我想你正在尋找的是這樣的:

unsigned char QuantizeFloat (float a) 
{ 
    return (unsigned char) (a * 256.0f); 
} 

這將均勻浮點值在[0,1]映射到[0,255]均勻字節值。對於i在0..255中的[i/256,(i + 1)/ 256 [(不包括(i + 1)/ 256))中的所有值被映射到i。什麼可能是不可取的是,1.0f映射到256.0f,其繞回到0.

0

可以在整個範圍內傳播一次性錯誤,同時保持平均分佈,就像你在12月31日閏秒。

limit = 4 
maxi = limit - 1 

n = 16 
for i in range(n): 
    x = i/(n - 1) 

    a = x * maxi # Wrong distribution 
    b = x * limit # One off 
    c = x * (limit - 1/limit) 

    print(f"{x:.3f} | {a:.3f} | {b:.3f} | {c:.3f}") 

-

0.000 | 0.000 | 0.000 | 0.000 
0.067 | 0.200 | 0.267 | 0.250 
0.133 | 0.400 | 0.533 | 0.500 
0.200 | 0.600 | 0.800 | 0.750 
0.267 | 0.800 | 1.067 | 1.000 
0.333 | 1.000 | 1.333 | 1.250 
0.400 | 1.200 | 1.600 | 1.500 
0.467 | 1.400 | 1.867 | 1.750 
0.533 | 1.600 | 2.133 | 2.000 
0.600 | 1.800 | 2.400 | 2.250 
0.667 | 2.000 | 2.667 | 2.500 
0.733 | 2.200 | 2.933 | 2.750 
0.800 | 2.400 | 3.200 | 3.000 
0.867 | 2.600 | 3.467 | 3.250 
0.933 | 2.800 | 3.733 | 3.500 
1.000 | 3.000 | 4.000 | 3.750