|
|
View previous topic :: View next topic |
Author |
Message |
evelikov92
Joined: 10 Mar 2015 Posts: 23
|
Big problem with simple math operation |
Posted: Tue May 19, 2015 1:24 pm |
|
|
Hi everybody!
I used pic18f6722 and 20x4 lcd with flexible driver
I have a big problem with few math operation, and variables;
Maybe sounds funny or/and stupid but I crazy because is not working fine;
I have first, second, and third number which is int8 and is between 0-255; and result which is long and is big number > 4 000 000 000
but when I used
first = 200;
second = 200;
result = first + second --> and result is not 400, but is 144
result = first * second --> and result is not 40 000, but is between 0-255
I want to calculate:
result = first + (second * 100) + (third * 60 * 100);
How can I fix this problem.
main.c
Code: |
#include "main.h"
#fuses NOXINST
#use delay(clock=32000000)
#include <flex_lcd.c>
void main()
{
int8 first, second, third;
long result;
setup_oscillator(OSC_32MHZ);
delay_ms(100);
lcd_init();
delay_ms(100);
first = read_eeprom(0x55);
second = read_eeprom(0x56);
third = read_eeprom(0x57);
result = first + (second * 100) + (third * 60 * 100);
lcd_gotoxy(1, 1);
printf(lcd_putc, "R: %u %u %u = %ld", first, second, third, result); //Display R: 255 255 255 = 43
first = 200;
second = 200;
result = first + second;
lcd_gotoxy(1, 2);
printf(lcd_putc, "F: %u + %u = %ld", first, second, result); //Display F: 200 + 200 = 144
first = read_eeprom(0x55);
second = 100;
result = first + second;
lcd_gotoxy(1, 3);
printf(lcd_putc, "S: %u + %u = %ld", first, second, result); //Display S: 200 + 100 = 99
write_eeprom(0x55, 200);
first = read_eeprom(0x55);
second = 100;
result = first + second;
lcd_gotoxy(1, 4);
printf(lcd_putc, "T: %u + %u = %ld", first, second, result); //Display T: 200 + 100 = 44
}
|
main.h
Code: |
#include <18F6722.h>
#device adc=12
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV25 //Brownout reset at 2.5V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES XINST //Extended set extension and Indexed Addressing mode enabled
#FUSES BBSIZ1K //1K words Boot Block size
#use delay(clock=32000000)
|
My version of CCS C Compiler is 4.057.
best regard evelikov92 |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1357
|
|
Posted: Tue May 19, 2015 2:05 pm |
|
|
you need to do some casting.
When you have:
Code: |
unsigned int8 A = 200;
unsigned int8 B = 200;
unsigned int32 C;
C = A + B;
|
Since both A and B are int8 sized variables, their result has to be int8. Remember the compiler isn't going to up convert for you. So the process for your original code is:
unsigned int8 value + unsigned int8 value = unsigned int8 value;
unsigned int32 value = (unsigned int32)unsigned int8 value;
Which isn't the process you were aiming for.
If you want the actual addition result to be the same size as C you need to cast either A or B to unsigned int32:
Code: |
unsigned int8 A = 200;
unsigned int8 B = 200;
unsigned int32 C;
C = A + (unsigned int32)B;
|
That'll force the compiler to cast A to an unsigned int32 to match B and the result will be unsigned int32.
The same applies to multiplication, you need one of the params to be the size of the result (via casting) so that the math gets converted to the size you want.
C = ((unsigned int32)A)*200 + B;
for example.
EDIT: Also avoid using non specific types like int and long. Stick to sized types like int8, int16, etc. |
|
|
evelikov92
Joined: 10 Mar 2015 Posts: 23
|
|
Posted: Wed May 20, 2015 12:11 am |
|
|
It's working. Thanks for fast answer jeremiah. |
|
|
|
|
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
|