Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Help with Constant Define--Compiler Issue with ANSI or my compiler or me?

Reply
Thread Tools

Help with Constant Define--Compiler Issue with ANSI or my compiler or me?

 
 
No Spam
Guest
Posts: n/a
 
      12-29-2004


----snip

#define POSITIVE_INTEGRATOR_SATURATION 0x03000000L //
#define NEGATIVE_INTEGRATOR_SATURATION 0xFD000000L //



long integrator;

integrator=0;

if (integrator>POSITIVE_INTEGRATOR_SATURATION)
integrator=POSITIVE_INTEGRATOR_SATURATION;
if (integrator<NEGATIVE_INTEGRATOR_SATURATION)
integrator=NEGATIVE_INTEGRATOR_SATURATION;


1. Why does the executable always assign
NEGATIVE_INTEGRATOR_SATURATION to integrator?

-I assume that long declaration means the value is signed (the most
significant bit indicates sign)

------------
#define INTEGRATOR_SATURATION 0x03000000L // 3



long integrator;

integrator=0;

if (integrator>INTEGRATOR_SATURATION)
integrator=POSITIVE_INTEGRATOR_SATURATION;
if (integrator<(0-INTEGRATOR_SATURATION))
integrator=NEGATIVE_INTEGRATOR_SATURATION;

This code leaves integrator at 0, as intended.

-------------

2. Why does the second snippet work, while the first does not.

Additional Info- My machine uses four bytes for long.

I would be happy to learn how to make this portable as soon as I stop
the limit cycles in my control system.




 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      12-29-2004
No Spam wrote:

> #define POSITIVE_INTEGRATOR_SATURATION 0x03000000L //
> #define NEGATIVE_INTEGRATOR_SATURATION 0xFD000000L //
>
> long integrator;
>
> integrator=0;
>
> if (integrator>POSITIVE_INTEGRATOR_SATURATION)
> integrator=POSITIVE_INTEGRATOR_SATURATION;
> if (integrator<NEGATIVE_INTEGRATOR_SATURATION)
> integrator=NEGATIVE_INTEGRATOR_SATURATION;
>
> 1. Why does the executable always assign
> NEGATIVE_INTEGRATOR_SATURATION to integrator?


Because NEG...ION is a large positive number, hence
greater than zero.

> -I assume that long declaration means the value is signed (the most
> significant bit indicates sign)


Yes, a `long' is signed. And yes, the most significant
bit of a signed integer is the sign bit. But you've missed
something: The type of 0xFD000000L is not `long' (on your
machine, where `long' occupies 32 bits), but `unsigned long'.
Section 6.4.4.1 paragraph 5:

