浮點與定點的二進位制儲存

2021-09-26 06:18:38 字數 1985 閱讀 9451

本篇主要介紹另外一種浮點轉定點的方式,並結合neon**進行介紹(上面的浮點定點基礎最好先看,大佬忽略)

static inline uint32_t fp32_to_bits(float f)  fp32 = ;

return fp32.as_bits;

}

int main()

; int32x4_t vacc0x0123 = vld1q_s32(value);

float scale = 0.05434;

const uint32_t scale_bits = fp32_to_bits(scale);

/* multiplier is in [0x40000000, 0x7fffff80] range */

int32_t multiplier = (int32_t)(((scale_bits & uint32_c(0x007fffff)) | uint32_c(0x00800000))<<7 );

assert(multiplier >= int32_c(0x40000000));

assert(multiplier <= int32_c(0x7fffff80));

/* shift is in [0, 31] range */

const int32_t shift = 127 + 31 - 32 - (fp32_to_bits(scale) >> 23);

assert(shift >= 0);

assert(shift < 32);

int32_t right_shift = -shift;

const int32x4_t vmultiplier = vld1q_dup_s32(&multiplier);

vacc0x0123 = vqrdmulhq_s32(vacc0x0123, vmultiplier);

const int32x4_t vright_shift = vld1q_dup_s32(&right_shift);

const int32x4_t vzero_shift_mask = vreinterpretq_s32_u32(vceqq_s32(vright_shift, vmovq_n_s32(0)));

vacc0x0123 = vsraq_n_s32(vacc0x0123, vbicq_s32(vacc0x0123, vzero_shift_mask), 31);

vacc0x0123 = vrshlq_s32(vacc0x0123, vright_shift);

int32_t result[4];

vst1q_s32(result, vacc0x0123);

printf("%f %f %f %f\n",(value[0]*scale),(value[1]*scale),(value[2]*scale),(value[3]*scale));

printf("%d %d %d %d ",result[0],result[1],result[2],result[3]);

return 0;

}

1)首先看fp32tobits函式,巧妙利用聯合體公用記憶體空間轉換float資料型別為uint32_t

等價於const uint32_t scale_bits = *(uint32_t*)(&float)

2)得到浮點的二進位制後,將有效位取出,並左移七位得到int32_t得到vmultiplier 

3)接下來就是比較費解的一步,

就是const int32_t shift = 127+31-32-(fp32tobits(scale)>>23)

(fp32tobits(scale)>>23)比較好理解就是獲得符號位與基數字,即127+m (m為浮點的二進位制小數轉換為

最後的結果是-m-1,範圍為0-31(這裡因為scale必須<1,所以m的範圍為-32<=m<=-1)

4)最後用value 乘以vmultiplier在移位shift就可以得到最後結果,等價於value 乘以scale的四捨五入

二進位制 二進位制起源

現代通訊技術的基礎是二進位制編碼。早在1865年麥克斯韋總結出麥克斯韋方程組之前,美國人摩斯 morse 於1837年發明了摩斯電碼和有線電報。有線電報的出現,具有劃時代的意義 它讓人類獲得了一種全新的資訊傳遞方式,這種方式 看不見 摸不著 聽不到 完全不同於以往的信件 旗語 號角 烽火,這也是二進...

浮點數的二進位制

1.前幾天,我在讀一本c語言教材,有一道例題 include void main void 在我的編譯器下 編譯是會發生錯誤的。錯誤 cannot convert from int to float win7 vc6.0 sp6 執行結果如下 num的值為 9 pfloat的值為 0.000000 ...

二進位制的儲存方式

二進位制的原碼 反碼 補碼 一 原碼 是一種計算機中對數字的二進位制定點表示方法,原碼不分正負他們的第一位都是符合位0代表正1代表負。比如 10的二進位制為 00000000 00000000 00000000 00001010。10的二進位制為 10000000 00000000 00000000...