C:解决警告:表达式中整数溢出?
我正在尝试组织我的 UART 库,并通过添加一些 #define 对其进行一些美化,以便稍后可以自定义它,而无需深入研究代码,但我似乎无法让以下代码正常工作:
#define FOSC 8000000
#define BAUDRATE 9600
#define BRGVAL (FOSC/2)/(16*BAUDRATE)-1
void uart_init(){
U1BRG = BRGVAL;
}
计算后 BRGVAL 变为 25.0416667,并且由于它不是整数,因此当我将其分配给 U1BRG 时,我会收到以下警告:
UART.c:在函数“uart_init”中:
UART.c:24:警告:表达式中的整数溢出
...并且该代码根本无法在目标硬件上运行。 (如果我手动输入 U1BRG = 25,它就像一个魅力)
有什么方法可以将该常量转换为整数以使编译器满意吗?
非常感谢, 哈姆扎。
I am trying to organise my UART library and prettify it a little bit by adding some #define s so I can customize it later without having to dig deeply into the code, but I can't seem to get the following bit of code working:
#define FOSC 8000000
#define BAUDRATE 9600
#define BRGVAL (FOSC/2)/(16*BAUDRATE)-1
void uart_init(){
U1BRG = BRGVAL;
}
After the calculation BRGVAL becomes 25.0416667, and because it is not an integer I get the following warning for it when I assign that into U1BRG:
UART.c: In function 'uart_init':
UART.c:24: warning: integer overflow in expression
...and the code simply does not work on target hardware. (If I manually put in U1BRG = 25 it works like a charm though)
Is there any way to typecast that constant into an integer to make the compiler happy?
Many Thanks,
Hamza.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
整数溢出意味着您已经超出了 int 值的上限,如果您收到此错误,则可能是 32767。它与浮点数无关;您指定的运算实际上是整数数学运算,因此除法的小数部分无论如何都会被丢弃。
尝试这样的操作:
L 后缀将这些常量转换为
long
类型而不是int
类型。(unsigned int)
转换转换为 U1BRG 的类型,并让编译器知道您了解long
值将适合unsigned int
从而隐藏它可能向您发出的任何警告。通常,消除编译器警告是不好的做法,但在这种情况下,很明显,尽管您需要
long
来存储计算中的中间值,但最终结果将适合unsigned int< /代码>。
Integer overflow means that you have exceeded the upper limit of an int value, which is likely to be 32767 if you are getting this error. It has nothing to do with floating point; the operations you have specified are in fact integer math operations, so the fractional part of the division is discarded anyway.
Try something like this:
The L suffix turns these constants into
long
type instead ofint
type. The(unsigned int)
cast converts to U1BRG's type, and lets the compiler know that you understand that thelong
value will fit into anunsigned int
and thus hide any warnings it may throw at you.Normally, it's bad practice to silence compiler warnings, but in this case, it's clear that although you need
long
to store intermediate values in the calculation, the final result will fit into anunsigned int
.我喜欢菲利普的答案,但我认为更好的解决方案是减少公式并将宏更改为:
这样做时,您消除了强制转换,以便编译器可以继续警告您,如果您选择低波特率,这将导致对于 16 位 int 来说,除法器值太大。
I like Philip's answer, but I think a better solution is to reduce the formula and change your macro to:
In doing so, you eliminate the cast so the compiler can continue to warn you if you choose a low baud rate that would result in a divider value too large for a 16-bit int.
从您的示例中不清楚 U1BRG 是全局变量还是 #define'ed 常量。无论如何,简单地转换为整数应该可以:
It's not clear from your example whether U1BRG is a global variable or a #define'ed constant. In any case, simply casting to an integer should work:
我可能会用这个:
I would probably use this:
您没有指出这一点,U1BRG 的数据类型是什么?如果它是一个
int
,则将其转换为如图所示编辑:修改此以考虑Adam Liss'评论说无符号整型太小而无法容纳宏的结果,我已将其更改为
long
...感谢 Adam 的提示...希望这有帮助,
此致,
汤姆.
You have failed to point this out, What's the data type for U1BRG? If it's an
int
, cast it like as shownEdit: Amended this to take into consideration of Adam Liss's comment that an unsigned int is too small to hold the result of the macro, I have changed it to make it a
long
...Thanks Adam for the headsup...Hope this helps,
Best regards,
Tom.