Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is SCHAR_MIN defined as -127 in C99?

§5.2.4.2.1 of C99 defines SCHAR_MIN as -127 and SCHAR_MAX as 127. Should not the range for an 8 bit signed integer be -128 to +127?

The limits.h for my compiler defines SCHAR_MIN as (-1 << ((CHAR_BIT)-1)), which is -128 given CHAR_BIT is 8.

Is there any reason why SCHAR_MIN was defined -127 and not -128 ?

like image 300
Summit Raj Avatar asked Nov 04 '11 13:11

Summit Raj


People also ask

Is char unsigned by default?

Otherwise, explicitly declare signed char or unsigned char to declare numeric variables that occupy a single byte. When a char ( signed or unsigned ) is widened to an int , its value is preserved. By default, char behaves like an unsigned char .

What is Climit C++?

<climits>(limits.This header defines constants with the limits of fundamental integral types for the specific system and compiler implementation used. The limits for fundamental floating-point types are defined in <cfloat> (<float. h>).


1 Answers

It doesn't actually define SCHAR_MIN as -127, it defines the minimum range of signed characters to -127..127.

It does this because it has to be able to handle the other two encoding schemes for signed numbers, those being ones' complement and sign/magnitude. Both of these have a positive and negative zero, stealing away the -128 you find in two's complement.

ISO C (C99), section 6.2.6.2/2, states that an implementation must choose one of these three different representations for signed integral data types:

  • two's complement;
  • ones' complement; or
  • sign/magnitude

The two's complement implementations far outweigh the others but the others do exist.

In all those representations, positive numbers are identical, the only difference being the negative numbers.

To get the negative representation for a positive number, you:

  • invert all bits then add one for two's complement.
  • invert all bits for ones' complement.
  • invert just the sign bit for sign/magnitude.

You can see this in the table below, for both 5 and 0:

number | two's complement    | ones' complement    | sign/magnitude
=======|=====================|=====================|====================
     5 | 0000 0000 0000 0101 | 0000 0000 0000 0101 | 0000 0000 0000 0101
    -5 | 1111 1111 1111 1011 | 1111 1111 1111 1010 | 1000 0000 0000 0101
       |                     |                     |
     0 | 0000 0000 0000 0000 | 0000 0000 0000 0000 | 0000 0000 0000 0000
    -0 | 0000 0000 0000 0000 | 1111 1111 1111 1111 | 1000 0000 0000 0000
           (no difference)        (both of these have distinct +/-0)
like image 52
paxdiablo Avatar answered Nov 06 '22 21:11

paxdiablo