Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
addtodate bug?

Subject: addtodate bug?

From: radar

Date: 12 May, 2010 15:47:45

Message: 1 of 9

I don't see why the output of this code should change as shown below.

clc

dv_cur = [ 2010 5 12 7 30 0];
dt_cur = datenum(dv_cur);

dv_end = [ 2010 5 12 15 15 0];
dt_end = datenum(dv_end);

while (dt_cur < dt_end)
    
    fprintf('current datetime is %s\n', datestr(dt_cur));
    dt_cur = addtodate(dt_cur, 1, 'minute');
      
end;

current datetime is 12-May-2010 07:31:00
current datetime is 12-May-2010 07:32:00
current datetime is 12-May-2010 07:33:00
current datetime is 12-May-2010 07:34:00

to

current datetime is 12-May-2010 10:04:00
current datetime is 12-May-2010 10:04:59
current datetime is 12-May-2010 10:05:59
current datetime is 12-May-2010 10:06:59
current datetime is 12-May-2010 10:07:59
current datetime is 12-May-2010 10:08:59
current datetime is 12-May-2010 10:09:59
current datetime is 12-May-2010 10:10:59

Subject: addtodate bug?

From: Steven Lord

Date: 12 May, 2010 17:15:30

Message: 2 of 9


"radar" <able@tds.net> wrote in message
news:926292603.124109.1273679295245.JavaMail.root@gallium.mathforum.org...
>I don't see why the output of this code should change as shown below.

Since a change of 1 in a serial date number represents the passage of a day,
(1/86400) would represent the passage of a second and (1/1440) would
represent the passage of a minute. However, neither of those numbers can be
exactly represented in double precision, so:


second = (1/86400);
z = 0;
for k = 1:86400
    z = z+second;
end
(z-1) % in exact arithmetic, would be 0
minute = (1/1440);
z2 = 0;
for k = 1:1440
    z2 = z2+minute;
end
(z2-1) % in exact arithmetic, would be 0


Neither z1 nor z2 are exactly 1, are they? This behavior is NOT, repeat NOT
a bug.

See Q6.1 in the newsgroup FAQ and in particular the bottom of the first
column of page 2 of the Cleve's Corner article linked in that question.

--
Steve Lord
slord@mathworks.com
comp.soft-sys.matlab (CSSM) FAQ: http://matlabwiki.mathworks.com/MATLAB_FAQ

Subject: addtodate bug?

From: radar

Date: 12 May, 2010 19:09:00

Message: 3 of 9

Thanks for the detailed response.

Subject: addtodate bug?

From: radar

Date: 13 May, 2010 01:57:20

Message: 4 of 9

since my method of using addtodate will not reliably create 1 minute intervals, how else can I do this?

using colon notation with time doesn't work for obvious reasons.

I need every one minute interval as a datestr or datenum from 7:30 to 3:15.

Subject: addtodate bug?

From: TideMan

Date: 13 May, 2010 05:26:22

Message: 5 of 9

On May 13, 1:57 pm, radar <a...@tds.net> wrote:
> since my method of using addtodate will not reliably create 1 minute intervals, how else can I do this?
>
> using colon notation with time doesn't work for obvious reasons.
>
> I need every one minute interval as a datestr or datenum from 7:30 to 3:15.

Instead of converting to Matlab days, then incrementing, increment
then convert to Matlab days:

Say, you want to generate nt=100 times from yr, mon, day,hr,mn,sec
onwards:
% Generate a matrix of times
tmx=ones(nt,1)*[yr mon day hr mn sec];
% Replace the minutes column
tmx(:,5)=mn + [0:nt-1]'*15;
% Convert to Matlab days
datenum(tmx)

This works because datenum is very smart.
It knows the different number bases of the individual components
(months, days, etc), and if you enter a number that is bigger than the
number basis (e.g., 26 hours), it cleverly converts that to 1 day 2
hours.

