Reputation: 58444
I'm hitting something here which is very odd but I'm not sure whether it's me knowing the TimeSpan APIs wrong. The following prints out false
and I'm not sure why:
var foo = TimeSpan.FromMilliseconds(123.34d);
var bar = TimeSpan.FromMilliseconds(123.33d);
Console.WriteLine(foo > bar);
The following prints true
:
var foo = TimeSpan.FromMilliseconds(123.34d);
var bar = TimeSpan.FromMilliseconds(123.33d);
Console.WriteLine(foo == bar);
Doesn't TimeSpan.FromMilliseconds
take millisecond precision into account while doing the comparison?
Upvotes: 4
Views: 2903
Reputation: 726489
TimeSpan
simply rounds the number of milliseconds that you pass it, so both 123.33
and 123.34
end up representing a timespan of 123 milliseconds. 123.5
would be rounded up to 123 milliseconds.
If you need better precision, do the math with the ticks yourself:
var foo = TimeSpan.FromTicks((long)(123.34*TimeSpan.TicksPerMillisecond));
var bar = TimeSpan.FromTicks((long)(123.33*TimeSpan.TicksPerMillisecond));
Console.WriteLine(foo > bar);
Now your program produces True
(demo).
Upvotes: 5
Reputation: 193
Its an issue with precision:
var fooba = TimeSpan.FromMilliseconds(123.36d);
var foob = TimeSpan.FromMilliseconds(123.35d);
var foo = TimeSpan.FromMilliseconds(123.34d);
var bar = TimeSpan.FromMilliseconds(123.33d);
Console.WriteLine(fooba + " > " + foob + "?: " + (fooba > foob));
Console.WriteLine(foob + " > " + foo + "?: " + (foob > foo));
Console.WriteLine(foo + " > " + bar + "?: " + (foo > bar));
Console.WriteLine(fooba + " == " + foob + "?: " + (fooba == foob));
Console.WriteLine(foob + " == " + foo + "?: " + (foob == foo));
Console.WriteLine(foo + " == " + bar + "?: " + (foo == bar));
00:00:00.1230000 > 00:00:00.1230000?: False
00:00:00.1230000 > 00:00:00.1230000?: False
00:00:00.1230000 > 00:00:00.1230000?: False
00:00:00.1230000 == 00:00:00.1230000?: True
00:00:00.1230000 == 00:00:00.1230000?: True
00:00:00.1230000 == 00:00:00.1230000?: True
Upvotes: 0
Reputation: 5886
According to the API documentation http://msdn.microsoft.com/en-us/library/system.timespan.frommilliseconds(v=vs.110).aspx the method TimeSpan.FromMilliSeconds(double d)
takes any double value but only respects values up to one digit after the comma since the double is converted into ticks before it is used within the TimeSpan struct.
The value parameter is converted to ticks, and that number of ticks is used to initialize the new TimeSpan. Therefore, value will only be considered accurate to the nearest millisecond. Note that, because of the loss of precision of the Double data type, this conversion can generate an OverflowException for values that are near to but still in the range of either MinValue or MaxValue.
This is also emphasized by the examples on that site:
GenTimeSpanFromMillisec( 1 );
GenTimeSpanFromMillisec( 1.5 );
GenTimeSpanFromMillisec( 12345.6 );
GenTimeSpanFromMillisec( 123456789.8 );
GenTimeSpanFromMillisec( 1234567898765.4 );
GenTimeSpanFromMillisec( 1000 );
GenTimeSpanFromMillisec( 60000 );
GenTimeSpanFromMillisec( 3600000 );
GenTimeSpanFromMillisec( 86400000 );
GenTimeSpanFromMillisec( 1801220200 );
Upvotes: 1
Reputation: 2786
Timespan accepts a floating point as a parameter for milliseconds but ignores the decimals.
Makes sense, as timespan has no notion of sub-milliseconds; it's the smallest unit.
Upvotes: 1