GNSS的经纬度使用float还是doubble数据类型存储传输?

1. 背景

        当你在使用导航、打车、定位等等场景下,一定会有形或者无形的使用位置服务,位置服务的基础功能功能就是向你提供位置信息,而经纬度是位置信息的主要信息,一般情况可以简单的认为位置信息就是经纬度信息。经纬度使用小数进行表示,小数在计算机内部以浮点表示,在IEEE754浮点原理 - 计算机存储小数的误差有多少-CSDN博客文章浏览阅读1k次,点赞11次,收藏21次。本质上计算机内部使用浮点就是二进制小数的科学计算法表示,与相同长度的整数(如都为32位长度)相比能表示更大的范围,但是浮点并不是全范围内等精度,它会随着要表示的数的绝对值变大而精度逐渐变小。https://blog.csdn.net/bitslink/article/details/139078980        已知,使用浮点可能存在误差,而且这个误差会随这个数增加而增大。那经纬度应该使用单精度浮点float还是双精度浮点doubble类型呢?首先应该清楚什么是经纬度?

2. 什么是经纬度

        经纬度是一套球面的坐标系统,纬度是指球面任意一点与球心连线与赤道面的夹角,范围在-90°~90°,赤道面以北成为北纬(一般使用正数表示),赤道面以南成为南纬(一般使用负数表示)。经度是指地球面上一点与两极的连线与0度经线所在平面的夹角,范围-180~+180(负东经,正西经)。经纬度如下图在球面上如下图所示:

经纬度示意图

3. 经纬度使用Float(单精度)的误差

        经纬度浮点数的最大范围在-180°~+180°,参考IEEE754浮点原理 - 计算机存储小数的误差有多少-CSDN博客对该范围内浮点小数进行分辨率分析,分析源码如下:

#include "stdio.h"
#include "stdint.h"

#define  NUM 19
int main()
{
    float ff[NUM];
    float yy[NUM];
    float dd[NUM];
    uint32_t *p;

    for(int i=0;i<NUM;i++)
    {
        if(0 == i)
        {
            ff[i] = 0.1;
            yy[i] = ff[0];
            p = (uint32_t *)&yy[i];
            *p += 1;
        }
        else
        {
            ff[i] = ff[i-1]+10;
            yy[i] = ff[i];
            p = (uint32_t *)&yy[i];
            *p += 1;
        }

        dd[i] = yy[i] - ff[i];

        printf("%0.2f\t %0.9f\n",ff[i],dd[i]);
    }

    printf("x=[");
    for(int i=0;i<NUM;i++)
    {
        printf("%0.2f,",ff[i]);
    }
    printf("]\n"); 
    printf("y=[");
    for(int i=0;i<NUM;i++)
    {
        printf("%0.9f,",dd[i]);
    }
    printf("]"); 
}

         浮点分析源码的运行结果如下:

0.10 0.000000007

5.10 0.000000477

10.10 0.000000954

15.10 0.000000954

20.10 0.000001907

25.10 0.000001907

30.10 0.000001907

35.10 0.000003815

40.10 0.000003815

45.10 0.000003815

50.10 0.000003815

55.10 0.000003815

60.10 0.000003815

65.10 0.000007629

70.10 0.000007629

75.10 0.000007629

80.10 0.000007629

85.10 0.000007629

90.10 0.000007629

95.10 0.000007629

100.10 0.000007629

105.10 0.000007629

110.10 0.000007629

115.10 0.000007629

120.10 0.000007629

125.10 0.000007629

130.10 0.000015259

135.10 0.000015259

140.10 0.000015259

145.10 0.000015259

150.10 0.000015259

155.10 0.000015259

160.10 0.000015259

165.10 0.000015259

170.10 0.000015259

175.10 0.000015259

180.10 0.000015259

185.10 0.000015259

        将运行结果,绘图后如下: 

浮点小数在0~180内使用float分辨率(纵轴分辨率、横轴浮点数)

        上图中浮点小数在130~180时分辨率最低,此时float分辨率仅为1.5259*10^{-5}(十万分子1.5),由分辨率引入的误差也为1.5259*10^{-5},弧长计算公式 l=\frac{\pi*r*\theta}{180}

角度与弧长

        根据弧长公式以及地球半径约为6371km,将上面曲线图纵轴转换成弧长的分辨率后,结果如下:

0.10 0.000828467

5.10 0.053021874

