View previous topic :: View next topic |
Author |
Message |
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
calculation |
Posted: Wed Apr 01, 2020 6:42 am |
|
|
Dear All,
I have a small issue. This is part of the code:
Code: |
unsigned int Alarm_1[9] = {15,35,23,23,12,00,9,00,20}; //stores 5 Alarms in steps of 3
unsigned int32 total_seconds;
unsigned int32 AlarmSecondsSort[3];
unsigned int32 timetodec(int Al_hour, int Al_minut, int Al_sec, int temp_array_pos)
{
unsigned int32 totaldecimal = 0;
totaldecimal = ((Al_hour*3600) + (Al_minut*60) + Al_sec);
AlarmSecondsSort[temp_array_pos] = totaldecimal;
return(0);
}
|
The Al_hour is 15, Al_minut = 35 and Al_sec = 23. For some reason the totaldecimal is coming 54075 instead of 56123. What could be the problem? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Wed Apr 01, 2020 7:26 am |
|
|
hmm.. the difference is a 'magical' 2048......
recode and display the calculate intermediate terms..
al_hour*3600, alminut*60
to see if they are incorrect.
hmm... another idea while I'm typing...
this...
Quote: | unsigned int32 timetodec(int Al_hour, int Al_minut, int Al_sec, int temp_array_pos)
{ |
says to use Al-hour as an integer NOT an unsigned int. That may affect how the compiler 'sees' the numbers.... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Wed Apr 01, 2020 7:58 am |
|
|
Change this:
(Al_minut*60)
To:
(Al_minut*60L)
Otherwise this multiplication will be performed using int arithmetic (255
max), so will overflow almost every time.... |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Wed Apr 01, 2020 7:59 am |
|
|
ok...I found the mistake.. I need to declare the Al_hour and Al_minut as int32. now it worked good. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Wed Apr 01, 2020 8:03 am |
|
|
No you don't.
Means wasted space for these values.
Code the line as:
totaldecimal = ((Al_hour*3600LL) + (Al_minut*60L) + Al_sec);
This forces the constants in the multiplications to be larger (int16 for the
minute multiplication - which is large enough to hold any value here), and
int32 for the hour multiplication.. Result you can keep the variables the
smaller size, but the compiler 'knows' to use the larger sizes for the
maths. |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Wed Apr 01, 2020 12:22 pm |
|
|
Yes it worked perfectly as well. Structly speak this was new for me. Why one is LL and the other one is L only? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Wed Apr 01, 2020 12:38 pm |
|
|
L makes it a 'long' int16. So only int16 arithmetic is used for thsi part.
This is quicker and smaller than int32, and minutes*60 is always small
enough to fit into an int16.
LL makes it a 'long long' int32. Houir*3600 can be large enough to exceed
an int16. 23*3600 = 86800. So here the int32 arithmetic must be used. |
|
|
|