为什么TimeSpan.FromSeconds(double)四舍五入到几毫秒?

TimeSpan.FromSeconds需要一个双精度值,并且可以将值减小到100纳秒,但是这种方法令人难以置信地将时间缩短到整个毫秒。

鉴于我刚刚花了半个小时来查明这种(记录的)行为,知道为什么会出现这种情况,可以更容易地忍受浪费的时间。

任何人都可以提出为什么这种看似适得其反的行为得以实施吗?

TimeSpan.FromSeconds(0.12345678).TotalSeconds
    // 0.123
TimeSpan.FromTicks((long)(TimeSpan.TicksPerSecond * 0.12345678)).TotalSeconds
    // 0.1234567

正如你发现你自己,这是一个记录的功能。 它在TimeSpan的文档中有描述:

参数

值类型:System.Double

几秒钟, 精确到最接近的毫秒

造成这种情况的原因可能是因为双打并不那么准确。 在比较双打时做一些四舍五入总是一个好主意,因为它可能只比你想象的大一点或者小一点。 当您尝试放入整个毫秒时,该行为实际上可能会为您提供一些意想不到的纳秒。 我认为这就是他们选择将整个值舍入到整个毫秒并丢弃较小数字的原因。


关于炒作的权利..

  • TimeSpan.MaxValue.TotalMilliseconds等于922337203685477.具有15位数的数字。
  • double精确到15位数字。
  • TimeSpan.FromSecondsTimeSpan.FromMinutes等所有经过转换以表示毫秒double (当时蜱然后到TimeSpan是不感兴趣了)
  • 因此,当您创建TimeSpan接近TimeSpan.MaxValue (或MinValue )时,转换精确到毫秒。
    所以对“为什么”这个问题的可能答案是:始终具有相同的精度
    还有一件事要考虑的是,如果通过首先将价值转换为long表示的价值来完成转换,那么这项工作是否可以做得更好。


    想象一下,您是负责设计TimeSpan类型的开发人员。 你已经掌握了所有的基本功能, 这一切似乎都很好。 然后有一天,一些beta测试人员会出现并向您显示此代码:

    double x = 100000000000000;
    double y = 0.5;
    TimeSpan t1 = TimeSpan.FromMilliseconds(x + y);
    TimeSpan t2 = TimeSpan.FromMilliseconds(x) + TimeSpan.FromMilliseconds(y);
    Console.WriteLine(t1 == t2);
    

    为什么这个输出是False ? 测试人员会问你。 即使你明白为什么会发生这种情况(将xy加在一起会导致精度的下降),但你必须承认,从客户的角度来看,这似乎有点奇怪。 然后他把这一个扔给你:

    x = 10.0;
    y = 0.5;
    t1 = TimeSpan.FromMilliseconds(x + y);
    t2 = TimeSpan.FromMilliseconds(x) + TimeSpan.FromMilliseconds(y);
    Console.WriteLine(t1 == t2);
    

    那个输出True ! 测试者可以理解地持怀疑态度。

    此时你有一个决定。 要么你可以允许在由double值构造的TimeSpan值之间进行算术运算,以产生精度超过double精度类型自身精度的结果 - 例如100000000000000.5(16位有效数字) - 或者,您可以,您知道,不允许那。

    所以你决定,你知道什么,我会这样做,以便任何使用double构造TimeSpan都会四舍五入到最接近的毫秒。 这样,明确地证明,从double转换为TimeSpan是一种有损耗的操作,在客户从double转换为TimeSpan并希望得到准确结果之后发现这样的奇怪行为的情况下可以免除我。

    我不一定认为这是“正确的”决定。 显然,这种方法本身会造成一些混乱。 我只是说需要做出某种决定,而这是显然决定的。

    链接地址: http://www.djcxy.com/p/52809.html

    上一篇: Why does TimeSpan.FromSeconds(double) round to milliseconds?

    下一篇: How frequent is DateTime.Now updated ? or is there a more precise API to get the current time?