Better way to combine number with fraction?

I have this struct output (from ROS2 message):
MessageType: 'builtin_interfaces/Time'
sec: 1706819594
nanosec: 685974901
I want to combine sec and nanosec in one value like this:
1706819594.685974901
I used the following line of code (and it worked):
zBase.header.stamp.sec+ sprintf(".%d",zBase.header.stamp.nanosec)
Is there a better way ?

 Accepted Answer

Note that you will need to use SPRINTF (or COMPOSE etc) to get the right output when NANOSEC has fewer than the full nine digits:
s = 1706819594;
ns = 685974901;
sprintf("%d.%09d",s,ns)
ans = "1706819594.685974901"
ns = 123;
sprintf("%d.%09d",s,ns)
ans = "1706819594.000000123"
Whereas your format string will given an incorrect output:
s + sprintf(".%d",ns)
ans = "1706819594.123"
If the input number has more than nine digits then the output will be wrong anyway.

5 Comments

I'm not understanding what you would do with this string. Are you only interested in displaying the value? In that case I understand why you want to obtain a string to represent it. But, if you need to do some numerical manipulation, then you will have to at some point turn it into a double. Alternatively could keep the seconds as a double and the nanoseconds as a double and then work with those if you need to maintain the nano second precision.
Hello, so these are messages from a simulator delivered from a ROS2 node, they contain coordinates of the end efffector of a robot. One of the things I need to do is to plot these actual values against the desired value. I also need to check process time of trajectory following.
If the two values are numeric and you want a single numeric output then skip the intermediate text:
format long G
s = 1706819594;
ns = 685974901;
out = s + ns/1e9
out =
1706819594.68597
As mentioned elsewhere in this thread, converting to numeric will irretrievably lose information.
Yes yes I understood this part, thank you. I was just explaining why I need these time stamps in a certain format (fast).

Sign in to comment.

More Answers (1)

If you want to use it as a numerical value I would do this
val = str2double(zBase.header.stamp.sec) + str2double(zBase.header.stamp.nanosec)/1e9

4 Comments

Even if you want to use it as a string later you could always convert the double back to a string using num2str
"Even if you want to use it as a string later you could always convert the double back to a string using num2str"
With the understanding that the interim DOUBLE will have lost information that cannot be retrieved:
fprintf('%.40f\n',1706819594.685974901)
1706819594.6859748363494873046875000000000000000000
Jon
Jon on 1 Feb 2024
Edited: Jon on 1 Feb 2024
Good catch, I hadn't thought about the finite precision limitation, using doubles to represent large values (1e9) to nano second precision.
Thank you so much, this is actually incredibly creative. I will use this method since the numbers are already "double".

Sign in to comment.

Categories

Products

Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!