TimeSpan与毫秒精度的比较

本文关键字:比较 精度 TimeSpan | 更新日期: 2023-09-27 18:28:01

我在这里遇到了一些非常奇怪的事情,但我不确定是否是我知道TimeSpan API错了。以下打印出false,我不确定原因:

var foo = TimeSpan.FromMilliseconds(123.34d);
var bar = TimeSpan.FromMilliseconds(123.33d);
Console.WriteLine(foo > bar);

以下打印true:

var foo = TimeSpan.FromMilliseconds(123.34d);
var bar = TimeSpan.FromMilliseconds(123.33d);
Console.WriteLine(foo == bar);

TimeSpan.FromMilliseconds在进行比较时不考虑毫秒精度吗?

TimeSpan与毫秒精度的比较

TimeSpan只需四舍五入通过它的毫秒数,因此123.33123.34最终都表示123毫秒的时间跨度。CCD_ 7将被四舍五入到123毫秒。

如果你需要更好的精度,可以自己用记号计算:

var foo = TimeSpan.FromTicks((long)(123.34*TimeSpan.TicksPerMillisecond));
var bar = TimeSpan.FromTicks((long)(123.33*TimeSpan.TicksPerMillisecond));
Console.WriteLine(foo > bar);

现在您的程序生成True(演示)。

根据API文档http://msdn.microsoft.com/en-us/library/system.timespan.frommilliseconds(v=vs.110).aspx方法TimeSpan.FromMilliSeconds(double d)接受任何双精度值,但只考虑逗号后一位以内的值,因为双精度在TimeSpan结构中使用之前会转换为刻度。。

值参数将转换为刻度,该刻度数用于初始化新的TimeSpan。因此,该值只能精确到毫秒。请注意,由于Double数据类型的精度损失,此转换可能会为接近但仍在MinValue或MaxValue范围内的值生成OverflowException。

该网站上的例子也强调了这一点:

GenTimeSpanFrom毫秒(1)
GenTimeSpanFrom毫秒(1.5)
GenTimeSpanFrom毫秒(12345.6)
GenTimeSpanFrom毫秒(123456789.8)
GenTimeSpanFrom毫秒(1234567898765.4)
GenTimeSpanFrom毫秒(1000)
GenTimeSpanFrom毫秒(60000)
GenTimeSpanFrom毫秒(3600000)
GenTimeSpanFrom毫秒(86400000)
GenTimeSpanFromMillisec(1801220200)

Timespan接受浮点作为毫秒参数,但忽略小数。

有道理,因为时间跨度没有亚毫秒的概念;它是最小的单位。

这是一个精度问题:

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