C Integrator wind up problem

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi there,

I use the IAR C compiler and I have this problem:

if ((x += y) >= 32767) x = 32767;
if ((x += y) <= -32768) x = -32768;

Note that x, y are signed integers.

In both cases I cannot limit x to respective limit value, because x overflows before each comparison.

I think that this most likely a generic C problem thats why I posted in this GCC forum.

Please is there any ideas to slve simply without using lengthy code (temporary registers etc).

Thanks,

Michael

Michael.

User of:
IAR Embedded Workbench C/C++ Compiler
Altium Designer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I think that this most likely a generic C problem thats why I posted in this GCC forum.

Bob has killed people for lesser offences!

If it's a generic C problem it belongs in "AVR Forum"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One idea:

int temp;
if ((temp = x + y) < x)
    x = temp;
else
    x = 32767;

Edit: However, if y can be negative, you'll have to check the sign of y, too.

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sebastian,

Actually I am trying to find a solution without the need of a temporary register, but as I see and also you suggested I am going to solve the problem using this solutiaon.

Thanks for your time.

Michael

Michael.

User of:
IAR Embedded Workbench C/C++ Compiler
Altium Designer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hm, isn't the V flag in the status register an overflow indicator? But I'm not sure, I'm no assembler expert. Maybe you can avoid with an inline assembler block the temporary register.

EDIT: Take a look at the instructions BRVC and BRVS

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't you think the compiler might just be using a "temporary register" behind this code anyway? Often the introduction of an intermediate automatic actually leads to a MORE efficient solution from the compiler so don't consdier it line by line but take a look at what the compiler's complete solution is.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

icarus1 wrote:
Hi there,

I use the IAR C compiler and I have this problem:

if ((x += y) >= 32767) x = 32767;
if ((x += y) <= -32768) x = -32768;

Note that x, y are signed integers.

In both cases I cannot limit x to respective limit value, because x overflows before each comparison.

I think that this most likely a generic C problem thats why I posted in this GCC forum.

Please is there any ideas to slve simply without using lengthy code (temporary registers etc).

Thanks,

Michael

you have to do the calculation as a long (32bit) calculation & comparison. You are right, you are overflowing, but your limit is also the limit for a 16bit signed value. This is not an IAR problem, and not really a problem at all. The C compiler is obeying the order of operations rules as it is supposed to. Your brackets even go on to enforce them further.

So there is no way that the result can ever be > or < your limits. You will have to use a 32bit temp var, or change the nature of your calculation. Which ever way you do it, there will be a speed penalty.

Also I doubt you really wanted to add y to x twice, which is in fact what your code was doing, once in each if case.

long tmp = x;

tmp += y;
if (tmp >= 32767L) tmp = 32767;
if (tmp <= -32768L) tmp = -32768;
x = tmp;

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:
I think that this most likely a generic C problem thats why I posted in this GCC forum.

Bob has killed people for lesser offences!

If it's a generic C problem it belongs in "AVR Forum"

I would have thought generic C problems belonged in the Off Topic forum if anywhere.

Jim (with pedants hat on) (the one with little jingly bells on it, if you're not sure)

Your message here - reasonable rates.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How about:

if (y<0) {
	 if ((x += y) > 0 ) 
		  x = -32768;
} else {
	 if ((x += y) < 0 ) 
		  x = 32767;
}

Edit: this doesn't work. Never mind.

C: i = "told you so";