Closed bapcyk closed 2 years ago
Pico
does not mean picoseconds. It is a fixed-point type with a resolution of 10^-12.
nominalDiffTimeToSeconds
converts a NominalDiffTime
to seconds (not picoseconds), just as its name says, which is why it gives 5 for five seconds.
Pico does not mean picoseconds. It is a fixed-point type with a resolution of 10^-12.
nominalDiffTimeToSeconds
converts aNominalDiffTime
to seconds (not picoseconds), just as its name says, which is why it gives 5 for five seconds.
OK, I just checked < 1 seconds intervals and I really get 0 seconds :)
But to be honest I still don't understand the idea of such a signature. Let's say we have a clock, maybe atomic clock, IDK, some atomic timer. And I use it to measure time interval between 2 events: t1 and t0. And I see on its frontal panel an indicator - "5 PICO". I read it as "the delta t is 5 picoseconds". If it shows me "5 SEC", it means 5 seconds. I see in the signature of the nominalDiffTimeToSeconds
exactly this "PICO".
I never see on the frontal panel of the timer something like "5 FEMTO" because my timer has a femtasecond resolution (its resolution is a technical/implementation detail and I don't expect to see it in the semisegments indicators), otherwise how to understand what it measured?
I mean, then why does nominalDiffTimeToSeconds
returns Pico
and not Uni
? You said "the resolution", but I tried to measure delta time of 50 microseconds and sure the function returns me 0 seconds, OK. It means that it's resolution is literally 1 second, no any picos in the picture.
Anyway, from my point of view, such signature looks very deceptive.
On the frontal panel you should see the indicator nominalDiffTimeToSeconds
. That's exactly what it does.
Pico
does not mean picoseconds. It means pico resolution.
The actual resolution depends on your clock. This is what I get:
Prelude Data.Time> t0 <- getCurrentTime
Prelude Data.Time> t1 <- getCurrentTime
Prelude Data.Time> let d = diffUTCTime t1 t0
Prelude Data.Time> nominalDiffTimeToSeconds d
7.231037469000
Notice the 000
at the end? That's because the Pico
type has pico resolution, but my clock apparently has nanosecond resolution.
That's because the Pico type has pico resolution, but my clock apparently has nanosecond resolution.
OK, then:
Pico
- because we have some abstract clock with Pico
resolutiongetSysClockResolution :: Integer
or similar and I don't want to have this Pico
in a function returning time delta treated as a seconds-based intervals (Haddock: Conversion functions such as fromInteger and realToFrac will treat it as seconds.
)Well, what is the problem to have Uni
as a return type?
Sorry, I completely cannot catch the idea. Maybe the idea is to know the denominator of the ratio? I use Fixed as time units, is it wrong? If yes, then why?
NominalDiffTime
has a resolution of picoseconds. So nominalDiffTimeToSeconds
converts it to a type that has a resolution of 10^-12.
Pico
is defined as type Pico = Fixed E12
. It's a fixed-precision type, that wraps around an Integer
.
If you want the actual resolution of your clock, it's getTime_resolution :: DiffTime
.
Then I cannot understand the next:
let x = 5 :: Pico
what does it mean? I was sure it's something * 10⁻¹²
. And if it's about time intervals, then it's 5 picoseconds. If it's about grams, then it's 5 picogram. But you tell me that 5 :: Pico
can be 5 seconds, 5 milliseconds, 5 picoseconds and everything else, but - with a resolution of 1 picosecond. It's a first strange logic to me.
The second one is why would somebody want to know the resolution of the time interval if it losts it being converted to integral - round
returns me just 5 without picoseconds accurancy ("resolution")?
I think about Pico
in the signature as about measure unit. But you told me that it's not the unit but the resolution! It's very weird. Even more, the resolution of what - getTime_resolution
is 1 nanosecond.
Maybe I cannot get the logic. I used to think that if I have a function like personAge :: Person -> Year
then it returns the age in years, and I would not interesting about any resolutions of the timer measured the age of the person.
As I understand "the resolution" literally means the denominator of the ratio. When I got 5 as a result and the denominator is 10¹² then it's the ratio:
5
------------------
1000000000000
and how it can be 5 seconds? If the nominalDiffTimeToSeconds
returns seconds (as its name says it) but with picosecond's resolution, OK, then it has to return something which leads to 5000000000000 after the round
(with possible noise). Where is the mistake?
let x = 5 :: Pico
means x
is five.
Read it like this:
let
x :: Pico
x = 5
The line x=5
mean x
is five. Not 5*10^-12. Not five picoseconds. Not even five seconds. Just the number five. Nothing else. Just, exactly, the plain ordinary number five. That's all it is. That's why it says x=5
, as in, x
is equal to five.
Now the type of x
is Pico
, which is the same as Fixed E12
. That's a fixed-point type that happens to have resolution of 10^-12. So for example, if you do this:
let
y :: Pico
y = 0.000000000003
z :: Pico
z = 0.0000000000003
Then y
will be greater than zero, but z
will be equal to zero, because that number is smaller than Pico
resolution.
hm... It's interesting. OK, then the last question, if I use Pico
, Milli
and similar as units (for time and so on) - could it be a problem (completely irrelevant to nominalDiffTimeToSeconds
) - directly or like:
newtype Sec = Sec Uni deriving newtype (...)
?
They always have values > 1, so I cannot lost the valuable digits like in your example (eg, 0.0005::Milli
) and I prefered them instead of a special libs for units/time-units and still had not any problems, is it OK?
Uni
is essentially just the same as Integer
. If you used it to represent seconds, it can only be a whole number of seconds.
I am trying to do:
I have a function for a conversion from any Fixed to another one. And I supposed that if I have picoseconds (5 in the case), it means 5 x 10⁻¹² seconds:
nominalDiffTimeToSeconds
really returns the value as picoseconds:nominalDiffTimeToSeconds :: NominalDiffTime -> Pico
. This is how I (and I believe many others persons) do understand the function returning picoseconds according to its signature.Sure, my conversion function returns 0, because 5 seconds ≠ 5 picoseconds, obviously.
After some digging I found:
Conversion functions such as fromInteger and realToFrac will treat it as seconds.
round
called on thedelta
returns 5, it seems it's really 5 there!So, my questions are:
round delta
return 5 and not 5000000000000 ?our function returns picoseconds - you can see it in its signature
, but at the same time...will treat as seconds (instead of picoseconds in signature)
?Pico
) and something likemySuperConvertor @Pico @Uni (delta * 100000000000)
looks like weird hack - everyone reading it may get it as a bug?I have feeling that it's some weird behavior/design of time's functions, but maybe I'm missing something. Maybe documentation of the module is not clean enough, please, show what is the logically right and consistent method to work with the Pico result from the
nominalDiffTimeToSeconds
function and how to understand the case. Thanks! :)