cnos
发表于 2024-12-29 19:47:04
LAOXU 发表于 2024-12-29 07:35
刚才折算了一下, 1分 约 18.5m, 依靠单精度浮点数运算, 精度有点勉强, 由于浮点数的浮动性, 在小于1分时, ...
我用工具算了一下1分在广西这大概是2公里呢,可不是只有18.5米。
EasyLad
发表于 2024-12-29 20:18:45
cnos 发表于 2024-12-29 19:46
你这么说也没错,但是前面的大数在刚好跨界进位的时候,是不能忽略的。
比如109度59.3354分,再走几十米 ...
把坐标都按0.0001分量纲转换为32位整数,然后求出差值及各种计算,最后再转回去。比如109度59.3354分转换结果为65993354,单位为0.0001分,其实就是一个算法问题
王昱顺
发表于 2024-12-29 23:51:32
cnos 发表于 2024-12-29 19:46
你这么说也没错,但是前面的大数在刚好跨界进位的时候,是不能忽略的。
比如109度59.3354分,再走几十米 ...
大概是没有这么麻烦的,就按你给的例子来吧,假设接收到的数据存储在char dat里面。
只需要dat-='0';即可得到数字形式存储的一串数组。
此时从最低位往高位一路算过去,带上借位,就是普通的数学计算,想算多少位的数据都可以。
比如你给出的109593354(去掉小数点了),假设下一个是110000001。
那么给出一段示例程序:
#include<math.h>
#define MAX_DIGITS 9 // 假设最大9位数字(可根据需要调整)
// 函数:比较两个大数字符串的大小
// 返回值:1 表示 num1 > num2,-1 表示 num1 < num2,0 表示相等
int compare_large_numbers(const char* num1, const char* num2) {
for (int i = 0; i < MAX_DIGITS; i++) {
if (num1 > num2) return 1;
if (num1 < num2) return -1;
}
return 0;
}
// 函数:按位计算差值,并将结果转换为long类型
long subtract_large_numbers(const char* num1, const char* num2) {
long result = 0;
int borrow = 0;
// 从最低位开始逐位相减
for (int i = MAX_DIGITS - 1; i >= 0; i--) {
int digit1 = num1 - '0'; // 将字符转换为数字
int digit2 = num2 - '0'; // 将字符转换为数字
int temp_diff = digit1 - digit2 - borrow;
// 处理借位
if (temp_diff < 0) {
temp_diff += 10;
borrow = 1;
} else {
borrow = 0;
}
// 更新结果
result = result + temp_diff*pow(10,MAX_DIGITS-1-i);
}
return result;
}
// 主函数
int main()
{
// 输入两个数字字符串
const char num1 = "109593354";
const char num2 = "110000001";
// 比较两个数的大小
int cmp = compare_large_numbers(num1, num2);
long difference;
if (cmp > 0) {
// num1 > num2,直接计算 num1 - num2
difference = subtract_large_numbers(num1, num2);
} else if (cmp < 0) {
// num1 < num2,计算 num2 - num1,并取负
difference = subtract_large_numbers(num2, num1);
difference = -difference;
} else {
// num1 == num2,差值为 0
difference = 0;
}
// 输出结果
printf("diff:%ld",difference);
return 0;
}
LAOXU
发表于 2024-12-30 01:18:24
cnos 发表于 2024-12-29 19:47
我用工具算了一下1分在广西这大概是2公里呢,可不是只有18.5米。
我是这样估算的, 是否算法错???
1度 = 60分, 地球 1圈周长约 40000km,
则
1度 长度 = 40000/360= 111.1111km
1分 长度 = 111.1111/60 = 1.85km
结果和你的也相符, 只是我单位换算搞错了 {:tu:}
LAOXU
发表于 2024-12-30 01:35:20
麻烦就是两坐标相减后,余下的值很小,还要做平方,开根号(最简单的数学笛卡尔两点距离公式)没考虑球面的情况。
这样就显得不够用,希望是能在几米差距就能做出有效反应。
----------------------------------------------------------------------------------------------------------
用 老王的方法 相减, 余值很小的情况下, 无论 用 long 类型, 还是转换成单精度浮点数后再运算, 和用 双精度浮点数运算, 结果(精度)几乎无差别.
LAOXU
发表于 2024-12-30 02:12:38
以前有点时间, 想搞个非标的 C51 浮点库, 非常适合于你在这上面的应用, 只是网上讨论时, 反应不良, 最终没弄.
这段时间很忙, 也没空搞这个.
讨论一下, C51 的单精度浮点数, 实际应用中, 精度是否够???
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=6320
(出处: 国芯技术交流网站)
zxcv1973
发表于 2024-12-30 10:44:25
度数*600000+分数*10000,结果为32位整数,精度0.0001分。和时间的算法类似,比如求2小时38分29.78秒和3小时17分58.23秒的时间间隔,可把小时分秒值转换为单位为0.01秒的整数值后再求差值即可。
LAOXU
发表于 2024-12-31 06:14:46
zxcv1973 发表于 2024-12-30 10:44
度数*600000+分数*10000,结果为32位整数,精度0.0001分。和时间的算法类似,比如求2小时38分29.78秒和3小 ...
原始数据是 :度度度分分.分分分分分分
359度 59.999999分 = 359*60+59.999999 = 21599.999999 分
扩大 1000000倍, 折合整数 为 21599999999 = 0x50775d7ff, 9位十六进制数.
全范围内计算, long 类型 精度不够 !!!
zxcv1973
发表于 2024-12-31 11:53:06
LAOXU 发表于 2024-12-31 06:14
原始数据是 :度度度分分.分分分分分分
359度 59.999999分 = 359*60+59.999999 = 21599.999999 分
为什么非要扩大1000000倍,扩大10000倍后精度就满足要求了
LAOXU
发表于 2025-1-1 03:54:54
zxcv1973 发表于 2024-12-31 11:53
为什么非要扩大1000000倍,扩大10000倍后精度就满足要求了
刚才验证了一下, 确实如此. 扩大10000倍后, 分辩率就达到了 0.2m ,能满足要求.
有点好奇, 我网上查到的, 卫星定位原始数据是 :度度度分分.分分分分, '分'只有 6位有效数字.
而楼上网友列出的 卫星定位原始数据是 :度度度分分.分分分分分分, '分'有 8位有效数字.
不知是哪颗卫星?