CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

int32 overflow
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kmp84



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

int32 overflow
PostPosted: Tue Apr 14, 2020 9:23 am     Reply with quote

Hello,

What will be the easy way to check "unsigned int32" overflow?
I have multiplication with two "unsigned int32" variable and want to check if result overflow instead show wrong value.

Best Regards!
Ttelmah



Joined: 11 Mar 2010
Posts: 19218

View user's profile Send private message

PostPosted: Tue Apr 14, 2020 10:11 am     Reply with quote

What processor family?. PIC16, 18, 24, 30 etc..

If you are using a PIC24, 30 or 33, you can use 'mul' which will produce
an int64 result. You can then test this against the maximum limit for
the int32.
On the smaller PIC's, it has been discussed here in the past that the
status register bits do reflect the result of the MSB operation after a
sum. So though rather 'unwanted' to be using low level operations like
this, it is possible to use these:

<https://www.ccsinfo.com/forum/viewtopic.php?p=144142>
kmp84



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

PostPosted: Tue Apr 14, 2020 12:00 pm     Reply with quote

Now I'm testing on PIC16F1459 but for future project will use PIC18.

Some test code:
Code:

#include <16F1459.h>
#device *=16
#fuses INTRC_IO,NOPROTECT,MCLR,PUT,NOWDT  // CLKOUT -> Enable clk/4 out on PIN_A4
#use delay(int=16MHz, clock=32MHz)
#USE RS232(DEBUGGER,rcv=PIN_B6,xmit=PIN_B6,stream=STREAM_MONITOR)

#zero_ram
void main(void){
   
   unsigned int32 Vol, Prc, Sum;
   
   delay_ms(100);                //StartUp Delay.
   setup_adc(ADC_OFF);           //Stop ADC.
   setup_adc_ports(NO_ANALOGS);  //Disable Adc-channels.
   setup_comparator(NC_NC_NC_NC);//Disable Comparator module.
                           
   printf("\n\rTarget 16F1459 Start.\n\r");
   
   Vol = 1234567;
   Prc = 12345;
   
   Sum = ((unsigned int32)Vol*Prc)/100;   // check Sum overflow?   
   printf("\r\nSum=%lu\r\n", Sum);   
                         
   for(;;){                         
      //           
   } 
}


How long take this calc. "Sum = ((unsigned int32)Vol*Prc)/100;" and can be optimized?
How to check with lowlevel asm flags (some carry flag)?
Quote:

Easy. Check to see if the result (a^2 + b^2) is less than either a^2 or b^2. If it is, there was an overflow. It's not a valid test for all combinations of a & b, but it's probably sufficient most of the time.

This check is not 100% ? If a^2 or b^2 overflow this compare will not be valid?
Ttelmah



Joined: 11 Mar 2010
Posts: 19218

View user's profile Send private message

PostPosted: Tue Apr 14, 2020 12:38 pm     Reply with quote

Code:

#byte STATUS=getenv("SFR:STATUS")
#bit CARRY=STATUS.0


The carry bit is then available for you to test.
jeremiah



Joined: 20 Jul 2010
Posts: 1317

View user's profile Send private message

PostPosted: Tue Apr 14, 2020 1:14 pm     Reply with quote

Ttelmah wrote:
Code:

#byte STATUS=getenv("SFR:STATUS")
#bit CARRY=STATUS.0


The carry bit is then available for you to test.


If the mnemonic is unique, you can also just do the bit variable using getenv():

Code:

#bit CARRY=getenv("BIT:C")
kmp84



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

PostPosted: Tue Apr 14, 2020 2:15 pm     Reply with quote

Code:

#byte STATUS=getenv("SFR:STATUS")
#bit CARRY=STATUS.0

#bit CARRY=getenv("BIT:C")


With both declaration CARRY bit doesn't change after mul. overflow.

Code:

   Sum = (unsigned int32)Vol*Prc;
   printf("\r\nSum=%lu, Carry:%u\r\n", Sum, CARRY);   



Compiler ver.5.092.
gaugeguy



Joined: 05 Apr 2011
Posts: 288

View user's profile Send private message

PostPosted: Tue Apr 14, 2020 2:53 pm     Reply with quote

The carry bit is going to be corrupted by the math in the printf function. You need to preserve the status of the carry bit just after the multiply by copying its state into another variable.
kmp84



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

PostPosted: Tue Apr 14, 2020 3:07 pm     Reply with quote

Quote:

The carry bit is going to be corrupted by the math in the printf function. You need to preserve the status of the carry bit just after the multiply by copying its state into another variable.


It's not the problem. In debug mode also doesn't change.
Ttelmah



Joined: 11 Mar 2010
Posts: 19218

View user's profile Send private message

PostPosted: Wed Apr 15, 2020 1:57 am     Reply with quote

Key word 'DEBUG'.

If you look at the older thread about this, with the link I gave in my first
reply, you will see that he found the debugger did not correctly update
the status bits, but that they were updating.
Code:

   int1 carry_copy;


   Sum = (unsigned int32)Vol*Prc;
   carry_copy=CARRY;

   printf("\r\nSum=%lu, Carry:%u\r\n", Sum, carry_copy);