And because you do most of the work in integers, the floating point
problem does not arise.

Subject: addtodate bug?

From: radar

Date: 13 May, 2010 12:52:31

Message: 6 of 9

Thank you Derek!

Subject: addtodate bug?

From: Roger Stafford

Date: 18 May, 2011 23:00:05

Message: 7 of 9

"Steven Lord" <slord@mathworks.com> wrote in message <hsenni$h02$1@fred.mathworks.com>...
>
> "radar" <able@tds.net> wrote in message
> news:926292603.124109.1273679295245.JavaMail.root@gallium.mathforum.org...
> >I don't see why the output of this code should change as shown below.
>
> Since a change of 1 in a serial date number represents the passage of a day,
> (1/86400) would represent the passage of a second and (1/1440) would
> represent the passage of a minute. However, neither of those numbers can be
> exactly represented in double precision, so:
>
> second = (1/86400);
> z = 0;
> for k = 1:86400
> z = z+second;
> end
> (z-1) % in exact arithmetic, would be 0
> minute = (1/1440);
> z2 = 0;
> for k = 1:1440
> z2 = z2+minute;
> end
> (z2-1) % in exact arithmetic, would be 0
>
> Neither z1 nor z2 are exactly 1, are they? This behavior is NOT, repeat NOT
> a bug.
>
> See Q6.1 in the newsgroup FAQ and in particular the bottom of the first
> column of page 2 of the Cleve's Corner article linked in that question.
> --
> Steve Lord
> slord@mathworks.com
> comp.soft-sys.matlab (CSSM) FAQ: http://matlabwiki.mathworks.com/MATLAB_FAQ
- - - - - - - - - -
  Hi Steve. I know a year has passed since this thread was first introduced, but I can't resist a mild objection to your response to this query.

  You stated in defense of 'addtodate' that in adding a minute to the serial date number it could not avoid a cumulative error due to the inability of representing 1/1440 as a precise binary floating point number, and of course it is indeed true that such fractions cannot be so represented. However, that doesn't prevent 'addtodate' from making an appropriate correction to each of its outputs so that such an error wouldn't accumulate. It need only correct each tentative serial date number output by multiplying it by 86400000, performing a 'round' to the nearest integer, and then dividing by that same quantity. This would ensure that each output of 'addtodate' was always the nearest possible 'double' fractional value in terms of days to an equivalent integral multiple of milliseconds, which is apparently not the case at present. Such an elementary correction would make 'addtodate'
immune from such cumulative errors almost to the years 300000 AD or BC before encountering the 'realmax' limitation.

  In the words of the famous quip, "it's not a bug - it's a feature", this is admittedly a "feature", but it is a feature that in my opinion Mathworks should seriously consider improving.

  I should add that what brought this to my attention was yesterday's unanswered thread "addtodate irreversible behavior" by Le Fou Volant at:

 http://www.mathworks.nl/matlabcentral/newsreader/view_thread/307921

