0

I have stumbled over an interesting problem in C. I have to implement a timer function in my organization in Simulink (which is a modeling software). However, since it does not have timer function, I am using a custom block in simulink to write the C code

In the code below time_t is of long data type, which I have to convert to float to be able to use it in Simulink. However, when I convert long to float, the seconds do not update as frequenty when using the float variable, and the result also looks different

I tried to search over the internet regarding to how to typecast long to float in "C", and I found out that one has to just add (float) infront of the variable that needs to be typecasted

Can anyone help provide suggestions on what could be going wrong, and why the two print statements give different results and how can I fix it

Please take note that I have never programmed in "C" (this is my first code), so it would really help me if the explanations are simple

   #include <stdio.h>
   #include <time.h>
   int main () {
   time_t seconds;
   float seconds_f;
   seconds = time(NULL);
   seconds_f = (float)seconds;
   printf("Hours since January 1, 1970 = %f\n", seconds_f);
   printf("Hours since January 1, 1970 = %.ld\n", seconds);
  
   return(0);
}

Result snippet

$gcc -o main *.c
$main
Hours since January 1, 1970 = 1625470848.000000
Hours since January 1, 1970 = 1625470904
prehistoricpenguin
  • 6,130
  • 3
  • 25
  • 42
Masoom Kumar
  • 129
  • 1
  • 8
  • Please don't tag c questions with c++ :) – prehistoricpenguin Jul 05 '21 at 07:43
  • Your integer is too large to store exactly in a typical 32-bit float. – Shawn Jul 05 '21 at 07:45
  • Good example of why you should (most of the time) use `double` rather than `float` :) – Dada Jul 05 '21 at 07:49
  • @Shawn Isnt the range of float 3.4E+38 to +3.4E+38 ? So the value 1625470904 still is in in the range. Right ? – Masoom Kumar Jul 05 '21 at 07:51
  • @Dada I tried to using "double seconds_f" instead of "float seconds_f", and I still have the same problem. The seconds_f does not update as frequently, and has different values. For example -> Hours since January 1, 1970 = 1625471616.000000 Hours since January 1, 1970 = 1625471623 – Masoom Kumar Jul 05 '21 at 07:54
  • 1
    @MasoomKumar this is correct, except that a `float` cannot represent all of the numbers in this range. Keep in mind that floating point numbers are rational numbers, and that there are an infinite amount of rational numbers in that range. Obviously, a `float` cannot represent an infinite amount of numbers, and can thus represent exactly only a fraction of numbers in that range. See for instance [this answer](https://stackoverflow.com/a/12635666/4990392). – Dada Jul 05 '21 at 07:55
  • 1
    @MasoomKumar you need to change both the type declaration (`double seconds_f` instead of `float seconds_f`) and the cast (`(double) seconds` instead of `(float) seconds`). – Dada Jul 05 '21 at 07:56
  • 1
    Many numbers can only be stored approximately. There's lots of good information out there about how IEEE754 floating point numbers work; spend some time learning about them. – Shawn Jul 05 '21 at 07:56
  • 1
    @MasoomKumar you can check out [this IEEE 754 calculator](https://www.h-schmidt.net/FloatConverter/IEEE754.html) to see why you cannot represent your number in a `float` variable. – Simon Doppler Jul 05 '21 at 07:59
  • @SimonDoppler : I will try to read through the IEEE 754 convetion to underastand what is going on. But I checked and our system can only recieved data in float32, so somehow I need to make this work with float data type – Masoom Kumar Jul 05 '21 at 08:06
  • @Dada : Going through the explanation. Thanks for the tip – Masoom Kumar Jul 05 '21 at 08:06
  • Subtract an offset time before converting it to `float`. If you have only 32-bit floating point types, you **cannot** have exact integer values in the 1.6 billions. – the busybee Jul 05 '21 at 09:52
  • Thank you very much for the suggestions. I now have a good understanding of why float doesnt represent all numbers, and found out that our system allows us to use UInt32. So I will time offset from today to get the timer workaround – Masoom Kumar Jul 05 '21 at 11:24

0 Answers0