From: Skybuck Flying on
Hello,

See comments for details.

// *** Begin of Main.cpp ***

#include <stdio.h>

typedef char int8;
typedef short int int16;
typedef int int32;
typedef long long int64;

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long long uint64;

/*

Skybuck Flying says GoodBye to Delphi.

Skybuck Flying says Hello to C/C++

Back to School with Skybuck Flying:

Lesson 1, Integer basics.

Conclusions:

Out of range detection for int8 ok.
Out of range detection for uint8 ok.

Out of range detection for int16 ok.
Out of range detection for uint16 ok.

Out of range detection for int32 BAD.
Out of range detection for uint32 ok.

Out of range detection for int64 BAD.
Out of range detection for uint64 ok.

Legal range for int8 ok.
Legal range for uint8 ok.

Legal range for int16 ok.
Legal range for uint16 ok.

Legal range for int32 BAD.
Legal range for uint32 ok.

Legal range for int64 BAD.
Legal range for uint64 ok.

Range detection is done at compile, warnings are displayed in the output
window.

No runtime checking.

Out of range situations can produce multiple warnings.

Trying to set a valid maximum negative value for int32 and int64 also gives
problems/warnings.

Platform tested intel architecture 32.

12 out of 16 tests passed.
4 out of 16 tests failed.

Score:

7.5 out of 10.

Microsoft's Visual Studio 2008 Professional Edition programmers get to go to
next lesson with Skybuck :)

*/

int main()
{
printf("Program Started \n\n");

int8 vMinInt8;
int8 vMaxInt8;

uint8 vMinUint8;
uint8 vMaxUint8;

int16 vMinInt16;
int16 vMaxInt16;

uint16 vMinUint16;
uint16 vMaxUint16;

int32 vMinInt32;
int32 vMaxInt32;

uint32 vMinUint32;
uint32 vMaxUint32;

int64 vMinInt64;
int64 vMaxInt64;

uint64 vMinUint64;
uint64 vMaxUint64;

// test int8
printf("sizeof(int8): %d \n", sizeof(int8) );

vMinInt8 = -128;
printf("vMinInt8: %d \n", vMinInt8 );

vMaxInt8 = 127;
printf("vMaxInt8: %d \n\n", vMaxInt8 );

// test uint8
printf("sizeof(uint8): %d \n", sizeof(uint8) );

vMinUint8 = 0; // -1 would give warning: signed/unsigned mismatch
printf("vMinUint8: %u \n", vMinUint8 );

vMaxUint8 = 255; // 256 would give warnings: truncation from int to
uint8, and truncation of constant value
printf("vMaxUint8: %u \n\n", vMaxUint8 );

// test int16
printf("sizeof(int16): %d \n", sizeof(int16) );

vMinInt16 = -32768; // -32769 would give warning: truncation from int to
int16
printf("vMinInt16: %d \n", vMinInt16 );

vMaxInt16 = 32767; // 32768 would give warning: truncation of constant
value
printf("vMaxInt16: %d \n\n", vMaxInt16 );

// test uint16
printf("sizeof(uint16): %d \n", sizeof(uint16) );

vMinUint16 = 0; // -1 would give warning: signed/unsigned mismatch
printf("vMinUint16: %u \n", vMinUint16 );

vMaxUint16 = 65535; // 65536 would give warnings: truncation from int to
uint16, and truncation of constant value
printf("vMaxUint16: %u \n\n", vMaxUint16 );

// test int32
printf("sizeof(int32): %d \n", sizeof(int32) );

// removing the minus solves the warning for now.
vMinInt32 = 2147483648; // -2147483648 still gives warning: unary minus
operator applied to unsigned type, result still unsigned
// little problem with negation probably
printf("vMinInt32: %d \n", vMinInt32 );

vMaxInt32 = 2147483647; // 2147483648 or any other out of range value
gives no warning what so ever ?!?!
printf("vMaxInt32: %d \n\n", vMaxInt32 );

// test uint32
printf("sizeof(uint32): %d \n", sizeof(uint32) );

vMinUint32 = 0; // -1 would give warning: conversion from int to uint32,
signed/unsigned mismatch
printf("vMinUint32: %u \n", vMinUint32 );

vMaxUint32 = 4294967295; // 4294967296 would give warning: truncation
from __int64 to uint32, and truncation of constant value.
printf("vMaxUint32: %u \n\n", vMaxUint32 );

// test int64
printf("sizeof(int64): %ld \n", sizeof(int64) );

// problem zone for maximum negative value and beyond:
// vMinInt64 = -9223372036854775809; // would give warning: unary minus
operator applied to unsigned type, result still unsigned
vMinInt64 = 9223372036854775808; // solves the warning and becomes
negative

printf("vMinInt64: %lld \n", vMinInt64 );

vMaxInt64 = 9223372036854775807; // 9223372036854775808 would give no
warning ?!?!
printf("vMaxInt64: %lld \n\n", vMaxInt64 );

// test uint64
printf("sizeof(uint32): %d \n", sizeof(uint64) );

vMinUint64 = 0; // -1 would give warning: conversion from 'int' to
'uint64', signed/unsigned mismatch
printf("vMinUint64: %llu \n", vMinUint64 );

vMaxUint64 = 18446744073709551615; // 18446744073709551616 would give
warning: constant too big
printf("vMaxUint64: %llu \n\n", vMaxUint64 );

printf("Program finished \n");
}

