Borrar filtros
Borrar filtros

Precision errors when constructing datetime. Some inputs create rounding errors inside datetime. How can I fix these (or at the very least round them)?

1 visualización (últimos 30 días)
I am having difficulty with some precision issues with datetime. Consider the following:
>> t = datetime([13,3,6,0,17,22.7],'Format','dd-MMM-uuuu HH:mm:ss.SSSSSSSSS')
t =
06-Mar-0013 00:17:22.699999999
>> t2 = datetime('06-Mar-0013 00:17:22.7','InputFormat','dd-MMM-uuu HH:mm:ss.S','Format','dd-MMM-uuuu HH:mm:ss.SSSSSSSSS')
t2 =
06-Mar-0013 00:17:22.700000000
>> t == t2
ans =
0
>> datevec(t) == datevec(t2)
ans =
1 1 1 1 1 1
>>seconds(t2-t)
ans =
6.8212e-16
I only need exact precision down to 1e-7 or so but this makes sequencing things very difficult when things like this happen:
>> datetime([0,0,0,0,0,0.7])+seconds(20) == datetime([0,0,0,0,0,20.7])
ans =
0
  5 comentarios
Peter Perkins
Peter Perkins el 11 de Mayo de 2016
Scott, that isn't quite correct. Internally, datetime does use a floating point representation (albeit with more bits than double). Mostly this is not something you need to worry about, and should not rely on the specifics of. However, any time you're working with fractional values in floating point anywhere in MATLAB, you need to be aware of the pitfalls of doing exact comparisons, and datetime is no exception.
In a sense, by the time you've typed 20.7, you're done for, because there is a conversion involved, and the conversion from .7s to some other unit can't possibly be "exact", because .7 itself isn't "exact". In (IIRC) R2015a, datetime added direct support for specifying milliseconds that solves this particular case:
>> a = datetime(0,0,0,0,0,20,700)
a =
30-Nov--0001 00:00:20
>> b = datetime(0,0,0,0,0,0,700) + seconds(20);
>> a == b
ans =
1
datetime, internally, stores dates/times in units of milliseconds. So even with the above, it's possible to construct examples involving sub-ms precision where an equality test on apparently identical datetimes will fail. This is, as Walter says, the usual floating point issue, with the usual solution: don't compare fractional values for exact equality.
Hope this helps.
Walter Roberson
Walter Roberson el 11 de Mayo de 2016
Exactly, you lost out when you specified 22.7, as that had to be converted to double to be passed to datetime, but the .7 part cannot be exactly represented in double precision.

Iniciar sesión para comentar.

Respuestas (0)

Categorías

Más información sobre Logical en Help Center y File Exchange.

Etiquetas

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by