{"action":"closed","issue":{"url":"https://api.github.com/repos/ros/roscpp_core/issues/48","repository_url":"https://api.github.com/repos/ros/roscpp_core","labels_url":"https://api.github.com/repos/ros/roscpp_core/issues/48/labels{/name}","comments_url":"https://api.github.com/repos/ros/roscpp_core/issues/48/comments","events_url":"https://api.github.com/repos/ros/roscpp_core/issues/48/events","html_url":"https://github.com/ros/roscpp_core/issues/48","id":161246425,"number":48,"title":"ros/time.h fromSec implementation suffers from floating point inaccuracy, and stores invalid data","user":{"login":"televator","id":1095088,"avatar_url":"https://avatars.githubusercontent.com/u/1095088?v=3","gravatar_id":"","url":"https://api.github.com/users/televator","html_url":"https://github.com/televator","followers_url":"https://api.github.com/users/televator/followers","following_url":"https://api.github.com/users/televator/following{/other_user}","gists_url":"https://api.github.com/users/televator/gists{/gist_id}","starred_url":"https://api.github.com/users/televator/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/televator/subscriptions","organizations_url":"https://api.github.com/users/televator/orgs","repos_url":"https://api.github.com/users/televator/repos","events_url":"https://api.github.com/users/televator/events{/privacy}","received_events_url":"https://api.github.com/users/televator/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/ros/roscpp_core/labels/bug","name":"bug","color":"e10c02"}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-06-20T17:11:46Z","updated_at":"2016-06-27T17:37:16Z","closed_at":"2016-06-27T17:37:16Z","body":"In some corner cases, floating point inaccuracy can lead to invalid data where nsec is calculated to be outside [0;1e9-1].\r\nTo illustrate the problem think of the following \r\n```\r\n#include <cmath>\r\n#include <boost/math/special_functions/round.hpp>\r\nint main()\r\n{\r\n        double someint = 1031.0; // some integer\r\n        double t = std::nextafter(someint, 0); // someint - epsilon\r\n        std::cout << next << std::endl;    // prints 1031.000000\r\n        // ros implementation of fromSec\r\n        uint32_t sec = (uint32_t)floor(t);\r\n        uint32_t nsec = (uint32_t)boost::math::round((t-sec) * 1e9);\r\n        std::cout << \"sec\"  << sec  << std::endl;   // prints 1030 (!)\r\n        std::cout << \"nsec\"<< nsec << std::endl;  // prints 1000000000 (!)\r\n}\r\n```\r\n(compile with c++11)\r\nCorrect behavior would be sec: 1031 nsec: 0, of course.\r\n\r\nI guess the rounding behavior is desired in general, so a remaining fix would be to catch this specific case. Alternatively, the order could be changed to multiply with 1e9 -> round -> split into secs/nsec.\r\nThe latter solution requires an appropriately long integer data type for the temporary."}}
{"actor":{"display_login":"dirk-thomas"}}