// *** End of Main.cpp ***

Bye,
Skybuck.


From: Jerry Coffin on
In article <b2cc4$47fe735f$541983fa$32705(a)cache3.tilbu1.nb.home.nl>,
spam(a)hotmail.com says...

[ ..., ]

> Legal range for int32 BAD.
> Legal range for uint32 ok.
>
> Legal range for int64 BAD.
> Legal range for uint64 ok.

You're running into a well-known situation in C and C++. An integer
literal in either language consists only of digits. Something like '-1'
is not a negative literal -- it's a unary minus followed by a positive
literal.

As such, creating a literal that represents the most negative value for
a signed type on a twos-complement machine is somewhat problematic. The
most negative value has a magnitude one greater than can be represented
as a positive signed value -- therefore, it's out of range for that
signed type. To represent the value, it has to have either unsigned type
or a larger type that can hold that value as a signed type.

There are a number of ways to form values like this. For example, you
can create the value '-32768' as:

-32767-1
0x8000
\177777

or, you can use one of the two values already provided:

SHRT_MIN
std::numeric_limits<short>::min

If you use '-32768' directly, it'll typically have type int instead of
short (assuming an implementation with 16-bit shorts and 32-bit ints)
even though that value can be represented in 16 bits.

Personally, I'd advise stepping back and figuring out what you're really
trying to accomplish here. I'm not quite sur what you think this
exercise was supposed to accomplish, but I doubt it means nearly as much
as you think.

--
Later,
Jerry.

The universe is a figment of its own imagination.
From: Philip Potter on
Jerry Coffin wrote:
> There are a number of ways to form values like this. For example, you
> can create the value '-32768' as:
>
> -32767-1
> 0x8000
> \177777

The last two are not guaranteed to work in C. Assigning a number outside
the range of an object of signed integer type has an
implementation-defined result or raises an implementation-defined
signal. (n1256 6.3.1.3p3)

> or, you can use one of the two values already provided:
>
> SHRT_MIN
> std::numeric_limits<short>::min

Yes - that's why they're there!
From: Richard Heathfield on
Jerry Coffin said:

> In article <b2cc4$47fe735f$541983fa$32705(a)cache3.tilbu1.nb.home.nl>,
> spam(a)hotmail.com says...
>
> [ ..., ]
>
>> Legal range for int32 BAD.
>> Legal range for uint32 ok.
>>
>> Legal range for int64 BAD.
>> Legal range for uint64 ok.
>
> You're running into a well-known situation in C and C++.

....and you're running into a well-known troll. Surely you recognise the
nick?

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
From: Jerry Coffin on
In article <8uCdnVTxaaqpFmLanZ2dnUVZ8uednZ2d(a)bt.com>,
rjh(a)see.sig.invalid says...

[ ... ]

> ...and you're running into a well-known troll. Surely you recognise the
> nick?

No, it doesn't look familiar, though I guess I shouldn't be surprised...

--
Later,
Jerry.

The universe is a figment of its own imagination.