编号622.08E6替换为622080000

时间:2013-11-14 03:32:30

标签: c floating-point floating-point-precision exponentiation

我最近遇到了一个C代码(顺便说一句),我找到了

freq_xtal = ((622.08E6 * vcxo_reg_val->hiv * vcxo_reg_val->n1)/(temp_rfreq));

从我的直觉来看,622.08E6似乎意味着622.08 x 10 ^ 6.

从这个问题来看,这个假设是正确的。

SO related question

所以我尝试用

替换622.08e6
uint32_t default_freq = 622080000;

由于某些原因,这似乎并没有消失

任何想法或建议表示赞赏

2 个答案:

答案 0 :(得分:6)

你遇到的问题(我在这里推测是因为我没有剩下的代码)似乎是用整数替换浮点导致乘法和除法是基于整数的,而不是基于小数。因此,您现在计算错误的值。

尝试将uint32_t类型转换为double,然后查看是否将其清除。

答案 1 :(得分:1)

问题是由于溢出!

原始表达式(622.08E6 * vcxo_reg_val->hiv * vcxo_reg_val->n1)/temp_rfreq(你有太多不必要的括号)是在 double精度中完成的,因为622.08E6是一个double字面值。这将导致浮点值

但是,如果用622080000替换文字,那么如果所有变量都是整数,整个表达式将以整数数学完成。但更重要的是,整数数学会溢出(至少比浮点数早得多)

请注意UINT32_MAX / 622080000.0 ≈ 6.9。这意味着只需将常数乘以7即可溢出。但是在代码中,您将622080000乘以2个其他值,其乘积远高于6 。您应该添加ULL后缀以在unsigned long long

中进行数学运算
freq_xtal = (622080000ULL * vcxo_reg_val->hiv * vcxo_reg_val->n1)/temp_rfreq;

或将变量更改为uint64_t default_freq = 622080000ULL;