Go Down

#### leonelpepe

##### Oct 30, 2012, 03:46 amLast Edit: Oct 30, 2012, 04:53 am by leonelpepe Reason: 1
Hi,

I have a doubt whit the addition instruction and know if an overflow happened.

uint8_t a = 200;
uint8_t b = 200;

uint8_t c = a + b; // the sum is overflowed

// c is 200 + 200 = 400 >>> 400 - 255 = 145

I can tell if the sum is overflowed.

In ASM normally I have the carry bit to know that. In C and in Arduino, can I use a instruction, flag or something similar?

Thanks.

#### PeterH

#1
##### Oct 30, 2012, 03:59 am

In C and in Arduino, can I use a instruction, flag or something similar?

No, there's nothing like that.
I only provide help via the forum - please do not contact me for private consultancy.

#### leonelpepe

#2
##### Oct 30, 2012, 04:06 am
OK, it is a very bad news. The only way that I can tinks is that c must be greather than a and b at the same time:

Code: [Select]
`uint8_t a = 200;uint8_t b = 200;uint8_t c = a + b; // the sum is overloaded// c is 200 + 200 = 400 >>> 400 - 255 = 145if (c < a && c < b) {  // Overload have being success.}`

#### lloyddean

#3
##### Oct 30, 2012, 04:15 am
I think you're referring to 'overflow' not overload.

#### leonelpepe

#4
##### Oct 30, 2012, 04:52 am

I think you're referring to 'overflow' not overload.

mmm. Yes, I'm not speak English very well. Sorry.

#5
##### Oct 30, 2012, 05:38 am

Give this a try...

Code: [Select]
`bool SafeAdd( uint8_t a, uint8_t b, uint8_t & r ){  uint16_t t;    t = a + b;    r = t;    return( (t & 0xFF00) == 0 );}bool SafeAdd( uint16_t a, uint16_t b, uint16_t & r ){  uint32_t t;    t = a + b;    r = t;    return( (t & 0xFFFF0000) == 0 );}void Test1( void ){  uint8_t a = 200;  uint8_t b = 200;  uint8_t r;  if ( SafeAdd( a, b, r ) )  {    Serial.println( F( "No problem." ) );  }  else  {    Serial.println( F( "Bad news!" ) );  }}void Test2( void ){  uint8_t a = 200;  uint16_t b = 200;  uint16_t r;  if ( SafeAdd( a, b, r ) )  {    Serial.println( F( "No problem." ) );  }  else  {    Serial.println( F( "Bad news!" ) );  }}void setup( void ){  Serial.begin( 250000 );    Test1();  Test2();}void loop( void ){}`

#### leonelpepe

#6
##### Oct 30, 2012, 05:57 am

Give this a try...

It is a great idea. Thanks, but... if I want to use a 32 bit variable? jaja

#7
##### Oct 30, 2012, 06:04 am

Then you use uint64_t for the result.

#### Mitxel

#8
##### Nov 07, 2012, 02:24 pm
I think, but am not sure, you can access the microcontroller "status register" from C code.

I think in "Arduino C" there is a special variable called "SREG" which is a representation of the status register of the microcontroller. The microcontroller status register contains a collection of flags and one of those flags is the carry flag. I think the carry flag is the flag in the status register bit0 .

You could try something like this:

Code: [Select]
`boolean isCarryOverflow(){return(SREG & 0x01); //Assuming the carry flag in on bit0}void setup(){......c = a + b;if(isCarryOverflow){...}...}`

ATmega datasheet >> http://www.atmel.com/Images/doc8161.pdf (page 10)
http://www.wvshare.com/article/AVR-1-1-5.htm

#### pYro_65

#9
##### Nov 07, 2012, 02:32 pm
Quote

• Bit 0 - C: Carry Flag
The Carry Flag C indicates a carry in an arithmetic or logic operation. See the "Instruction Set
Description" for detailed information.

Yeah its bit 0, there is also an instruction 'BSET' for checking bits in the status register.
https://forum.arduino.cc/index.php?action=dlattach;topic=327736.0;attach=128670 New EEPROM library released

#### Krupski