As a comment too, you don't show the declarations of Vol, and Prc,
but if Prc is not int32, then how can an overflow occur?. Int32
arithmetic won't overflow multiplying any smaller type. If you are
multiplying int16's and want to verify the result will fit into an int16,
you need to use int16 arithmetic, or int32 arithmetic, store the result
into an int32, and then test the result against INT16_MAX from
stdint.h.
You say in your original post that you are using unsigned int32
variables, but in your post here you show a variable being cast up
to be an unsigned int32.
Ttelmah



Joined: 11 Mar 2010
Posts: 19218

View user's profile Send private message

PostPosted: Wed Apr 15, 2020 3:54 am     Reply with quote

OK.
Update on this.

I went back to a really old compiler, and tried a test on a basic PIC18.
On this the carry flag does get set (V4 compiler).
However on the PIC16 here, and on the current compilers, it doesn't.
On the PIC16 here it is permanently clear. On the PIC18, it is permanently
set even if there isn't an overflow.
The way to get to this is to access the contents of @MUL3232.@SCRATCH1
However not sure of an easy way to find this.

Wrote a basic program by using the symbol file to get the address of this
which on this code was address 0x5B
Code:

#DEFINE OVERFLOW 0x5B //@MUL3232.@SCRATCH1

void main()
{
   unsigned int32 Vol, Prc, Sum;
   unsigned int16 carry_copy;
   
   Vol = 1234567;
   Prc = 12345; 
   sprintf(output, "\n\rTarget 16F1459 Start.\n\r");   
   
   while(TRUE)
   {
      for (Prc=3000;Prc<15000;Prc+=100)
      {   
         Sum = Vol*Prc;
         carry_copy=*(int16*)OVERFLOW;
         carry_copy=carry_copy!=0;
     
         sprintf(output, "\r\nSum=%lu, Carry:%lu\r\n", Sum, carry_copy);
         delay_cycles(1);
      }
   }
}


This correctly sees 'carry_copy' go to 1, when the maths overflows on
the fifth loop. I don't know if there is an easy way to make a variable
access the scratch variable without having to look it up in the symbol
file. Maybe getenv will allow access to the scratch variables?.
I know it will tell you where the scratch area 'is', but not if there is
any way of finding a specific variable...
temtronic



Joined: 01 Jul 2010
Posts: 9102
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Apr 15, 2020 5:23 am     Reply with quote

hmm..I've been pondering this and ...

if you check to see if BOTH variables are > than a 'magic' value, then you will have an overflow.

Using unsigned 8 bit variables A, B, RESULT

If A and B are both => 16, an overflow will occour for RESULT.

In this case 16 is the 'magic' value, accually the square root of 256.

Potentially it should be faster being done BEFORE the A X B operation ?

This looks good in my mind...hopefully someone smarter than me can check it out....

Jay
jeremiah



Joined: 20 Jul 2010
Posts: 1317

View user's profile Send private message

PostPosted: Wed Apr 15, 2020 6:38 am     Reply with quote

temtronic wrote:
hmm..I've been pondering this and ...

if you check to see if BOTH variables are > than a 'magic' value, then you will have an overflow.

Using unsigned 8 bit variables A, B, RESULT

If A and B are both => 16, an overflow will occour for RESULT.

In this case 16 is the 'magic' value, accually the square root of 256.

Potentially it should be faster being done BEFORE the A X B operation ?

This looks good in my mind...hopefully someone smarter than me can check it out....

Jay


In this vein, I don't think you need a magic value. Just check and see if the result of the multiplication is LESS than both of the operands. If so, the multiplication wrapped around (overflowed).

Does that seem viable/plausible?


Last edited by jeremiah on Wed Apr 15, 2020 8:13 am; edited 2 times in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19218

View user's profile Send private message

PostPosted: Wed Apr 15, 2020 7:29 am     Reply with quote

Yes,
The magic value approach has issues. Think about the situation where
one value (for the 8bit example), is 254, while the other is just 2. Both
numbers are not greater than 16, yet the value will definitely overflow....

The test that would work, would be to work out which of the initial values
was the largest, then if the result is less than this, an overflow has taken
place. This is Jeremiah's suggestion. The only situation that also has to
be tested for is one of the multiplicands being zero.
temtronic



Joined: 01 Jul 2010
Posts: 9102
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Apr 15, 2020 8:29 am     Reply with quote

Well I knew thinking without coffee is a bad idea.... Very Happy
I was just trying to save a lot of time doing the multiply
so much for a clever shortcut, but I'm glad others figured it out....
kmp84



Joined: 02 Feb 2010
Posts: 345

View user's profile Send private message

PostPosted: Wed Apr 15, 2020 9:02 am     Reply with quote

Thanks mr. Ttelmah,

You 'save' my future project Smile
For me the easy way was to check STATUS overflow bit. I don't know why CCS 'destroy' standard working features. May be in v.6.xxx will come back Smile.

Best Wishes.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group