Nothing special at all. In this case I just wanted to be able to get a UNIX time with a fractional part and convert it into a NaiveDateTime to the microseconds:
time = 1485425805.49934
fraction = 0.49934
time
|> trunc()
|> DateTime.from_unix!()
|> NaiveDateTime.to_erl()
|> NaiveDateTime.from_erl!(trunc(fraction * 1_000_000))
~N[2017-01-26 10:16:45.499340]
I was just looking for a way to have {unix_seconds, fraction} = magic_function(fractional_unix_seconds), that’s all.
Where’s your unix time with fractional part coming from? The unix APIs return structs with secs & microsecs to begin with. Postgres stores as microsecs. Etc. You might just need to get your initial time from a different API, if possible. Of course if it’s being handed to you by an external library, then your first idea is probably still best.
Legacy WordPress database. People put all kinds of stuff in there, you wouldn’t believe the things I’ve found in production dumps while I was troubleshooting (years ago). Including PHP-serialized objects (which is a TLV string-encoded format).
oh yeah. That’s actually numerically correct behavior. Strictly cosmetically bad for most purposes. No claims are made about if fluid dynamics simulations will or won’t be messed up by this.
For anyone else tuning in who is confused by this:
time = 1485425805.49934
time - trunc(time)
0.4993400573730469
it’s because 148542580549934/100000 has trimmed precision that isn’t the same as when you do 49934/100000 because there’s more precision with IEEE floating point around [0,1]
True. I simply wanted to chase this to some as-much-satisfactory-as-possible conclusion.
(I mean, in terms of trying to write as correct as possible code. But yeah, binary floating-point will never be viewed as correct by us the humans who are used to the decimal system. Hence we never use binary floats for financial operations.)