将uint32浮点表示转换为uint8
在没有太多细节的情况下,我有两个嵌入式系统,它们都不能使用浮点库.在它们之间是一个移动应用程序,在那里执行一些计算.一次计算需要保持精度.该值作为字节数组通过蓝牙发送到客户端.收到它后,我将其存储为uint32.然后,再次与需要精度的移动应用程序共享该值.那里没有问题,因为我可以使用
Java的ByteBuffer类.问题是我还需要将这个值与Z80微处理器作为uint8共享,因为它是通过UART传输的,并且用作ADC计数(0-255),因此它会失去精度(但不需要它)结束).
所以我在使用Java的移动应用程序中这样做: int bits = Float.floatToIntBits(fAdcCount); byte[] b = new byte[4]; b[0] = (byte)(bits & 0xff); b[1] = (byte)((bits >> 8) & 0xff); b[2] = (byte)((bits >> 16) & 0xff); b[3] = (byte)((bits >> 24) & 0xff); 然后,b以BLE特性写入BLE微控制器.然后,BLE微控制器将此缓冲区读取为小端32位字,并将其存储在uint32中.在调试器中查看这个uint32会显示正确的值,就像我上面说的那样,我可以将这个uint32放回一个字节数组并将其发送到移动应用程序并使用Java的ByteBuffer类读取它.这工作正常,我得到正确的浮点值. 问题是我需要这个浮点表示的整数部分作为uint8通过UART发送到Z80微处理器,因为它用作0-255的ADC计数. 那么,如何将一个被包装成uint32(小端字节顺序)的浮点值转换为uint8,从而失去精度?我也知道范围是0-255,这意味着转换时永远不会有大于255.0的范围. 例如,如果我有这个: uint32 fValue = 0x43246ADD; // = 164.417 …… 如何在不使用float的情况下得到它?: uint8 result = 164; 解决方法
一些经过轻度测试的代码可以启动OP.使用大量常量来允许自定义和各种程度的错误检查. OP没有解决舍入:舍入到最近,朝向0或??.截断为0.
#include <stdint.h> #define MANTISSA_BIT_WIDTH 23 #define BIASED_EXPO_MAX 255 #define EXPO_BIAS 127 #define SIGN_MASK 0x80000000 unsigned DN_float_to_uint8(uint32_t x) { if (x & SIGN_MASK) return 0; // negative int expo = (int) (x >> MANTISSA_BIT_WIDTH); if (expo == 0) return 0; // sub-normal if (expo == BIASED_EXPO_MAX) return 255; // Infinity,NaN expo -= EXPO_BIAS; if (expo > 7) return 255; // too big if (expo < 0) return 0; // wee number uint32_t mask = ((uint32_t)1 << MANTISSA_BIT_WIDTH) - 1; uint32_t mantissa = mask & x; mantissa |= mask + 1; mantissa >>= (MANTISSA_BIT_WIDTH - expo); return mantissa; } #include <stdio.h> int main() { printf("%un",DN_float_to_uint8(0x43246a00)); // 164 printf("%un",DN_float_to_uint8(0x437e0000)); // 254 printf("%un",DN_float_to_uint8(0x437f0000)); // 255 printf("%un",DN_float_to_uint8(0x43800000)); // 256 printf("%un",DN_float_to_uint8(0x3f7fffff)); // 0.99999994 printf("%un",DN_float_to_uint8(0x3f800000)); // 1 printf("%un",DN_float_to_uint8(0x40000000)); // 2 return 0; } 产量 164 254 255 255 0 1 2 有用IEEE 754 Converter 要将正值舍入到最接近的(许多处理方式),从零开始,只需看看要移出的最后一位. // mantissa >>= (MANTISSA_BIT_WIDTH - expo); // return mantissa; // shift as needed expect for 1 bit mantissa >>= (MANTISSA_BIT_WIDTH - expo - 1); // now shift last bit mantissa = (mantissa + 1) >> 1; // Handle special case if (mantissa >= 256) mantissa = 255; return mantissa; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows-8 – 用于图标的Segoe UI符号中的字形名称是什么
- Windows批处理脚本url解码
- 在COM dll上使用tlbexp.exe
- windows-10 – Windows 10,两个不同会话的监视器
- windows-phone-7 – WP7 Mango中的相机捕捉
- windows-server-2012 – Windows Server 2012上的FTP服务器
- Windows – Active Directory GPO中的SID
- windows-7 – 在Windows 7上递归设置权限
- 如何从Windows锁定Windows(如“Windows L”)?
- 更改在R Windows GUI中运行脚本的Cntrl R快捷方式
- 在windows中如何并行化?例子?
- osx – 可以在Windows机器上运行VMWare Fusion映
- Windows DNS是否自动注册所有域成员?
- windows-server-2008 – 防止RDP回复域名
- windows – AD:你能成为无限团体的成员吗?
- tinymce-3 – TypeError:window.tinyMCE.execIn
- 安装程序 – NSIS与Windows游戏资源管理器集成
- windows – 是否可以禁用msiexec帮助GUI?
- Win7程序运行出现Windows Based Scrip Host 已停
- windows-phone-7 – windows 7手机 – 关闭键盘