内核中比较float类型的方法

        因为近期在搞内核开发,整出一个内核文件系统,同时在核外提供了一系列API。文件系统支持时空索引,而空间索引采用float类型来表示。但是内核中并没有float类型,因此最初的方式是将float拆成整数部分和小数部分,这也好理解。但是第一版的设计者把这部分想的太简单了,把2.4拆成了2 和4分别用一个int32_t类型存储,这倒是没啥,但是很显然这种方式是错误的,因为还少了一个小数点后面的连续0的个数,比如2.04存成整数和小数就成了2和04了,但是04和4是一样的,也就是小数点后面的0没有保存。2.04转换成2和4,之后再转换回来就成了2.4了,这显然是不行的。

        一种解决方案,再增加一个字段来表示小数点后面的连续0的个数。但是这种方案很显然会继续增加空间占用量。以float占4个字节,int占4个字节为例,一个float就需要12个字节来表示(实际上,同事使用的是8字节的long)。而数据采集过程中,每一帧数据都有时空信息,也就是至少有3个float,则需要36字节来表示12个字节的内容。

        另外一种解决方案,从float的内存编码方式入手。经过查找资料确认,在c语言中,float使用的是sign*1.x*2^y这种形式来表示的。其中sign表示符号位,是float的4个字节的最高位,也就是第31位。后面的30-23共8位表示的是y,而x是由剩下的23位表示的。基于此,我进行了两次尝试:(1)提取符号位,提取指数段,提取小数段,然后根据三者的组合进行比较,也能成功,但是中间的移位操作把我彻底整崩溃了,因为能执行移位操作的是整形,float不支持,如果将一个float a,进行移位,则会将之先强转为int,再进行移位,比如1.4移位中,先把1.4变成了1再进行移位,这肯定是不行的。所以,我们必须先把float的内容赋值给一个int变量,通过memcpy的方式,不是用值赋值,而是内容赋值,这样将float的内容赋值给一个int,这个int就可以按照移位操作得到对应的符号位、指数段等了,且得到的内容是正确的。但这种方式需要3个步骤获取对应段,然后进行组合,判断谁大谁小,这种方式倒是没问题;(2)经过前面的尝试和分析float的存储方式,我发现根本不用提取那么多字段,可以直接比,对于float a、b,两个值,我们定义两个int变量c和d,使用memcpy(&c,&a,4)和memcpy(&d,&b,4);将a和b的内容赋值给c和d,那么对于c和d只有在c和d均为负数时,其比较结果与按照整数比较时相反,其余情况均与整数比较时一致。也就是得到如下的结论:

 

 搞定,剩下的就是把上述逻辑抽成一个函数即可,在核外参数是两个float,在核内则是两个int。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值