Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Cleaned up examples using UWIDTH

...

Code Block
bgColor#ccccff
langc
#include <stddef.h>
#include <assert.h>
#include <limits.h>
#include <inttypes.h>
 
size_t popcount(uintmax_t num) {
  size_t width = 0;
  while (num != 0) {
    if (num % 2 == 1) {
      width++;
    }
    num >>= 1;
  }
  return width;
}
#define UWIDTH(type, umax_value) (sizeof(type) * CHAR_BITpopcount(umax_value)
  
void func(signed int si_a, signed int si_b) {
  signed int result;
  signed long long tmp;
  assert(UWIDTH(signed long long, ULLONG_MAX) >=
         2 * UWIDTH(int, UINT_MAX));
 
  tmp = (signed long long)si_a * (signed long long)si_b;
 
  /*
   * If the product cannot be represented as a 32-bit integer,
   * handle as an error condition.
   */
  if ((tmp > INT_MAX) || (tmp < INT_MIN)) {
    /* Handle error */
  } else {
    result = (int)tmp;
  }
  /* ... */
}

The assertion fails if long long has less than twice the width of int. The purpose of the UWIDTH() macro and the function popcount() is explained in INT19-C. Correctly compute integer widths.

...

Code Block
bgColor#ccccff
langc
#include <limits.h>
#include <stddef.h>
#include <inttypes.h>
 
extern size_t popcount(uintmax_t);
#define UWIDTH(type, umax_value) (sizeof(type) * CHAR_BITpopcount(umax_value) 

void func(signed long si_a, signed long si_b) {
  signed long result;
  if ((si_a < 0) || (si_b < 0) ||
      (si_b >= UWIDTH(signed long, ULONG_MAX)) ||
      (si_a > (LONG_MAX >> si_b))) {
    /* Handle error */
  } else {
    result = si1si_a << si2si_b;
  }
 
  /* ... */
}

Anchor
Left Shift Operator
Left Shift Operator

...