好问题!
我知道这个问题已经9岁了,我只知道您要寻找的答案的一部分,但是我来这里时遇到的是一个类似的问题,自提出该问题以来,很多事情已经发生了变化,例如可用的硬件和GPS 。我经常在处理与不同应用程序中的不同类型GPS兼容的固件中工作,却浪费了数小时(和几天)的时间,而我却花了很多时间(和天数)为与我合作或使用过的不同应用程序设计出“最佳设计”发达。
与往常一样,不同的解决方案将提供收益和成本,最终,“最佳设计”将始终是收益和成本与系统需求的“最佳匹配”。当我问同样的问题时,有一些事情我必须考虑:
CPU时间成本
如果CPU没有内置的浮点协处理器(许多微控制器就是这种情况),那么处理“ float”,“ double”和“ long double”会非常昂贵。例如,对于一个我经常使用的16位微控制器,使用“双”值的乘法运算将花费326个CPU时钟周期,而除法运算则花费1193个时钟周期。非常贵!
精度权衡
在赤道处,一个“浮点数”(IEEE-754 32位浮点值)需要表示一个带符号的度值,假设可以表示7个“干净的”有效十进制数字,那么一个最低有效十进制数字的变化(例如,从179.9999到180.0000)将代表约11.12米的距离。这可能会或可能不会满足硬系统精度要求。而“双”(代表15个“干净的”有效十进制数字,因此从179.999999999999变为180.000000000000)表示约0.00011毫米。
输入精度限制
如果您正在处理来自GPS的输入,那么您将获得多少位数的真实准确度,并且需要保留多少位数?
开发时间成本
IEEE-754的64位双精度值('double')和32位单精度值('float')在C语言中非常方便处理,因为几乎所有C编译器都附带了两者的数学库,并且通常非常可靠。如果您的CPU带有硬件浮点处理器,这是一个简单的选择。
RAM和存储成本
如果必须将大量这些值保留在RAM(或存储,例如MYSQL)中,则可用RAM(和存储空间)可能会影响解决方案的可操作性。
可用数据与必需数据
在撰写本文时,我正在处理的一个示例(来到这个问题的原因)是我正在处理一个u-blox M8 GPS,它能够为我提供二进制GPS信息(节省了转换ASCII NMEA的CPU开销。句子)。在这种二进制格式(称为“ UBX协议”)中,纬度和经度表示为带符号的32位整数,该表示形式能够表示(在赤道处)低至约1.11厘米的精度。例如,经度-105.0269805表示为-1050269805(使用所有32位),一个LSb的变化表示任何地方的纬度变化约为1.11厘米,在赤道处的经度约为1.11厘米(在较高的纬度处则较小,与余弦成比例)纬度)。GPS所使用的应用程序可以完成导航任务,而导航任务(已经存在且经过测试的代码)需要“ double”数据类型。不幸的是,仅通过将整数的基数2位移到“ double”的内部表示位中,就无法轻松地将该整数转换为IEEE-754 64位“ double”,因为要执行的十进制移位是以10为基数的十进制移位。取而代之的是以2为基数的十进制移位,那么整数的以2为基数的位数可以移到'double'的位域中,而只需很少的转换。但是a,我拥有的有符号整数不是这种情况。因此,这将使我在没有硬件浮点处理器的CPU上花费一个乘法:326个CPU时钟周期。仅通过将整数的基数2的位移动到“ double”的内部表示位中就无法轻松完成,因为要执行的十进制移位是10的基数十进制移位。取而代之的是以2为基数的十进制移位,则整数的以2为基数的位数可以移到'double'的位域中,而只需很少的转换。但是a,我拥有的有符号整数不是这种情况。因此,这将使我在没有硬件浮点处理器的CPU上花费一个乘法:326个CPU时钟周期。仅通过将整数的基数2的位移动到“ double”的内部表示位中就无法轻松完成,因为要执行的十进制移位是10的基数十进制移位。取而代之的是以2为基数的十进制移位,则整数的以2为基数的位数可以移到'double'的位域中,而只需很少的转换。但是a,我拥有的有符号整数不是这种情况。因此,这将使我在没有硬件浮点处理器的CPU上花费一个乘法:326个CPU时钟周期。但是a,我拥有的有符号整数不是这种情况。因此,这将使我在没有硬件浮点处理器的CPU上花费一个乘法:326个CPU时钟周期。但是a,我拥有的有符号整数不是这种情况。因此,这将使我在没有硬件浮点处理器的CPU上花费一个乘法:326个CPU时钟周期。
double ldLatitude;
int32_t li32LatFromGps;
ldLatitude = (double)li32LatFromGps * 0.0000001;
请注意,选择了此乘法:
ldLatitude = (double)li32LatFromGps / 10000000.0;
因为“双倍”乘法比我正在处理的CPU上的“双倍”除法快3.6倍。这就是微控制器世界中的生活。:-)
如果不是可以直接使用32位带符号整数完成导航任务,那将是BRILLIANT(将来可能,如果我可以在周末节省时间的话)。那么就不需要转换了。。。。。。。。。。CPU成本,可能效率更高。开发时间成本?这是另一个问题,尤其是在已经使用系统进行了充分测试的系统中,它使用的是IEEE-754 64位“ double”值!另外,已经存在提供地图数据(使用“双”度值)的软件,该软件也必须转换为使用带符号的整数-并非一夜之间!
一种非常有趣的选择是使用原始纬度/经度整数直接(不进行平移)表示“矩形”(实际上是梯形,在极点处变为三角形)的近似值之间的交点。在赤道处,这些矩形的尺寸为东西方向大约1.11厘米,南北方向为1.11厘米,而在说英国伦敦的纬度处,尺寸为大约0.69厘米的东西方向而向南1.11厘米。根据应用程序的需求,这可能不容易解决。
无论如何,我希望这些想法和讨论能对正在为该系统寻求“最佳设计”的其他人提供帮助。
亲切的问候,维克