嵌入式开发中C语言的浮点数处理问题(1)

给CC1101写寄存器,根据用户指定的Frequency deviation,按公式计算

反反推DEVIATION_M和DEVIATION_E的值,

写入DEVIATN,寄存器描述如下:

 借ChatGPT生成的代码,把f_dev定义为了double,测试了下,是可用的

#include <stdio.h>
#include <math.h>
#include <float.h>  // For DBL_MAX

#define FXOSC 27000000  // 27 MHz

int find_deviation_parameters(double f_dev, int *DEVIATION_M, int *DEVIATION_E) {
    // Calculate the constant K
    double K = (f_dev * pow(2, 17)) / FXOSC;
    
    // Initialize variables to find the closest match
    double closest_f_dev_diff = DBL_MAX;
    int best_DEVIATION_M = -1, best_DEVIATION_E = -1;

    // Iterate over possible values of DEVIATION_E
    for (int DEVIATION_E_local = 0; DEVIATION_E_local < 8; DEVIATION_E_local++) {
        // Calculate the potential DEVIATION_M value
        double potential_M = K / pow(2, DEVIATION_E_local) - 8;
        
        // Check if potential_M is within the valid range (0 to 7)
        if (potential_M >= 0 && potential_M < 8) {
            // Calculate the actual deviation frequency for this pair
            double actual_f_dev = (FXOSC / pow(2, 17)) * (8 + (int)potential_M) * pow(2, DEVIATION_E_local);
            double f_dev_diff = fabs(f_dev - actual_f_dev);
            
            // Check if this is the closest match so far
            if (f_dev_diff < closest_f_dev_diff) {
                closest_f_dev_diff = f_dev_diff;
                best_DEVIATION_M = (int)potential_M;
                best_DEVIATION_E = DEVIATION_E_local;
            }

            // If potential_M is an integer within the valid range (0 to 7), we have an exact match
            if (floor(potential_M) == potential_M) {
                *DEVIATION_M = (int)potential_M;
                *DEVIATION_E = DEVIATION_E_local;
                return 1;  // Success with an exact match
            }
        }
    }

    // If no exact valid pair is found, return the closest match
    if (best_DEVIATION_M != -1 && best_DEVIATION_E != -1) {
        *DEVIATION_M = best_DEVIATION_M;
        *DEVIATION_E = best_DEVIATION_E;
        return 1;  // Success with the closest match
    }
    
    // If no valid pair is found at all, return 0 to indicate failure
    return 0;
}

int main() {
    double f_dev = 5000;  // Example frequency deviation
    int DEVIATION_M, DEVIATION_E;

    if (find_deviation_parameters(f_dev, &DEVIATION_M, &DEVIATION_E)) {
        printf("DEVIATION_M: %d, DEVIATION_E: %d\n", DEVIATION_M, DEVIATION_E);
    } else {
        printf("No valid DEVIATION_M and DEVIATION_E found.\n");
    }

    return 0;
}

但是有些小问题,具体表现为当输入的f_dev精度不一样是,计算出的寄存器值差了一个数。

I test with the double-f_dev version function find_deviation_parameters, when the input f_dev is 4943.848, the result is "DEVIATION_M: 4, DEVIATION_E: 1", however when I change the f_dev to 4943.84, the result is "DEVIATION_M: 3, DEVIATION_E: 1". there can be some glitches, please improve it.

这是不可接受的,所以问了下ChatGPT,给我改善了下

To improve the precision and consistency of the results for the floating-point version, we need to ensure that small changes in the input f_dev do not lead to disproportionate changes in the output parameters. This can be achieved by ensuring that all calculations are performed with high precision and by carefully managing rounding.

Here is an improved version of the function to handle floating-point inputs more accurately:

#include <stdio.h>
#include <math.h>
#include <float.h>  // For DBL_MAX

#define FXOSC 27000000.0  // 27 MHz

int find_deviation_parameters(double f_dev, int *DEVIATION_M, int *DEVIATION_E) {
    // Calculate the constant K
    double K = (f_dev * pow(2.0, 17)) / FXOSC;
    
    // Initialize variables to find the closest match
    double closest_f_dev_diff = DBL_MAX;
    int best_DEVIATION_M = -1, best_DEVIATION_E = -1;

    // Iterate over possible values of DEVIATION_E
    for (int DEVIATION_E_local = 0; DEVIATION_E_local < 8; DEVIATION_E_local++) {
        // Calculate the potential DEVIATION_M value
        double potential_M = K / pow(2.0, DEVIATION_E_local) - 8.0;
        
        // Check if potential_M is within the valid range (0 to 7)
        if (potential_M >= 0 && potential_M < 8) {
            // Calculate the actual deviation frequency for this pair
            double actual_f_dev = (FXOSC / pow(2.0, 17)) * (8 + floor(potential_M + 0.5)) * pow(2.0, DEVIATION_E_local);
            double f_dev_diff = fabs(f_dev - actual_f_dev);
            
            // Check if this is the closest match so far
            if (f_dev_diff < closest_f_dev_diff) {
                closest_f_dev_diff = f_dev_diff;
                best_DEVIATION_M = (int)floor(potential_M + 0.5);
                best_DEVIATION_E = DEVIATION_E_local;
            }

            // If potential_M is an integer within the valid range (0 to 7), we have an exact match
            if (fabs(potential_M - floor(potential_M + 0.5)) < DBL_EPSILON) {
                *DEVIATION_M = (int)floor(potential_M + 0.5);
                *DEVIATION_E = DEVIATION_E_local;
                return 1;  // Success with an exact match
            }
        }
    }

    // If no exact valid pair is found, return the closest match
    if (best_DEVIATION_M != -1 && best_DEVIATION_E != -1) {
        *DEVIATION_M = best_DEVIATION_M;
        *DEVIATION_E = best_DEVIATION_E;
        return 1;  // Success with the closest match
    }
    
    // If no valid pair is found at all, return 0 to indicate failure
    return 0;
}

int main() {
    double f_dev = 4943.848;  // Example frequency deviation
    int DEVIATION_M, DEVIATION_E;

    if (find_deviation_parameters(f_dev, &DEVIATION_M, &DEVIATION_E)) {
        printf("DEVIATION_M: %d, DEVIATION_E: %d\n", DEVIATION_M, DEVIATION_E);
    } else {
        printf("No valid DEVIATION_M and DEVIATION_E found.\n");
    }

    // Test with a slightly different frequency deviation
    f_dev = 4943.84;
    if (find_deviation_parameters(f_dev, &DEVIATION_M, &DEVIATION_E)) {
        printf("DEVIATION_M: %d, DEVIATION_E: %d\n", DEVIATION_M, DEVIATION_E);
    } else {
        printf("No valid DEVIATION_M and DEVIATION_E found.\n");
    }

    return 0;
}

 其实就是转换的问题,导致了误差的累积,精度丢失了。这涉及到 (int)转换, floor函数,还有(int)floor函数的用法,另开一篇写吧。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值