The type of an integer constant is the first of the
corresponding list in which its value can be
represented.
[... and for a hexadecimal constant with an L suffix
the list begins `long int', `unsigned long int', ...]

Since the value 0xFD000000L (424463564 is greater than
your system's LONG_MAX, it cannot be represented as a `long'.
But it can be represented as an `unsigned long', so that is
the constant's type.

Now: Almost all C operators that use two operands require
the operands to have the same type. If they're not already
of the same type, C promotes one or both until the promoted
types match, and then applies the operator to the promoted
values. When you write

integrator < NEG...ION

you are trying to compare a `long' and an `unsigned long',
so C actually evaluates

(unsigned long)integrator < NEG...ION

.... and for the values given, this comparison is true.

Suggested fix:

#define NEG...ION -0x30000000L

Inferior (because of dubious portability) fix:

#define NEG...ION (long)0xFD000000

General principle: Stop thinking about the way your numbers
are represented, and start thinking about their values. You
will save yourself much frustration by doing so.

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)lid
 
Reply With Quote
 
 
 
 
No Spam
Guest
Posts: n/a
 
      12-29-2004
On Wed, 29 Dec 2004 08:50:46 -0500, Eric Sosman
<(E-Mail Removed)> wrote:

>No Spam wrote:
>
>> #define POSITIVE_INTEGRATOR_SATURATION 0x03000000L //
>> #define NEGATIVE_INTEGRATOR_SATURATION 0xFD000000L //
>>
>> long integrator;
>>
>> integrator=0;
>>
>> if (integrator>POSITIVE_INTEGRATOR_SATURATION)
>> integrator=POSITIVE_INTEGRATOR_SATURATION;
>> if (integrator<NEGATIVE_INTEGRATOR_SATURATION)
>> integrator=NEGATIVE_INTEGRATOR_SATURATION;
>>
>> 1. Why does the executable always assign
>> NEGATIVE_INTEGRATOR_SATURATION to integrator?

>
> Because NEG...ION is a large positive number, hence
>greater than zero.
>
>> -I assume that long declaration means the value is signed (the most
>> significant bit indicates sign)

>
> Yes, a `long' is signed. And yes, the most significant
>bit of a signed integer is the sign bit. But you've missed
>something: The type of 0xFD000000L is not `long' (on your
>machine, where `long' occupies 32 bits), but `unsigned long'.
>Section 6.4.4.1 paragraph 5:
>
> The type of an integer constant is the first of the
> corresponding list in which its value can be
> represented.
> [... and for a hexadecimal constant with an L suffix
> the list begins `long int', `unsigned long int', ...]


> Since the value 0xFD000000L (424463564 is greater than
>your system's LONG_MAX, it cannot be represented as a `long'.
>But it can be represented as an `unsigned long', so that is
>the constant's type.


You are telling me

#define foo1 0xFFFFFFFFL

#define foo2 -1L

(foo1==foo2) evaluates to false

where the machine allocates 32 bits for type long?

Correct?

So by the paragraph,


#define foo1 0xFFFFFFFFUL

#define foo2 0xFFFFFFFFL

(foo1==foo2) evaluates to true (on my machine)?


> Now: Almost all C operators that use two operands require
>the operands to have the same type. If they're not already
>of the same type, C promotes one or both until the promoted
>types match, and then applies the operator to the promoted
>values. When you write
>
> integrator < NEG...ION
>
>you are trying to compare a `long' and an `unsigned long',
>so C actually evaluates
>
> (unsigned long)integrator < NEG...ION
>
>... and for the values given, this comparison is true.
>
> Suggested fix:
>
> #define NEG...ION -0x30000000L
>
> Inferior (because of dubious portability) fix:
>
> #define NEG...ION (long)0xFD000000
>
> General principle: Stop thinking about the way your numbers
>are represented, and start thinking about their values. You
>will save yourself much frustration by doing so.


Yes I freely admit that I translated the code into C from an assembly
program, but kept the assembly language way of thinking. Plus I never
would have thought of expressing a hexadecimal number with a negative
sign in front of it.
 
Reply With Quote
 
Dietmar Schindler
Guest
Posts: n/a
 
      12-30-2004
No Spam wrote:
> You are telling me
>
> #define foo1 0xFFFFFFFFL
>
> #define foo2 -1L
>
> (foo1==foo2) evaluates to false
>
> where the machine allocates 32 bits for type long?


Let me say that he is not telling you that. For the equality operation,
the (long) operand -1L is converted to the type of the (unsigned long)
operand 0xFFFFFFFFL. Consequently, the expression evaluates to 1 (true).
 
Reply With Quote
 
Lawrence Kirby
Guest
Posts: n/a
 
      12-30-2004
On Wed, 29 Dec 2004 20:58:42 +0000, No Spam wrote:

> On Wed, 29 Dec 2004 08:50:46 -0500, Eric Sosman>
> <(E-Mail Removed)> wrote:


....

>> Since the value 0xFD000000L (424463564 is greater than
>>your system's LONG_MAX, it cannot be represented as a `long'.
>>But it can be represented as an `unsigned long', so that is
>>the constant's type.

>
> You are telling me
>
> #define foo1 0xFFFFFFFFL
>
> #define foo2 -1L
>
> (foo1==foo2) evaluates to false
>
> where the machine allocates 32 bits for type long?
>
> Correct?


No, on an implementation with 32 bit longs Eric is saying that 0XFFFFFFFFL
will have type unsigned long. In the expression foo1==foo2, since the left
hand side has type unsigned long, the right hand side will be converted to
that type before the comparison is made. (unsigned long)-1L evaluates to
ULONG_MAX which in 32 bits will be 0xFFFFFFFF so foo1 and foo2 will
compare equal in that case.

> So by the paragraph,
>
>
> #define foo1 0xFFFFFFFFUL
>
> #define foo2 0xFFFFFFFFL
>
> (foo1==foo2) evaluates to true (on my machine)?


Yes, in a 32 bit type foo1 and foo2 both have type unsigned long
with the same value.

Lawrence
 
Reply With Quote
 
Micah Cowan
Guest
Posts: n/a
 
      01-03-2005
Lawrence Kirby wrote:
>>#define foo1 0xFFFFFFFFUL
>>
>>#define foo2 0xFFFFFFFFL
>>
>>(foo1==foo2) evaluates to true (on my machine)?

>
>
> Yes, in a 32 bit type foo1 and foo2 both have type unsigned long
> with the same value.


Actually, on an implementation with 32-bit long, 0xFFFFFFFFL
should be implementation defined, no? (i.e., it won't necessarily
get the value -1, and thus won't necessarily convert to
0xFFFFFFFFUL on comparison...)
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      01-03-2005
Micah Cowan wrote:
> Lawrence Kirby wrote:
>
>>>#define foo1 0xFFFFFFFFUL
>>>
>>>#define foo2 0xFFFFFFFFL
>>>
>>>(foo1==foo2) evaluates to true (on my machine)?

>>
>>
>>Yes, in a 32 bit type foo1 and foo2 both have type unsigned long
>>with the same value.

>
>
> Actually, on an implementation with 32-bit long, 0xFFFFFFFFL
> should be implementation defined, no? (i.e., it won't necessarily
> get the value -1, and thus won't necessarily convert to
> 0xFFFFFFFFUL on comparison...)


Aside from the 32-bitness of `long' there's nothing
implementation-defined about it. The constant's value is
too large for `long', so its type will be `unsigned long'
and its value will be 4294967295UL or `(unsigned long)-1'.

--
(E-Mail Removed)

 
Reply With Quote
 
Micah Cowan
Guest
Posts: n/a
 
      01-04-2005
Eric Sosman wrote:
> Micah Cowan wrote:


> Aside from the 32-bitness of `long' there's nothing
> implementation-defined about it. The constant's value is
> too large for `long', so its type will be `unsigned long'
> and its value will be 4294967295UL or `(unsigned long)-1'.
>


Oops. Yup. I shoulda known better than to correct a message from
Lawrence.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pre-ansi to ansi c++ conversion? Frank Iannarilli C++ 2 07-21-2009 11:05 PM
Are there statistics packages in ANSI C and/or ANSI C++? lbrtchx@gmail.com C Programming 11 04-28-2008 03:00 AM
Are there statistics packages in ANSI C and/or ANSI C++? lbrtchx@gmail.com C++ 1 04-24-2008 06:44 PM
Typed arrays (was: Is it ANSI or is it compiler dependent?) Canonical Latin C++ 19 05-12-2004 08:47 PM
Is it ANSI or is it compiler dependent? Canonical Latin C++ 22 05-12-2004 12:25 AM



Advertisments