0
\$\begingroup\$

I have this code and i use in my device.

PIC18F252 PCH compiler CCS 5.007
//t_time_stamp=3776590560;            // 2019/09/04  12:56:00
utc_sec = t_time_stamp % 60;          //int32

min_temp = t_time_stamp / 60;         //float32 
min_temp_int = t_time_stamp / 60;     //int32
utc_min = min_temp_int % 60;          //int32

hour_temp = min_temp / 60;            //float32 
hour_temp_int = min_temp / 60;        //int32
utc_hour = hour_temp_int % 24;        //int32

day_temp1 = hour_temp / 24;           //float32 
day_temp1_int = hour_temp / 24;       //int32
day_temp2_int = day_temp1_int % 1461; //int32
utc_day_cnt = (day_temp2_int % 365) + 1; 

utc_year_cnt = day_temp1 / 365.25;    //int32 code here

It work correctly until 5 last month, but hour_temp_int is not correctly now; hour_temp_int is 11 at 10:26 to 10:30 but it should be 10! Only this parameter and at this time is not correct! What is my mistake? Basic and Special types I change types float32 to unsigned float32 or float48 but i have Error enter image description here

\$\endgroup\$
0

2 Answers 2

2
\$\begingroup\$

Mistake is to use floating point numbers here as precision of 1 is needed. With floating point numbers there will be rounding errors and for example 32-bit floats do not have precision of 1 any more at values larger than 16777215.

I don't have the same rounding problem on my PC, but a different one:

3776579879 -> 9:57:59

3776579880 -> 10:58:0

3776579999 -> 10:59:59

3776580000 -> 10:0:0

\$\endgroup\$
4
  • \$\begingroup\$ i use code in my products at 10 years ago so and this code at all time is ok and only at last 5 month 10:26:00 to 10:30:00 is not correct and only at hour ! why second , min , day, and other is correct? \$\endgroup\$ Commented Sep 14, 2019 at 8:41
  • \$\begingroup\$ Seconds are correct because calculations uses integer modulo arithmetic. Minutes are correct because calculations use integer division and integer modulo arithmetic. Hours may have rounding errors because it is using float arithmetic, first integer seconds are converted to float minutes with a float division, and then to float hours with float division before storing the result back into integer hours variable. I did not analyze if your day calculation is correct or not. \$\endgroup\$
    – Justme
    Commented Sep 14, 2019 at 9:13
  • \$\begingroup\$ I chang to float64 but it make Error 48 and for unsigned float32 it make Error 38 \$\endgroup\$ Commented Sep 14, 2019 at 9:34
  • \$\begingroup\$ Your answer is make sense And "why the answer was correct" is a good question. I have to decrease 100 years so that the computation is less than 32 bits \$\endgroup\$ Commented Sep 14, 2019 at 10:13
0
\$\begingroup\$

thanks for Justme I change start time from 1900 to 2000 and use 32 bit variable by this way my problem was solved! in this case we don't have more than 31 bit data and it work to 2036! this is my new code

t_time_stamp= t_time_stamp - 3155760000;
utc_sec = t_time_stamp % 60;
min_temp_int = (unsigned int32) (t_time_stamp / 60);
utc_min = min_temp_int % 60;
hour_temp_int = (unsigned int32) ( min_temp_int / 60);
utc_hour = hour_temp_int % 24;
day_temp1_int = (unsigned int32) (hour_temp_int / 24);
day_temp2_int = day_temp1_int % 1461;
utc_day_cnt = (day_temp2_int % 365) + 1;
utc_year_cnt = (unsigned int32) (day_temp1_int / 365.25);
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.