Boost logo

Boost :

Subject: Re: [boost] [chrono] boost::chrono::floor() and negative durations
From: Krzysztof Czainski (1czajnik_at_[hidden])
Date: 2013-11-21 17:06:38


2013/11/21 Howard Hinnant <howard.hinnant_at_[hidden]>

> On Nov 20, 2013, at 12:49 PM, Vicente J. Botet Escriba <
> vicente.botet_at_[hidden]> wrote:
>
> > Le 20/11/13 13:45, Krzysztof Czainski a écrit :
> >> Hello,
> >>
> >> The function boost::chrono::floor() is documented: "This function round
> >> down the given parameter." Therefore I expect the assert in the
> following
> >> program to pass, but it fails:
> >>
> >> #include <boost/chrono/floor.hpp>
> >> #include <cassert>
> >>
> >> int main()
> >> {
> >> boost::chrono::nanoseconds const nsec( -1 );
> >> boost::chrono::seconds const sec =
> >> boost::chrono::floor<boost::chrono::seconds>(nsec);
> >> assert( sec.count() == -1 );
> >> }
> >>
> >> Is this intended behavior? If yes, could the docs be updated to clarify
> >> this?
> >>
> >>
> > Hi,
> >
> > no, there is a bug with negative numbers.
> >
> > template <class To, class Rep, class Period>
> > To floor(const duration<Rep, Period>& d)
> > {
> > + if (d<duration<Rep, Period>::zero())
> > + return duration_cast<To>(d)-To(1);
> > + else
> > return duration_cast<To>(d);
> > }
> >
> > Please, coul dyou create a ticket so that I don't forget it.
> >
> > Thanks,
> > Vicente
> >
> > _______________________________________________
> > Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
> #include <chrono>
>
> using namespace std::chrono;
>
> template <class To, class Rep, class Period>
> To floor(const duration<Rep, Period>& d)
> {
> if (d<duration<Rep, Period>::zero())
> return duration_cast<To>(d)-To(1);
> else
> return duration_cast<To>(d);
> }
>
> #include <iostream>
>
> int
> main()
> {
> using namespace std::literals;
> std::cout << floor<seconds>(-1000ms).count() << '\n';
> }
>
> For me outputs:
>
> -2
>
> How about this instead:
>
> template <class To, class Rep, class Period>
> To
> floor(const std::chrono::duration<Rep, Period>& d)
> {
> To t = std::chrono::duration_cast<To>(d);
> if (t > d)
> --t;
> return t;
> }
>
> Howard

Ticket #9419 created.

I think it's a bit more complicated. Doesn't Howard's version return -2 as
well?

I'll try to take a closer look how chrono implements floor, ceil and round
and suggest something here. But I'm thinking of something like this
implementation of integral division [1].

Cheers,
Kris

[1] http://goo.gl/F8by6T


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk