www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to convert `std.datetime.Duration` to seconds of floating point

reply drug <drug2004 bk.ru> writes:
Now I do it this way (https://run.dlang.io/is/8kVibT):
```
	auto some_duration = dur!"msecs"(500);
	auto seconds = some_duration.total!"hnsecs" / 10_000_000.0;
	assert(seconds.approxEqual(0.5));
```
is there better way to do it?

Thanks in advance
Feb 19
parent reply Dennis <dkorpel gmail.com> writes:
On Tuesday, 19 February 2019 at 14:34:09 UTC, drug wrote:
 Now I do it this way (https://run.dlang.io/is/8kVibT):
 ```
 	auto some_duration = dur!"msecs"(500);
 	auto seconds = some_duration.total!"hnsecs" / 10_000_000.0;
 	assert(seconds.approxEqual(0.5));
 ```
 is there better way to do it?
What you're doing now is the way to do it. This is by design, as Jonathan M. Davis explains: "In general, using floating point values with time is an incredibly bad idea. It can certainly make sense when printing stuff out, but using it in calculations is just asking for trouble given all of the unnecessary imprecision that it adds. So, Duration does not directly support floating point values at all, and that's very much on purpose. (...) And if you're just trying to print out the a duration as a floating point value, because it's nice to view that way, then that's fine, but you'll need to do the conversion yourself. And it's not that hard." https://forum.dlang.org/post/mailman.3711.1453121204.22025.digitalmars-d-learn puremagic.com
Feb 19
parent reply drug <drug2004 bk.ru> writes:
On 19.02.2019 18:07, Dennis wrote:
 On Tuesday, 19 February 2019 at 14:34:09 UTC, drug wrote:
 Now I do it this way (https://run.dlang.io/is/8kVibT):
 ```
     auto some_duration = dur!"msecs"(500);
     auto seconds = some_duration.total!"hnsecs" / 10_000_000.0;
     assert(seconds.approxEqual(0.5));
 ```
 is there better way to do it?
What you're doing now is the way to do it. This is by design, as Jonathan M. Davis explains: "In general, using floating point values with time is an incredibly bad idea. It can certainly make sense when printing stuff out, but using it in calculations is just asking for trouble given all of the unnecessary imprecision that it adds. So, Duration does not directly support floating point values at all, and that's very much on purpose. (...) And if you're just trying to print out the a duration as a floating point value, because it's nice to view that way, then that's fine, but you'll need to do the conversion yourself. And it's not that hard." https://forum.dlang.org/post/mailman.3711.1453121204.22025.digitalmars-d learn puremagic.com
Well, I understand that using floating point values to represent time internally is a bad idea and I totally agree. But some convenient API to convert Duration to floating point and vice versa would be useful because in mechanics for example you often need to express time in seconds with fractional part. In this regard std::chrono is more expressive (the only one though, in general std.datetime is much more powerful than std::chrono).
Feb 19
parent reply Alex <sascha.orlov gmail.com> writes:
On Tuesday, 19 February 2019 at 16:26:33 UTC, drug wrote:
 Well, I understand that using floating point values to 
 represent time internally is a bad idea and I totally agree. 
 But some convenient API to convert Duration to floating point 
 and vice versa would be useful because in mechanics for example 
 you often need to express time in seconds with fractional part. 
 In this regard std::chrono is more expressive (the only one 
 though, in general std.datetime is much more powerful than 
 std::chrono).
If you need a real (double, float) parameter, just use it. Transport the units separately...
Feb 19
parent reply drug <drug2004 bk.ru> writes:
On 19.02.2019 19:35, Alex wrote:
 On Tuesday, 19 February 2019 at 16:26:33 UTC, drug wrote:
 Well, I understand that using floating point values to represent time 
 internally is a bad idea and I totally agree. But some convenient API 
 to convert Duration to floating point and vice versa would be useful 
 because in mechanics for example you often need to express time in 
 seconds with fractional part. In this regard std::chrono is more 
 expressive (the only one though, in general std.datetime is much more 
 powerful than std::chrono).
If you need a real (double, float) parameter, just use it. Transport the units separately...
Could you elaborate what you mean? ``` auto point = vec3(1.0, 2.0, 3.0); vec3 velocity = ...; auto t = dur!"msecs"(500); ... auto new_point = point + velocity * t.total!"msecs"/1e3; ``` How can I use a real parameter and transport units separately here?
Feb 19
parent reply Alex <sascha.orlov gmail.com> writes:
On Tuesday, 19 February 2019 at 16:44:23 UTC, drug wrote:
 On 19.02.2019 19:35, Alex wrote:
 On Tuesday, 19 February 2019 at 16:26:33 UTC, drug wrote:
 Well, I understand that using floating point values to 
 represent time internally is a bad idea and I totally agree. 
 But some convenient API to convert Duration to floating point 
 and vice versa would be useful because in mechanics for 
 example you often need to express time in seconds with 
 fractional part. In this regard std::chrono is more 
 expressive (the only one though, in general std.datetime is 
 much more powerful than std::chrono).
If you need a real (double, float) parameter, just use it. Transport the units separately...
Could you elaborate what you mean? ``` auto point = vec3(1.0, 2.0, 3.0); vec3 velocity = ...; auto t = dur!"msecs"(500); ... auto new_point = point + velocity * t.total!"msecs"/1e3; ``` How can I use a real parameter and transport units separately here?
like ´´´ import std.datetime; void main() { import std.stdio; auto d = Data!"msecs"(); writeln(d.point); writeln(d.t); } struct Data(string units) { real[3] point = [1.0, 2.0, 3.0]; real[3] velocity = ...; auto t = dur!units(500); } ´´´
Feb 19
parent drug <drug2004 bk.ru> writes:
19.02.2019 19:55, Alex пишет:
 On Tuesday, 19 February 2019 at 16:44:23 UTC, drug wrote:
 On 19.02.2019 19:35, Alex wrote:
 On Tuesday, 19 February 2019 at 16:26:33 UTC, drug wrote:
 Well, I understand that using floating point values to represent 
 time internally is a bad idea and I totally agree. But some 
 convenient API to convert Duration to floating point and vice versa 
 would be useful because in mechanics for example you often need to 
 express time in seconds with fractional part. In this regard 
 std::chrono is more expressive (the only one though, in general 
 std.datetime is much more powerful than std::chrono).
If you need a real (double, float) parameter, just use it. Transport the units separately...
Could you elaborate what you mean? ```     auto point = vec3(1.0, 2.0, 3.0);     vec3 velocity = ...;     auto t = dur!"msecs"(500);     ...     auto new_point = point + velocity * t.total!"msecs"/1e3; ``` How can I use a real parameter and transport units separately here?
like ´´´ import std.datetime; void main() {     import std.stdio;     auto d = Data!"msecs"();     writeln(d.point);     writeln(d.t); } struct Data(string units) {     real[3] point = [1.0, 2.0, 3.0];     real[3] velocity = ...;     auto t = dur!units(500); } ´´´
Well, your code is more heavy and less flexible than just using `total!"msecs"/1e3`. Sorry, but it's loosely coupled with my question.
Feb 19