c - 转换 int 值的问题
问题描述
因此,我尝试遵循以下示例:Fixed Point Arithmetic in C Programming,但出现以下错误left shift count >= width of type
。
我确实在stackoverflow上发现其他人有这个问题,但我不明白这个错误?
#include "contiki.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//Define sizeof - macros
#define SHIFT_AMOUNT 16 // 2^16 = 65536
#define SHIFT_MASK ((1 << SHIFT_AMOUNT) - 1) // 65535 (all LSB set, all MSB clear)
static int price = 500 << SHIFT_AMOUNT;
void calcTest(){
price += 10 << SHIFT_AMOUNT;
price *= 3;
price /= 4; // now our price is ((500 + 10) * 3) / 4 = 382.5
printf("price integer is %d\n", price >> SHIFT_AMOUNT);
printf ("price fraction is %d\n", price & SHIFT_MASK);
}
//Defining two processors, one for making the 'knock' and one to listen
PROCESS(data_comp, "data_comp");
AUTOSTART_PROCESSES(&data_comp);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(data_comp, ev, data)
{
static struct etimer timer;
PROCESS_BEGIN();
/* Setup a periodic timer that expires after 10 seconds. */
etimer_set(&timer, CLOCK_SECOND * 10);
while(1) {
calcTest();
/* Wait for the periodic timer to expire and then restart the timer. */
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
etimer_reset(&timer);
}
PROCESS_END();
}
解决方案
您链接到的问题中的示例是int
为 32 位的 C 实现编写的。在您使用的 C 实现中,int
类型似乎是 16 位,这对于 16 位移位来说太短了。您将需要调整代码以使用更短的移位或更宽的整数类型。
每个整数类型都有一个宽度,即用于表示它的位数,包括一个符号位(如果类型是有符号的)和值位,但不包括填充位。
错误消息“left shift count >= width of type”表示左移的数量大于或等于您要移动的整数类型的宽度。例如,如果您将一个 16 位数字左移 16 位,则您将所有位移出整数,并且没有剩下任何位。C 标准本质上将此视为溢出:它没有定义行为。所以编译器会警告你。
由于问题中的代码与问题中的错误消息不完全匹配,我们无法确定,但一种可能性是您正在为int
类型为 16 位宽的目标进行编译,因此SHIFT_AMOUNT
16 位太多了。请注意,int
由于符号位以及 C 标准中定义有符号整数的移位方式,移位 an 也是有问题的。移位时通常最好使用无符号类型。
可能的补救措施包括:
- 检查您的班次金额。对 16 位使用 16
int
会导致有点极端的定点类型。您可能需要更小的班次量。 - 使用更大的整数类型,也许
long
. - 使用更宽的类型进行移位并转换回来。例如,如果
long
是 32 位,您可以定义SHIFT_MASK
为((int) ((1l << SHIFT_AMOUNT) - 1))
。 - 如果
SHIFT_AMOUNT
已知至少为 1,但不超过 16,则通过使用更短的移位来避免超出类型的宽度,左操作数已经移位了一位:((2 << SHIFT_AMOUNT-1) - 1)
. - 将操作分为两个班次:
((1 << SHIFT_AMOUNT/2 << SHIFT_AMOUNT-SHIFT_AMOUNT/2) - 1)
.
请注意,上述选项不处理签名问题。您需要澄清上下文以获得进一步的建议。
推荐阅读
- html - 辅助功能 - 选项卡与屏幕阅读器不匹配
- javascript - 在 p5.js 中使用来自 Datamuse API 的 JSON 数据时遇到问题
- google-chrome - 如果冻结,如何停止异步 gatt.connect()
- php - 表单提交返回输入 Laravel
- php - 密码验证不提供任何输出作为回报并且没有显示错误
- laravel - 基于选项搭建 Laravel 应用程序
- python - Filtering pandas dataframe groups based on groups comparison
- json - 获取 Java.text.ParseException
- c# - TFS:“无法从程序集中加载类型''”-但有时仅显示
- javascript - 在 javascript 中使用大数字的位运算符