【问题标题】:Rounding problems when creating date vectors创建日期向量时的舍入问题
【发布时间】:2015-03-04 11:56:15
【问题描述】:

我想在 matlab 中创建一个包含日期的向量。为此我指定了开始时间和停止时间:

WHM01_start = datenum('01-JAN-2005 00:00')
WHM01_stop = datenum('01-SEP-2014 00:00')

然后我用

创建了向量
WHM01_timevec = WHM01_start:datenum('01-JAN-2014 00:20') - datenum('01-JAN-2014 00:00'):WHM01_stop;

在我希望每个时间步长为 20 分钟之后。不幸的是,在数千个值之后我得到一个舍入错误,导致我

>> datestr(WHM01_timevec(254160))

ans =

31-Aug-2014 23:39:59

并不像预期的那样,31-Aug-2014 23:40:00
如何更正这些不正确的值?

编辑:我也看到了这个thread,但不幸的是我得到了每个日期的向量,而不是所需的数字。

【问题讨论】:

    标签: arrays matlab date floating-accuracy


    【解决方案1】:

    你可以给函数datenum提供数字格式的年、月、日……。 Datenum 接受一个或多个参数的向量,如果数字太大(例如,120 分钟),datenum 知道如何处理它。

    因此,通过以 20 分钟为增量提供分钟向量,您可以避免舍入错误(至少在 1 秒级别上):

    WHM01_start = datenum('01-JAN-2005 00:00');
    WHM01_stop = datenum('01-SEP-2014 00:00');
    
    time_diff = WHM01_stop - WHM01_start;
    
    WHM01_timevec = test = datenum(2005,01,01,00,[00:20:time_diff*24*60],00);
    
    datestr(WHM01_timevec(254160))
    

    回答您的评论:

    您看到舍入错误的原因是您使用了两个大数字的差值作为时间增量。大数的差值具有(相对)较大的舍入误差。

    Matlab 时间以自(虚构)日期 0.0.0000 起的天数计算。您的时间增量是 1/3 小时,或 1/(24*3) 天。修改您的原始代码,使其读取

    WHM01_timevec = WHM01_start:1/(24*3):WHM01_stop;
    

    是一种减少舍入误差的替代方法,但对于非常大的时间跨度,第一个解决方案是一种更稳健的方法。

    【讨论】:

      【解决方案2】:

      Related answer: 使用linspace 而不是colon operator :

      %// given
      WHM01_start = datenum('01-JAN-2005 00:00')
      WHM01_stop = datenum('01-SEP-2014 00:00')
      
      %// number of elements
      n = numel(WHM01_start: datenum('01-JAN-2014 00:20') - ...
                             datenum('01-JAN-2014 00:00') : WHM01_stop);
      
      %// creating vector using linspace
      WHM01_timevec = linspace(WHM01_start, WHM01_stop, n);
      
      %// proof
      datestr(WHM01_timevec(254160))
      

      ans =
      
      31-Aug-2014 23:40:00
      

      此解决方案的缺点:要确定输出向量的元素数,我使用使用: 创建的原始向量,这可能不是最佳选择。


      来自链接答案的重要引述:

      使用 linspace 可以降低这些问题发生的概率,这不是安全措施。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-01-08
        • 2021-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多