10.10 0.106043749

15.10 0.106043749

20.10 0.212087497

25.10 0.212087497

30.10 0.212087497

35.10 0.424174994

40.10 0.424174994

45.10 0.424174994

50.10 0.424174994

55.10 0.424174994

60.10 0.424174994

65.10 0.848349988

70.10 0.848349988

75.10 0.848349988

80.10 0.848349988

85.10 0.848349988

90.10 0.848349988

95.10 0.848349988

100.10 0.848349988

105.10 0.848349988

110.10 0.848349988

115.10 0.848349988

120.10 0.848349988

125.10 0.848349988

130.10 1.696699977

135.10 1.696699977

140.10 1.696699977

145.10 1.696699977

150.10 1.696699977

155.10 1.696699977

160.10 1.696699977

165.10 1.696699977

170.10 1.696699977

175.10 1.696699977

180.10 1.696699977

185.10 1.696699977

角度与弧长分辨率(纵轴为弧长单位米、横轴为角度)

        经纬度在180°内对应弧长最低分辨率约为1.7米,而由分辨率导致的误差等于分辨率,最大存储误差为1.7米。若使用float对经纬度进行存储传输,那么由于采用了float单精度浮点会存在一定误差,这个误差最大值小于1.5米。对于中国经纬度范围为73.33~135.05,3.51~53.33,采用单精度浮点flaot最大的存储误差为1.7米,最小的存储误差为0.85米。

4. 经纬度使用double(双精度)的误差

        与float类似首先对0~180内的浮点数进行进度分析,分析C语言源码如下:

#include "stdio.h"
#include "stdint.h"
#include "math.h"

#define  NUM 40
int main()
{
    double ffd[NUM];
    double yyd[NUM];
    double ddd[NUM];
    uint64_t *pd;

    for(int i=0;i<NUM;i++)
    {
        if(0 == i)
        {
            ffd[i] = 0.1;
            yyd[i] = ffd[0];
            pd = (uint64_t *)&yyd[i];
            *pd += 1;
        }
        else
        {
            ffd[i] = ffd[i-1]+5;
            yyd[i] = ffd[i];
            pd = (uint64_t *)&yyd[i];
            *pd += 1;
        }
        
        ddd[i] = (yyd[i] - ffd[i])*M_PI*6371000/180.0;

        printf("%0.2f\t %0.17lf\n",ffd[i],ddd[i]);
    }

    printf("x=[");
    for(int i=0;i<NUM;i++)
    {
        printf("%0.2lf,",ffd[i]);
    }
    printf("]\n"); 
    printf("y=[");
    for(int i=0;i<NUM;i++)
    {
        printf("%0.17lf,",ddd[i]);
    }
    printf("]"); 
}

运行结果如下:

0.10 0.00000000000154314

5.10 0.00000000009876093

10.10 0.00000000019752187

15.10 0.00000000019752187

20.10 0.00000000039504374

25.10 0.00000000039504374

30.10 0.00000000039504374

35.10 0.00000000079008747

40.10 0.00000000079008747

45.10 0.00000000079008747

50.10 0.00000000079008747

55.10 0.00000000079008747

60.10 0.00000000079008747

65.10 0.00000000158017495

70.10 0.00000000158017495

75.10 0.00000000158017495

80.10 0.00000000158017495

85.10 0.00000000158017495

90.10 0.00000000158017495

95.10 0.00000000158017495

100.10 0.00000000158017495

105.10 0.00000000158017495

110.10 0.00000000158017495

115.10 0.00000000158017495

120.10 0.00000000158017495

125.10 0.00000000158017495

130.10 0.00000000316034990

135.10 0.00000000316034990

140.10 0.00000000316034990

145.10 0.00000000316034990

150.10 0.00000000316034990

155.10 0.00000000316034990

160.10 0.00000000316034990

165.10 0.00000000316034990

170.10 0.00000000316034990

175.10 0.00000000316034990

180.10 0.00000000316034990

185.10 0.00000000316034990

将结果绘制曲线图,如下:

浮点在0~180内使用double分辨率(纵轴分辨率、横轴浮点数)

        根据弧长公式:l=\frac{​{\pi}r\theta}{180},其中r为地球半径约为6371米、θ为角度,然后将上图的纵轴转换成弧长,如下图所示: 

