Opened 13 years ago
Closed 10 years ago
#3471 closed Patches (fixed)
microseconds constructor overflows
Reported by: | Andrey Semashev | Owned by: | Andrey Semashev |
---|---|---|---|
Milestone: | Boost 1.43.0 | Component: | date_time |
Version: | Boost 1.40.0 | Severity: | Problem |
Keywords: | microseconds | Cc: |
Description
From the users ML: http://lists.boost.org/boost-users/2008/10/41763.php
The boost::date_time::microseconds(...) constructor overflows the int64 size limits in intermediary calculations. The code below will reproduce the error (using VC++ 2008 and boost 1.36).
ptime start(boost::gregorian::date(2000, 1, 1)); ptime end(boost::gregorian::date(2000, 5, 1)); time_duration td = end - start; ptime wrongEnd = start + microseconds(td.total_microseconds()); BOOST_CHECK_EQUAL(end, wrongEnd);
The microseconds constructor takes an int64 as input and the total_microseconds is well within its range. Inside the date_time::subsecond_duration<time_duration, 1000000> the internal duration is calculated as
ss*traits_type::res_adjust()/frac_of_second
Since the both res_adjust() and frac_of_second have the value 1000000, the result should be ss*1 but... the intermediary value ss*res_adjust overflows the int64 causing a negative number to be returned.
Question is, is this by design or is it a bug? I'm rather new to boost::date_time and was hoping to replace our current datetime types with it. We are using millisecond timestamped data over long time series (years).
I guess the simple solution would be to add parentheses around (res_adjust()/frac_of_second) assuming frac_of_second always divides res_adjust. However, there are similar issues when adding 200 years worth of seconds which overflows the int32 argument (but that's not of my immediate concern).
Attachments (1)
Change History (12)
comment:1 by , 13 years ago
comment:2 by , 12 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:3 by , 12 years ago
Milestone: | Boost 1.41.0 → Boost 1.43.0 |
---|
comment:4 by , 12 years ago
Owner: | changed from | to
---|---|
Status: | assigned → new |
comment:5 by , 12 years ago
Owner: | changed from | to
---|
by , 12 years ago
Attachment: | subsecond_duration-overflow-fix.diff added |
---|
comment:6 by , 12 years ago
Any estimate when this will make it into a release? Milestone is still set for 1.43.
comment:7 by , 12 years ago
Or something like "(ss / frac_of_second) * traits_type::res_adjust() + (ss % frac_of_second) * traits_type::res_adjust() / frac_of_second" ?
comment:8 by , 12 years ago
Type: | Bugs → Patches |
---|
comment:9 by , 10 years ago
So, this is a real problem. Will this ever make it into a release? It's as simple as a set of parenthesis. If not, can we have some rational in the bug?
comment:10 by , 10 years ago
comment:11 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
In my opinion, this is definitely a bug. I'd take it one step further: the presence of this simple integer-overflow bug suggests that there may be integer arithmetic bugs throughout the date_time library. An expert in integer arithmetic should review the entire date_time library looking for similar bugs.
Note that the suggested solution of adding parentheses won't work in many common cases, such as when this function is called from the nanoseconds constructor.