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位有效数字.
不知是哪颗卫星?
页: 1 2 [3] 4
查看完整版本: B版 AI8H2K12U-45I-TSSOP20 工程样片刚回来,2025年6月开始供货