角度与弧长分辨率(纵轴为弧长单位米、横轴为角度)

        使用double类型后,分辨率为3.16*10-9米(3.16纳米),由分辨率导致的存储误差等于分辨率除2,最大误差约为1.58纳米。 

5. 总结

        对于经纬度使用单精度float存储传输,分辨率误差随所在地的经纬度增加而增加,当经纬度大于130°后存储误最大的存储误差约为1.7米。对于普通GNSS测量误差一般10米数量级,此时使用单精度float后对总的误差影响不大;但使用了双频GNSS或者RTK GSNSS后测量,前者测量误差在2~3米,否则测量误差约为10cm数量级,这时若仍然使用单精度float存储,此时可能存在存储误差要大于测量误差,此次可以使用双精度浮点进行存储,虽然这可能带来存储空间的翻倍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/648100.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

五分钟”手撕“异常

目录 一、什么是异常 二、异常的体系和分类 三、异常的处理 1.抛出异常 2.异常的捕获 异常声明throws&#xff1a; try-catch处理 四、finally finally一定会被执行吗&#xff1f; 五、throw和throws区别 六、异常处理的流程 七、自定义异常 一、什么是异常 顾名…

Java顺序表

Java顺序表 前言一、线性表介绍常见线性表总结图解 二、顺序表概念顺序表的分类顺序表的实现throw具体代码 三、顺序表会出现的问题 前言 推荐一个网站给想要了解或者学习人工智能知识的读者&#xff0c;这个网站里内容讲解通俗易懂且风趣幽默&#xff0c;对我帮助很大。我想与…

ESP8266 接入阿里云物联网云平台

AT指令集参考资料 乐鑫科技&#xff1a;基础 AT 命令集 概念浅析 物模型 是对设备在云端的功能描述&#xff0c;包括设备的属性、服务和事件。物联网平台通过定义一种物的描述语言来描述物模型&#xff0c;称之为TSL&#xff08;即 Thing Specification Language&#xff0…

【学习笔记】3D-2D:PnP

主要解决什么问题&#xff1f; 主要解决的是已知空间中N个3D点及其图像中的2D点坐标&#xff0c;求相机在空间中的位置与姿态 求解PnP问题最少需要几个点&#xff1f; 最少只需要3个点对 求解PnP问题的常用方法 主要有用3对点估计位姿的P3P&#xff0c;另外还有DLT&#x…

前端如何学会全栈分页开发?源码和思路都在这了

本项目代码已开源&#xff0c;具体见&#xff1a; 前端工程&#xff1a;vue3-ts-blog-frontend 后端工程&#xff1a;express-blog-backend 数据库初始化脚本&#xff1a;关注公众号程序员白彬&#xff0c;回复关键字“博客数据库脚本”&#xff0c;即可获取。 前言 这是博客系…

商标注册申请名称的概率,多想名称选通过率好的!

近日给深圳客户申请的商标初审下来了&#xff0c;两个类别都下的初审&#xff0c;和当初的判断基本一致&#xff0c;普推知产老杨当时沟通说需要做担保申请注册也可以&#xff0c;后面选择了管家注册&#xff0c;最近大量的帮客户检索商标名称&#xff0c;分享下经验。 两个字基…

STM32H7系统窗口看门狗 (WWDG)应用方法介绍

