微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

转换 int 值的问题

如何解决转换 int 值的问题

所以我尝试遵循以下示例:Fixed Point Arithmetic in C Programming,但出现以下错误 left shift count >= width of type

enter image description here

我确实在 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 位宽的目标,因此16 位的 SHIFT_AMOUNT 太多了。请注意,由于符号位以及 C 标准中如何定义有符号整数的移位,移位 int 也是有问题的。移位时通常最好使用无符号类型。

可能的补救措施包括:

  • 检查您的轮班金额。对 16 位 int 使用 16 会导致有点极端的定点类型。您可能需要较小的移位量。
  • 使用更大的整数类型,可能是 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)

请注意,上述选项不处理签名问题。您需要澄清上下文以获得进一步的建议。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。