float 轉定點計算加法和乘法

2021-07-16 10:14:56 字數 3220 閱讀 7310

float 浮點數轉成定點數計算其加法和乘法

需要注意的是,以下的程式是建立在下述條件為真的情況下的:

(sizeof(float) == 4 && sizeof(long

long) == 8 && sizeof(int) == 4) == ture

也就是說,一定要保證float和int是佔4個位元組(32bits),long long是佔8個位元組(64bits)的。

1, 浮點數轉定點乘法

void fixedpointmul(float&a, float& b, float& res)

//實際尾數還要加上最前面的1,這裡用long long的原因是兩個24位數的乘法,最多是48位,已超出int

long

long ma = (ia & 0x7fffff) | 0x800000;

long

long mb = (ib & 0x7fffff) | 0x800000;

//碼位

int ea = ((ia >> 23) & 0xff) - 0x7f;

int eb = ((ib >> 23) & 0xff) - 0x7f;

//mul

long

long mc = ma * mb;//相當於a<< (23-ea) a<<(23-eb)

//計算階碼

//先計算最高有效位

int i = 0;

long

long tmp = mc;

while (tmp != 0)

int ec = i - 1 - (23 - ea + 23 - eb) + 0x7f;

//再右移mc msb 到第24位

//把msb移位到第24位

//把msb移位到第24位

if (i < 24)

mc = (mc << (24 - i)) & 0xffffff;

else

mc = (mc >> (i - 24)) & 0xffffff;

////標記兩個數的正負

int sa = 0;

if ((ia & 0x80000000) ^ (ib & 0x80000000))//xor

sa = 1;//negative

//float

//拼接成float

int rc = 0x00000000;

rc = rc | (mc & 0x7fffff);

rc = rc | ((ec << 23) & 0x7fffffff);

//判斷正負

if (sa == 1)

rc = rc | 0x80000000;

res = *(float*)(&rc);

return;

}

2, 浮點轉定點加法(減法可以認為是加上乙個負數)
#ifndef max

#define max(x,y) ((x)>(y) ? (x) : (y))

#endif

void fixedpointadd(float& a, float& b, float& res)

if (ib == 0)

//if ((ia & 0x7f800000 == 0x7f800000) | (ib & 0x7f800000 == 0x7f800000));

//實際尾數還要加上最前面的1

long

long ma = (ia & 0x7fffff) | 0x800000;

long

long mb = (ib & 0x7fffff) | 0x800000;

//碼位

int ea = ((ia >> 23) & 0xff) - 0x7f;

int eb = ((ib >> 23) & 0xff) - 0x7f;

//正負

int sa = ia & 0x80000000;

int sb = ib & 0x80000000;

//移動到48位並加上符號運算

if (ea > eb)

else

//考慮符號

ma = (sa == 0 ? ma : -ma);

mb = (sb == 0 ? mb : -mb);

long

long mc = ma + mb;

int i = 0;

long

long tmp = 0;

//結果符號

tmp = 0x8000000000000000;

int sc = ((mc & tmp) == 0 ? 0 : 1);

if (sc == 1)//說明結果是負數

//計算階碼

//先計算最高有效位

tmp = mc;

while (tmp != 0)

//code

int ec = 0x7f;

if (ea > eb)

ec += ea + (i - 48);

else

ec += eb + (i - 48);

//把msb移位到第24位

if (i < 24)

mc = (mc << (24 - i)) & 0xffffff;

else

mc = (mc >> (i - 24)) & 0xffffff;

////float

//拼接成float

int rc = 0x00000000;

rc = rc | (mc & 0x7fffff);

rc = rc | ((ec << 23) & 0x7fffffff);

//判斷正負

if (sc == 1)

rc = rc | 0x80000000;

res = *(float*)(&rc);

return;

}

最後需要注意的是,float佔4個位元組的情況下,在二進位制情況下,共有24bit數字是精確數字,轉換到十進位制數, 只有6位有效數字是絕對精確的,所以在兩個float數字比較其誤差時,應注意,第7位及以後的數字是無意義的。

比如說:12345.67888和12345.6999其實對於float的記憶體來說是一樣的,但是它們之間的絕對誤差是:0.02111,達到了2%。

再比如:123456.000和123456.9999,在float的記憶體上是一樣的,但是,其絕對差為0.9999。

所以用絕對差來表示兩個float數是否相近,是不合理的。

高精度加法和乘法

今天偶然看了一下某大神的模板,不經意翻到這個就順便 借 了一下 上 吧 date 2015 8 21 晚上 author itak motto 今日的我要超越昨日的我,明日的我要勝過今日的我 以創作出更好的 為目標,不斷地超越自己。include include include using name...

矩陣的加法和乘法

編寫乙個矩陣的加法函式 乙個矩陣的乘法函式,然後呼叫函式計算矩陣的和與積,並輸出。為了使函式更加通用,本次課程設計使用一維陣列來存放矩陣。問題的關鍵是如何將一維陣列與二維矩陣的元素之間建立對應關係。問題拓展 1 增加求矩陣的轉置 求矩陣的秩 求正方陣的行列式,求矩陣的鞍點元素的位置與值。2 將矩陣進...

高精度加法和乘法

今天偶然看了一下某大神的模板,不經意翻到這個就順便 借 了一下 上 吧 date 2015 8 21 晚上 author itak motto 今日的我要超越昨日的我,明日的我要勝過今日的我 以創作出更好的 為目標,不斷地超越自己。include include include using name...