Dear list.
I would have expected to be able to set the thirtysecond bit of an integer type, but I cannot. Does anybody know why?
Thanks, Bastiaan.
program thirtysecond;
const thirtyfirst = 2#01000000000000000000000000000000; thirtysecond = 2#10000000000000000000000000000000;
var i_thirtyfirst : integer value thirtyfirst; i_thirtysecond : integer value thirtysecond; {constant out of range, initial value is of wrong type} i_minus_zero : integer value 2#10000000000000000000000000000000; {idem} i_minint : integer value 2#11111111111111111111111111111111; {idem} i_thirtysecond2 : integer value 1 shl 31; {idem}
begin end.
On Thu, 28 Dec 2006, Bastiaan Veelo wrote:
Dear list.
I would have expected to be able to set the thirtysecond bit of an integer type, but I cannot. Does anybody know why?
hardware.
concider a sequence of integers: ..., -3, -2, -1, 0, +1, +2, +3, ...
what you wanted is: ..., -3, -2, -1, -0, +0, +1, +2, +3, ... which is not allowed.
Russ
Bastiaan Veelo wrote:
I would have expected to be able to set the thirtysecond bit of an integer type, but I cannot. Does anybody know why?
"Integer" is a signed type, so a set 32nd bit indicates a negative number (two's complement) on virtually every modern architecture. The numbers you want are thus a negative numbers, which can be given as
-2#10000000000000000000000000000000
and
-2#00000000000000000000000000000001
(or simply -1 in the latter case).
If you want unsigned numbers >= 2^31, you need an unsigned type, called "Cardinal" in GPC (or, of course, a type larger than 32 bytes, such as "LongInt"). With either of those types your test program works.
Please note that in Pascal, unlike C, integers represent numbers, not bit-patterns, so storing a 32-bit-pattern (with the topmost bit set) in a signed integer type, which is common practice in C, is not allowed in Pascal, as it would alter the numeric value.
Frank
Frank Heckenbach wrote:
... snip ...
Please note that in Pascal, unlike C, integers represent numbers, not bit-patterns, so storing a 32-bit-pattern (with the topmost bit set) in a signed integer type, which is common practice in C, is not allowed in Pascal, as it would alter the numeric value.
You have a misconception about C. Numbers are represented by values. The bit pattern is specified for positive and unsigned values, which restricts the representation to binary. However 2's complement, 1's complement, and sign-magnitude representation is allowed for negative values. What you call a "common practice" is in fact an error which is often not caught by the compiler.
Thank you, Frank and others. The issue is solved, the curious may read on.
I figured that it had something to do with the sign. The prefix - is logical if you think of it as a number in binary notation, but I thought of it as a bit field. We have a large amount of legacy code that compiles with the Prospero Extended Pascal compiler. I do not know why it does, maybe that compiler is not standard compliant in this regard.
That code consists of a library that stores flags in 32-bit constants. Then, in many utility programmes, some of these flags are ORed together and stored in an integer variable (although a cardinal would have been more appropriate). In our case, the flag that is stored in the 32nd bit (the sign bit of an integer) never occurs alone, and therefore the hypothetical value of -0 is never attempted to be stored in the integer variable. Actually we do not have 32 flags, so we can just reorganise the bits and not use the 32rd one.
Best regards, Bastiaan.
Bastiaan Veelo wrote:
Thank you, Frank and others. The issue is solved, the curious may read on.
I figured that it had something to do with the sign. The prefix - is logical if you think of it as a number in binary notation, but I thought of it as a bit field. We have a large amount of legacy code that compiles with the Prospero Extended Pascal compiler. I do not know why it does, maybe that compiler is not standard compliant in this regard.
Seems so, EP 6.1.7 says:
: An extendedÂnumber shall denote, in conventional positional notation : with the specified radix, a value of integerÂtype in the closed : interval 0 to maxint (see 6.4.2.2).
(So, no negative values.)
That code consists of a library that stores flags in 32-bit constants. Then, in many utility programmes, some of these flags are ORed together and stored in an integer variable (although a cardinal would have been more appropriate).
Indeed, if the topmost bit is used. Of course, Cardinal itself is not part of standard Pascal, so if you need this in standard code, you might need some contortions for this bit. (However, bit-operations such as "or" and "shl" are not standard Pascal either, to start with.)
In our case, the flag that is stored in the 32nd bit (the sign bit of an integer) never occurs alone, and therefore the hypothetical value of -0 is never attempted to be stored in the integer variable.
Actually, it wouldn't be -0, as virtually every modern platform uses two's complement, so this value would be -(MaxInt + 1) instead.
Actually we do not have 32 flags, so we can just reorganise the bits and not use the 32rd one.
OK, probably easier. :-)
CBFalconer wrote:
Frank Heckenbach wrote:
... snip ...
Please note that in Pascal, unlike C, integers represent numbers, not bit-patterns, so storing a 32-bit-pattern (with the topmost bit set) in a signed integer type, which is common practice in C, is not allowed in Pascal, as it would alter the numeric value.
You have a misconception about C. Numbers are represented by values. The bit pattern is specified for positive and unsigned values, which restricts the representation to binary. However 2's complement, 1's complement, and sign-magnitude representation is allowed for negative values. What you call a "common practice" is in fact an error which is often not caught by the compiler.
OT, but is it really an error according to standard C, or not explicitly forbidden? (In the latter case, the behaviour would still be undefined, but it would be allowed for double-"errors" to cancel, such as storing a negative value in an unsigned integer variable, then assigning this variable to a signed variable and expecting the original negative value there. I've seen such things in C code, of course. ;-)
Anyway, the moral is, if you want to use bit-patterns and need all the bits, always use an unsigned type (such as "Cardinal" in GPC, or "unsigned int" in C). (Not applicable to standard Pascal, unfortunately.)
Frank