gpt4 book ai didi

c - AVR C 十六进制和十进制乘法不符合预期

转载 作者:太空狗 更新时间:2023-10-29 16:10:14 25 4
gpt4 key购买 nike

在将十六进制整数(例如 0xFFFF)与十进制整数(例如 2)相乘时,我刚刚在我的代码中发现了一个错误。这是出现问题的代码:

print_int_new_line(0xFFFF*2);
print_int_new_line(65535*2);

执行这段代码会得到以下结果:

65534
131070

这是相关的 UART 代码:

void print_int_new_line(uint64_t data) {
print_int(data);

print_new_line();
}

void print_int(uint64_t data) {
char data_buffer[(int)(log(data)+2)]; // size of the number (log(number)+1) + 1 for the /0

ultoa(data, data_buffer, 10); // convert the int to string, base 10

// print the newly created string
print_string(data_buffer);
}

void print_string(char * data) {

// transmit the data char by char
for(; *data != '\0'; data++){
USART_transmit(data);
}
}

void USART_transmit(const char * data){
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE0)) )
;

/* Put data into buffer, sends the data */
UDR0 = *data;
}

关于我的设置的一些信息:

单片机:ATmega2560开发板:Arduino Mega2560串口波特率:38400集成开发环境:Atmel Studio 7.0.4.1417

使用 AVR 工具链。

我阅读了this十六进制和十进制整数之间可以进行乘法的 stackoverflow 页面。此外,在 online 中对此进行测试c 编译器给出正确的输出。

谁能给我一个解释?

最佳答案

此行为是由于处理十进制和十六进制整数常量的差异所致。

对于 0xFFFF65535,编译器将首先尝试将值转换为 int。但是由于平台有一个 16 位的 int 类型,其中 INT_MAX32767,所以无法执行该转换。

关键区别在于下一步。对于十六进制常量 0xFFFF,编译器会尝试将其转换为 unsigned int,相当于 (unsigned int)65535。但是,对于十进制常量,不会尝试转换为无符号类型。下一次转换尝试是 long int。这将成功并等效于 (long int)65535

因此对 print_int_new_line 的调用等同于:

print_int_new_line((unsigned int)65535*2);
print_int_new_line((long int)65535*2);

2 被提升为乘法时:

print_int_new_line((unsigned int)65535*(unsigned int)2);
print_int_new_line((long int)65535*(long int)2);

第一次乘法的 unsigned int 结果太小,无法容纳完整结果,因此被截断为 65534long int 可以保存结果,因此它会产生 131070 的正确答案。

您可以通过附加 L(即 0xFFFFL)强制十六进制常量使用 long int

关于c - AVR C 十六进制和十进制乘法不符合预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50259140/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com