浮点与定点的二进制存储

1、浮点数和定点数存储

https://blog.csdn.net/niaolianjiulin/article/details/82764511

2、浮点转定点

本篇主要介绍另外一种浮点转定点的方式,并结合neon代码进行介绍(上面的浮点定点基础最好先看,大佬忽略)

static inline uint32_t fp32_to_bits(float f) {
	union {
		float as_value;
		uint32_t as_bits;
	} fp32 = { f };
	return fp32.as_bits;
}
int main()
{
    int32_t value[4] = {234,536,382,430};
    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为浮点的二进制小数转换为1.x * 2^{m}形式小数点的偏移数),

最后的结果是-m-1,范围为0-31(这里因为scale必须<1,所以m的范围为-32<=m<=-1)

4)最后用value 乘以vmultiplier在移位shift就可以得到最后结果,等价于value 乘以scale的四舍五入

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值