ros/roscpp_core — pull request #29 by meyerj (2014-08-25 17:48:54+00:00)
Title: Fixed duration initialization from seconds for negative values

Recreated from #28 against indigo-devel:

`DurationBase::fromSec()` always sets `nsec <= 0` for negative arguments while `normalizeSecNSecSigned()` used in the secs and nsecs constructor does the opposite, asserting `nsec >= 0`. This results in wrong comparisons between Duration instances constructed differently.

Example:
```cpp
ros::Duration d1(-0.5); // d1 = -0.5
ros::Duration d2(0, -500000000); // d2 = -0.5
ros::Duration d3(-1, 500000000); // d3 = d2 = -0.5
ros::Duration d4(0, -100000000); // d4 = -0.1

assert(d1.sec == 0 && d1.nsec == -500000000);
assert(d2.sec == -1 && d2.nsec == 500000000);
assert(d3.sec == -1 && d3.nsec == 500000000);
assert(d4.sec == -1 && d4.nsec == 900000000);

std::cout << d1 << std::endl; // prints 0.-500000000
std::cout << d2 << std::endl; // prints -0.500000000
std::cout << d3 << std::endl; // prints -0.500000000
std::cout << d4 << std::endl; // prints -0.100000000

EXPECT_EQ(d1, d2); // This will fail because d1.sec == 0 and d2.sec == -1
EXPECT_LT(d1, d4); // This will fail because d4.sec < d2.sec
```

The solution is quite simple: I had to replace the `trunc()` function call with `floor()`. This also avoids the `HAVE_TRUNC` preprocessor conditionals. Alternatively one could add a `normalizeSecNSecSigned(sec, nsec)` call to the end of the `fromSec()` implementation.

The tests have been updated to also cover negative durations. I only tested this patch with ROS hydro in Ubuntu precise with amd64 architecture, but it also applies to the indigo-devel branch.