#10
##### Nov 07, 2012, 02:53 pm

Hi,

I have a doubt whit the addition instruction and know if an overflow happened.

uint8_t a = 200;
uint8_t b = 200;

uint8_t c = a + b; // the sum is overflowed

An unsigned 8 bit INT can only hold a value from 0 to 255 (decimal). If you add one to 255, it "rolls over" back to zero.

You need to use a larger INT... maybe a uint16_t (16 bits - 0 to 65535) or a uint32_t (32 bits - 0 to 4294967295) or even a uint64_t (64 bits.... ginormous!)

You can detect if a variable has overflowed. There is no carry bit available to C, but if the result is smaller than you expect, you can assume that an overflow has occurred.

Note that this is also true with subtraction... a uint8_t with a value of 0, minus 1 = 255. In this case, the result is larger than you expect and this signifies a borrow.
Gentlemen may prefer Blondes, but Real Men prefer Redheads!

#11
##### Nov 07, 2012, 07:07 pmLast Edit: Nov 07, 2012, 07:10 pm by Coding Badly Reason: 1
I think, but am not sure, you can access the microcontroller "status register" from C code.

You can but doing so is "dangerous".  The compiler can reorder (or even remove) code when it optimizes.  When you write this...

Quote
[font=Courier New]c = a + b;
if(isCarryOverflow())
{
...
}
// Some code after the if that has no dependency on anything above.[/font]

The compiler could do something like this...

Quote
[font=Courier New]c = a + b;
// Some code that was after the if that has no dependency on anything nearby.
if(isCarryOverflow())
{
...
}[/font]

In other words, there is no way to guarantee the SREG check is performed immediately after the addition.

#### Mitxel

#12
##### Nov 07, 2012, 07:37 pm
You can but doing so is "dangerous".  The compiler can reorder (or even remove) code when it optimizes.  When you write this...

Yes, the compiler optimizer is always surprising.

This guy (http://www.fefe.de/intof.html) says that if an addtion  of integers owerflowed, then the sum is always less than either addend. (I do not know the reason)

Then, say, we have A which is an integer of 48 bits, consisting A_Hi (16 bits) and A_Low (32 bits) and we add B which is a 32-bit integer.

Maybe something like that would work

Code: [Select]
`unsigned int A_Hi;unsigned long A_Low;unsigned long B;A_Low += B;if(B > A_Low) A_Hi ++;`

(I apologize for my horrid English)

#### PeterH

#13
##### Nov 07, 2012, 07:48 pm

This guy (http://www.fefe.de/intof.html) says that if an addtion  of integers owerflowed, then the sum is always less than either addend. (I do not know the reason)

I haven't followed that link, but I expect you meant to say that at least one of the addends will be greater than the sum (they may not both be greater).
I only provide help via the forum - please do not contact me for private consultancy.

#### robtillaart

#14
##### Nov 07, 2012, 08:26 pm
Quote
I haven't followed that link, but I expect you meant to say that at least one of the addends will be greater than the sum (they may not both be greater).

if a <=255 and b<=255 and a+b > 255 ==>  (a+b)%256 < a  and (a+b)%256 < b

you can test this quite simple
Code: [Select]
`void setup(){  Serial.begin(115200);  for (uint8_t a = 0; a < 255; a++) // 255 not in the loop to prevent endless loop    for (uint8_t b = 0; b < 255; b++)    {      uint8_t c = a + b;      uint16_t d = (uint16_t )a + b;      Serial.print((int)a);      Serial.print('\t');      Serial.print((int)b);      Serial.print('\t');      Serial.print((int)c);      Serial.print('\t');      Serial.print(c < a?"overflow":"ok");      Serial.println();    }}void loop(){}`

but you can test overflow before it occurs just by doing a subtraction, no need to test a register, works for 16, 32 and 64 bit

Code: [Select]
`void setup(){  Serial.begin(115200);  for (uint8_t a = 0; a < 255; a++)    for (uint8_t b = 0; b < 255; b++)    {      if (255 - b < a ) Serial.println("overflow");      else Serial.println((int)(a+b));    }}void loop(){}`

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up

Please enter a valid email to subscribe