首页 > 其他分享 >[嵌入式RTOS]记录一下因浮点数转为字符串导致精度损失所踩的坑

[嵌入式RTOS]记录一下因浮点数转为字符串导致精度损失所踩的坑

时间:2023-03-21 19:59:12浏览次数:51  
标签:some lon 浮点数 RTOS 1000000 嵌入式 enlarged double lat

1.起因:

工作中对接平台需要将设备的GPS数据传给平台,但是平台采用的不是回调函数将数据直接作为参数返回而是格式化的字符串命令,所以需要将double类型的gps数据格式化输出到字符串中,项目中之前采用的是sprintf进行格式化输出,但是通过打印对比发现有精度损失,所以改成先放大数据1000000倍(数据有6位小数),然后整数部分通过做除法获得,小数部分通过取模运算获得。

void report_gps_info(double lon,double lat)
{
  //some codes
  sprintf(gpsinfo,"%.6lf&%.6lf",lat,lon);
  //some codes
}

void report_gps_info(double lon,double lat)
{
  //some codes
  UINT32 enlarged_lat = lat*1000000;   //added by xxx to solve the problem of loss of accuracy
  UINT32 enlarged_lon = lon*1000000;
  sprintf(baseinfo,"%d.%d&%d.%d",enlarged_lat/1000000,enlarged_lat%1000000,enlarged_lon/1000000,enlarged_lon%1000000);
  //some codes
}

2.再次出问题:

修改后当时测试还是有精度损失,不过只在最后一位差了1影响微乎其微就没怎么在意,于是提交了代码,merge后隔了几天分公司同事测试发现地图上位置出现了很大偏移,查看log发现是数据经过这个函数处理后出的问题,只有经度错误,纬度数据正常,对比查看发现原因是经度数据小数第一位为0,乘1000000后取模让前面的0出现了丢失导致的。

3.最终解决方案:

最终在取模结果也就是小数部分的格式控制上加了位宽限制解决了问题。

void report_gps_info(double lon,double lat)
{
  //some codes
  UINT32 enlarged_lat = lat*1000000;   //added by xxx to solve the problem of loss of accuracy
  UINT32 enlarged_lon = lon*1000000;
  sprintf(baseinfo,"%d.06%d&%d.06%d",enlarged_lat/1000000,enlarged_lat%1000000,enlarged_lon/1000000,enlarged_lon%1000000);
  //some codes
}
1、%d 普通的整数输出
2、%6d 整数输出,宽度是6位,不足左边补空格
3、%06d 整数输出,宽度是6位,不足左边补数字0
4、%-6d 整数输出,宽度是6位,不足右边补空格
5、%.6f 输出小数,即保留小数点后6位

4.反思:

当时提交代码前测试所处位置的gps数据小数位第一位正好不为0就没注意到这个问题,考虑问题真的不够全面。。。在处理这种数据问题时应该更严谨和考虑更多种情况的,突然又想起上次改动最小系统进行OTA升级代码时没有加宏控,从而导致在升级时调用非最小系统代码让系统卡死的事,也是因为考虑问题不全面,自测流程也不完整导致的。将这些经历记录于此,希望以后不再踩此类的坑。

标签:some,lon,浮点数,RTOS,1000000,嵌入式,enlarged,double,lat
From: https://www.cnblogs.com/blog-of-rml/p/17241188.html

相关文章

  • #创作者激励#嵌入式好用工具—软件篇【新人向】
    【本文正在参加2023年第一期优质创作者激励计划】文件下载在gitee仓库:https://gitee.com/lalhan/embedded-tool-sharing视频:https://www.bilibili.com/video/BV1rx4y1T7Jf......
  • 嵌入式硬件电路设计的基本技巧
        不光是代码有可读性的说法,原理图也有。很多时候原理图不仅仅是给自己看的,也会给其它人看,如果可读性差,会带来一系列沟通问题。所以,要养成良好习惯,做个规范的原理图。......
  • RTOS 最常用的一种扩展— AT 设备包
    RTOS使用的是模块方式,以便于扩展,这一点跟  类似。各种软件包可以让开发者将RTOS用于任何想要的目标设备。RTOS最常用的一种扩展是AT设备包,它包含各种不同AT设备(......
  • 嵌入式开发中常用的条件编译
    条件编译命令常见形式:1#ifdef标识符2程序段13#else4程序段25#endif作用:当标识符被#define定义过,则对程序段1进行编译,否则编译程序段2。常用形式2:#ifndef......
  • 浮点数编码原理
    1前言​计算机中浮点数的编码,由美国加州大学的WilliamKahan教授于1985年设计,后被IEEE借鉴,制定出IEEE浮点标准。​浮点数在计算机中的二进制编码由符号......
  • 蓝桥杯嵌入式——I2C总线
    配置根据原理图进行配置    官方提供的文件 编程 首先编写一个读的函数1unsignedchareeprom_read(unsignedcharaddr)2{3unsignedchar......
  • 蓝桥杯嵌入式——输入捕获的补充
    输入捕获除了可以测量频率,也可以测量占空比配置 首先是定时器2的配置,通道一直接捕获,测量上升沿,通道二间接捕获,测量下降沿    定时器3同上编程(中断部分)这个程......
  • 【2023全球半导体IC新品盛宴】一年一度Embedded World全球顶级嵌入式会展结束,盘点各大
     今年我们国内也有越来越多的厂家开始参展,下面逐一将这三天搜集整理的资讯给大家做个分享【视频版】https://www.bilibili.com/video/BV1CX4y1f7Fx【ST意法半导体......
  • 嵌入式数据库-分析型数据库-DuckDB
    数据库按照是否是关系型关系型数据库可分为交易型数据库(OLTP)、分析型数据库(OLAP)和混合负载数据库(HTAP)。交易型数据库满足处理在线的实时交易事务场景,......
  • 全志R128芯片 如何在FreeRTOS下对代码源文件进行快速预处理?
    1.主题FreeRTOS_R128_如何对代码源文件进行快速预处理2.问题背景硬件:R128软件:FreeRTOS客户在日常的开发过程中,会碰到源文件中有许多的宏或许多条件编译的代码,有时候需......