Thread: Signed Long comparison in IF Statement

  1. #16
    Registered User
    Join Date
    Feb 2008
    Posts
    116
    Quote Originally Posted by iMalc View Post
    What happens if you replace:
    Code:
    else if(output < -255)
    with this?:
    Code:
    else if ((unsigned long)output >= 0x80000000UL && (unsigned long)output < 0xFFFFFF01UL)
    Cause if that works, I'd say you've run into a compiler bug.

    Note for others: I'm not interested in hearing about undefined behaviour when casting a negative to unsigned here.
    I'm interested in diagnosing a real-world problem that we can be pretty sure relates to a two's-complement machine.

    I'll try that on the hardware to see what happens

  2. #17
    Registered User
    Join Date
    Feb 2008
    Posts
    116
    Quote Originally Posted by rcgldr View Post
    How are KP, KI, and KD defined? If these are unsigned, then the calculation for output will get "promoted" to unsigned (although with 2's complement math, I'm not sure why this would cause a problem).

    If that's not the problem, then taking a guess here, on the compiler you are using, what is the default variable type for a decimal constant such as 255 or -255 as used in your if statements? Have you tried suffixing those constants with the letter L: 255L or -255L to see if that makes any difference?

    Can you try something simple like output = -255; sprintf(string,"%ld\n\r",output); ?

    I tried the 255L and -255L but that didn't work.
    I also just printed out the signed long output = -255, and it prints out -255. So that looks fine

  3. #18
    Registered User
    Join Date
    Feb 2008
    Posts
    116
    As far as compiler version, I think I have AVRGCC 3.4.1.95 that has GCC 4.6.2 for 8-bit AVR microcontrollers.

    I am using Atmel Studio 6 for the IDE.

  4. #19
    Registered User
    Join Date
    Feb 2008
    Posts
    116
    the max range that I need is from -20,000 to 20,000. So obviously I don't need signed long. Do you think switching to a smaller type like int16_t would be better and have less problems? I modified a code that I downloaded from the internet, but left the datatypes as it was since the code was suppose to be for a microcontroller board that was a PID controller for a motor.

  5. #20
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Plain int is guaranteed to have at least the range [-32767, 32767], so that would cover the max range that you have in mind, though it wouldn't hurt to #include <limits.h> and check INT_MIN and INT_MAX just in case your compiler is non-standard in that respect.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #21
    Registered User
    Join Date
    Feb 2008
    Posts
    116
    Quote Originally Posted by laserlight View Post
    Plain int is guaranteed to have at least the range [-32767, 32767], so that would cover the max range that you have in mind, though it wouldn't hurt to #include <limits.h> and check INT_MIN and INT_MAX just in case your compiler is non-standard in that respect.
    yeah so I checked this

    Code:
    	int setValue = 0;
    	int feedbackValue = 0;
    	static int errorValue = 0;
    	static int prevError = 0;
    	static int integral = 0;
    	int derivative = 0;
    	int output = 0;
    It works with changing the variables to "INT" from "SIGNED LONG", so I'm not quite sure what the difference is causing the problem or if it's a compiler thing.

  7. #22
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by dcwang3 View Post
    I also just printed out the signed long output = -255, and it prints out -255. So that looks fine
    Quote Originally Posted by dcwang3 View Post
    the max range that I need is from -20,000 to 20,000.


    Quote Originally Posted by dcwang3 View Post
    It works with changing the variables to "INT" from "SIGNED LONG", so I'm not quite sure what the difference is causing the problem or if it's a compiler thing.
    It's either a compiler issue if switching from ints to longs solved the problem or somehow you're getting values outside the range -32768 to +32767 during inputs or calculations.
    Last edited by rcgldr; 04-25-2013 at 02:07 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. typedef long int comparison
    By nepper271 in forum C++ Programming
    Replies: 2
    Last Post: 07-12-2011, 07:36 PM
  2. C++ - unsigned long long int comparison
    By grimuth in forum C++ Programming
    Replies: 8
    Last Post: 05-05-2010, 10:20 AM
  3. Unsigned Long returning signed value
    By dinklebaga in forum C Programming
    Replies: 3
    Last Post: 03-06-2009, 06:07 AM
  4. Short/long/signed/unsigned int
    By scuzzo84 in forum C Programming
    Replies: 4
    Last Post: 09-13-2005, 11:40 PM
  5. Replies: 8
    Last Post: 05-13-2003, 02:47 PM