Maximum value of typed signed type

I read John Reger 's blog about how he gives his students a task on saturating arithmetic. The interesting part is that the code should compile as-is when using typedefs to specify different integer types, see the following snippet for the full header :

typedef signed int mysint;
//typedef signed long int mysint;

mysint sat_signed_add (mysint, mysint);

mysint sat_signed_sub (mysint, mysint);

The corresponding unsigned version is easy to implement (although I’m not really sure that add-on bits will not do this problem either), but I really don’t see how I can get the maximum (or minimum) value of an unknown signed type in C, without using macros for MAX_und MIN_or undefined behavior.

Am I missing something or is the concession just ruined (or most likely I am missing some important information that he gave to his students)?

+4
source share
5 answers

I see no way to do this without making assumptions or causing the behavior defined by the implementation (not necessarily undefined). However, if you assume that the introduction mysintor uintmax_tno additional bits to fill in bits, you can calculate the maximum value as follows:

mysint mysint_max = (mysint)
    ((~(uintmax_t)0) >> (1 + CHAR_BITS * (sizeof(uintmax_t) - sizeof(mysint))));

-mysint_max (/ ) -mysint_max - 1 ( ), , . , , , . - " " , , , .

, , mysint -1. mysint 0, 1, / mysint_max - 1.

, , , int . . , union:

union mysint_bits {
    mysint i;
    unsigned char bits[sizeof(mysint)];
} msib;

int counter = 0;

for (msib.i = -1; counter < sizeof(mysint); counter += 1) {
    msib.bits[counter] = ~msib.bits[counter];
}

, ( mysint ) msib.i .

+6

C, - . ( ++ std::numeric_limits, .)

(myuint)(-1). , (& sect; 6.3.1.3/1-2):

& hellip; , , , .

, -1 , , , . ( , " " .)

, , , [ . ], :

(mysint)( (myuint)(-1) / (myuint)2 )

, , , , ( 2--), (1-- /).

, , . , . , , , , . [: , .]

, (, ), 2'- , min, max:

myuint max_myuint = (myuint)(-1);
mysint max_mysint = (mysint)(max_myuint / (my_uint)2);
mysint min_mysint = (-max_mysint) - (mysint)1;

, undefined, . , 6.3.1.3/3, :

; .

, , . , , , gcc. gcc, "C-, " :

  •  , ,    (C99 6.2.6.2).

    GCC ,   .

  • ,   ,   (C90 6.2.1.2, C99 6.3.1.3).

    N  2 ^ N ; .

, 2s- , , , , uintmax_t:

uintmax_t umax = (uintmax_t)(-1);
while ( (mysint)(umax) < 0 ) umax >>= 1;
mysint max_mysint = (mysint)(umax);
mysint min_mysint = (-max_mysint) - (mysint)1;
+4

MAX typedef -

typedef signed int mysint;
mysint size; // will give the size of the type
size=sizeof(mysint)*(mysint)8-(mysint)1; // as it is signed so a bit
                                        // will be deleted for sign bit
mysint max=1;//start with first bit
while(--size)
{
   mysint temp;
   temp=(max<<(mysint)1)|(mysint)1;// set all bit to 1
   max=temp;
}
/// max will contain the max value of the type mysint
+1

char ( , DSP), ( uintmax_t to , ) sizeof(mysint)*8 - 1 1 , mysint. .

, , limits.h, .

0

,

// MSB is 1 and rests are zero is minimum number in both 2 and 1's
// compliments representations.
mysint min =  (1 << (sizeof(mysint) * 8 - 1));
mysint max = ~x;
0

Source: https://habr.com/ru/post/1570049/


All Articles