目录 概述 1 认识窗口看门狗 (WWDG) 1.1 窗口看门狗定义 1.2 WWDG 主要特性 2 WWDG 功能说明 2.1 WWDG框图 2.2 WWDG 内部信号 2.3 控制递减计数器 2.4 看门狗中断高级特性 2.5 如何设置看门狗超时 3 WWDG 寄存器 3.1 控制寄存器 (WWDG_CR) 3.2 配置寄存器 (W…

如何调用通义千问大模型API

目录 登录阿里云 大模型服务平台百炼 登录控制台 QWen Long QWen 通义千问开源系列 大语言模型 OpenAI接口兼容 登录阿里云 阿里云-计算&#xff0c;为了无法计算的价值 大模型服务平台百炼 降价信息&#xff1a; 登录控制台 右上角取得API key 创建Key QWen Long qw…

C#的奇技淫巧:利用WinRM来远程操控其他服务器上的进程

前言&#xff1a;有时候远程服务器的进程你想偷偷去围观一下有哪些&#xff0c;或者对一些比较调皮的进程进行封杀&#xff0c;或者对一些自己研发的服务进行远程手动启动或者重启等&#xff0c;又不想打开远程桌面&#xff0c;只想悄咪咪地执行&#xff0c;那也许下面的文章会…

关于解决Qt在安装的时候没有勾选sources组件的方法

关于解决Qt在安装的时候没有勾选sources组件的方法 一、引言 在安装数据库连接到qt的时候发现没有sources文件夹&#xff0c;原来是安装的时候没有勾选sources组件&#xff0c;发现问题后找到了维护qt组件的安装方式&#xff0c;特此记下来 二、分析原因 首先在安装的时候就…

Lookin高效调试iOS App的UI

Lookin是一款iOS开发时常用的调试软件&#xff0c;由腾讯微信读书团队QMUI开发。 它可以查看和修改iOS App里的UI对象的软件&#xff0c;展示App UI图层&#xff0c;类似于Xcode自带的UI Inspector工具&#xff0c;或另一款叫做Reveal的软件。 此外&#xff0c;虽然Lookin主体…

【C++语言】继承:类特性的扩展,重要的类复用!

【C语言】继承&#xff0c;更进一步的复用 ✨精美思维导图奉上继承1. 继承的相关概念&#xff1a;2. 继承的定义&#xff1a;&#xff08;1&#xff09;定义格式&#xff1a;&#xff08;2&#xff09;访问限定符和继承方式&#xff1a;&#xff08;3&#xff09;默认继承方式&…

C++_C++11的学习

1. 统一的列表初始化 1.1&#xff5b;&#xff5d;初始化 在C98 中&#xff0c;标准就已经允许使用花括号 {} 对数组或者结构体元素进行统一的列表初始值设定。而到了C11&#xff0c;标准扩大了用大括号括起的列表 ( 初始化列表 )的使用范围&#xff0c;使其能适用于所有的内…

最大连续1的个数(滑动窗口)

算法原理&#xff1a; 这道题大眼一看是关于翻转多少个0的问题&#xff0c;但是&#xff0c;如果你按照这种思维去做题&#xff0c;肯定不容易。所以我们要换一种思维去做&#xff0c;这种思维不是一下就能想到的&#xff0c;所以想不到也情有可原。 题目是&#xff1a;给定一…

ESP32-C6接入巴法云,Arduino方式

ESP32-C6接入巴法云&#xff0c;Arduino方式 第一、ESP32-C6开发环境搭建第一步&#xff1a;安装arduino IDE 软件第二步&#xff1a;安装esp32库第三&#xff1a;arduino 软件设置 第二&#xff1a;简单AP配网程序第一步&#xff1a;程序下载第二步&#xff1a;程序使用第三步…

linux centos nginx配置浏览器访问后端(tomcat日志)

1、配置nginx访问tomcat日志路径 vim /usr/local/nginx/conf/nginx,conflocation ^~ /logs {autoindex on;autoindex_exact_size on;autoindex_localtime on;alias /home/tomcat/apache-tomcat-9.0.89-1/logs;}###配置讲解### 1、location ^~ /logs { … }: location&#xf…

代码随想录——从前序与中序遍历序列构造二叉树(Leetcode105)

题目链接 递归 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

构建智能化商场存包柜平台的数据结构设计

随着城市生活节奏的加快&#xff0c;人们对于便利的需求也越来越迫切。在城市中&#xff0c;商场存包柜平台成为了解决人们日常出行中行李存放问题的重要设施。为了更好地管理和运营这些存包柜&#xff0c;智能化商场存包柜平台的数据结构设计显得尤为关键。 一、需求分析与功能…

每日AIGC最新进展(12):在舞蹈视频生成中将节拍与视觉相融合、Text-to-3D综述、通过内容感知形状调整进行 3D 形状增强

Diffusion Models专栏文章汇总&#xff1a;入门与实战 Dance Any Beat: Blending Beats with Visuals in Dance Video Generation https://DabFusion.github.io 本文提出了一种名为DabFusion的新型舞蹈视频生成模型&#xff0c;该模型能够根据给定的静态图像和音乐直接生成舞蹈…

韩顺平0基础学Java——第11天

p234-249 又一个月了&#xff0c;时间过得好快啊&#xff0c;希望支棱起来 可变参数 public int sum(int ... nums){ } 这个nums是数组 细节&#xff1a; 1可变参数可以为0个&#xff0c;或任意个 2可变参数的实参可以为数组 3可变参数的本质就是数组 4可变参数可以和普通…