-3

So I tried to follow an example from: Fixed Point Arithmetic in C Programming, but I get the following error left shift count >= width of type.

enter image description here

I did find others having this issue here on stackoverflow but I don't understand this error?

#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();
}

WRD BAC
  • 9
  • 4

1 Answers1

2

The example in the question you link to is written for a C implementation in which int is 32 bits. In the C implementation you are using, the int type appears to be 16 bits, and this is too short for 16-bit shifts. You will need to adjust the code to use shorter shifts or a wider integer type.

Each integer type has a width, which is the number of bits used to represent it, including a sign bit (if the type is signed) and the value bits but excluding padding bits.

The error message “left shift count >= width of type” says amount of the left shift is greater than or equal to the width of the integer type you are shifting. For example, if you shift a 16-bit number 16 bits left, you shift all bits out of the integer, and there are none left. The C standard essentially treats this as overflow: It does not define the behavior. So the compiler is warning you.

Since the code in the question does not exactly match the error messages in the question, we cannot be sure, but one possibility is you are compiling for target in which the int type is 16 bits wide, so the SHIFT_AMOUNT of 16 bits is too much. Note that shifting an int is also problematic because of the sign bit and how shifts of signed integers are defined in the C standard. It is usually preferable to use an unsigned type when shifting.

Possible remedies include:

  • Check your shift amount. Using 16 for a 16-bit int results in a somewhat extreme fixed-point type. You may want a smaller shift amount.
  • Use a larger integer type, perhaps long.
  • Use a wider type for the shift and convert back. For example, if long is 32 bits, you could define SHIFT_MASK to be ((int) ((1l << SHIFT_AMOUNT) - 1)).
  • If SHIFT_AMOUNT is known to be at least one, but not more than 16, then avoid exceeding the width of the type by using a shorter shift with a left operand already shifted a bit: ((2 << SHIFT_AMOUNT-1) - 1).
  • Split the operation into two shifts: ((1 << SHIFT_AMOUNT/2 << SHIFT_AMOUNT-SHIFT_AMOUNT/2) - 1).

Note the above options do not deal with the signedness issue. You would need to clarify the context for further advice on that.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312