This problem may involve some kind of round-off errors (though I haven't figured out what they might be) and deserves an answer from someone at Mathworks.

Roger Stafford

Subject: addtodate bug?

From: Roger Stafford

Date: 19 May, 2011 07:26:03

Message: 8 of 9

"Roger Stafford" wrote in message <ir1j1l$ese$1@newscl01ah.mathworks.com>...
> ........
> immune from such cumulative errors almost to the years 300000 AD or BC before encountering the 'realmax' limitation.
> ........
- - - - - - - - - -
  I didn't say what I meant when I wrote "before encountering the 'realmax' limitation". It has nothing to do with 'realmax'. I should have said: before encountering the 53-bit limitation - that is, where the number of milliseconds would exceed 2^53.

Roger Stafford

Subject: addtodate bug?

From: Steven_Lord

Date: 19 May, 2011 14:14:10

Message: 9 of 9



"Roger Stafford" <ellieandrogerxyzzy@mindspring.com.invalid> wrote in
message news:ir1j1l$ese$1@newscl01ah.mathworks.com...
> "Steven Lord" <slord@mathworks.com> wrote in message
> <hsenni$h02$1@fred.mathworks.com>...
>>
>> "radar" <able@tds.net> wrote in message
>> news:926292603.124109.1273679295245.JavaMail.root@gallium.mathforum.org...
>> >I don't see why the output of this code should change as shown below.
>>
>> Since a change of 1 in a serial date number represents the passage of a
>> day, (1/86400) would represent the passage of a second and (1/1440) would
>> represent the passage of a minute. However, neither of those numbers can
>> be exactly represented in double precision, so:
>>
>> second = (1/86400);
>> z = 0;
>> for k = 1:86400
>> z = z+second;
>> end
>> (z-1) % in exact arithmetic, would be 0
>> minute = (1/1440);
>> z2 = 0;
>> for k = 1:1440
>> z2 = z2+minute;
>> end
>> (z2-1) % in exact arithmetic, would be 0
>>
>> Neither z1 nor z2 are exactly 1, are they? This behavior is NOT, repeat
>> NOT a bug.
>>
>> See Q6.1 in the newsgroup FAQ and in particular the bottom of the first
>> column of page 2 of the Cleve's Corner article linked in that question.
>> --
>> Steve Lord
>> slord@mathworks.com
>> comp.soft-sys.matlab (CSSM) FAQ:
>> http://matlabwiki.mathworks.com/MATLAB_FAQ
> - - - - - - - - - -
> Hi Steve. I know a year has passed since this thread was first
> introduced, but I can't resist a mild objection to your response to this
> query.
>
> You stated in defense of 'addtodate' that in adding a minute to the
> serial date number it could not avoid a cumulative error due to the
> inability of representing 1/1440 as a precise binary floating point
> number, and of course it is indeed true that such fractions cannot be so
> represented. However, that doesn't prevent 'addtodate' from making an
> appropriate correction to each of its outputs so that such an error
> wouldn't accumulate. It need only correct each tentative serial date
> number output by multiplying it by 86400000, performing a 'round' to the
> nearest integer, and then dividing by that same quantity. This would
> ensure that each output of 'addtodate' was always the nearest possible
> 'double' fractional value in terms of days to an equivalent integral
> multiple of milliseconds, which is apparently not the case at present.
> Such an elementary correction would make 'addtodate' immune from such
> cumulative errors almost to the years 300000 AD or BC before encountering
> the 'realmax' limitation.

That's a possibility; I can pass that suggestion on to the developers
responsible for ADDTODATE.

If I wanted to determine the time multiple minutes from a specified time, I
would call ADDTODATE _once_ adding the whole span rather than calling it
multiple times with intervals of one minute each.

t = now;
t1 = addtodate(t, 10, 'minute');
t2 = t;
for k = 1:10
    t2 = addtodate(t2, 1, 'minute');
end

If I needed an array of values representing times spaced at one minute
intervals, I'd probably use DATEVEC and DATENUM.

t = now;
V = datevec(t);
M = repmat(V, 11, 1);
M(:, 5) = M(:, 5)+(0:10).';
t1 = datenum(M)

> In the words of the famous quip, "it's not a bug - it's a feature", this
> is admittedly a "feature", but it is a feature that in my opinion
> Mathworks should seriously consider improving.
>
> I should add that what brought this to my attention was yesterday's
> unanswered thread "addtodate irreversible behavior" by Le Fou Volant at:
>
> http://www.mathworks.nl/matlabcentral/newsreader/view_thread/307921
>
> This problem may involve some kind of round-off errors (though I haven't
> figured out what they might be) and deserves an answer from someone at
> Mathworks.

I've forwarded that thread to the developers responsible for ADDTODATE as
well. I don't know when or if they will respond in that thread. I posted a
message to that effect in that thread.

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Tags for this Thread

No tags are associated with this thread.

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us