{"action":"opened","issue":{"url":"https://api.github.com/repos/facebook/folly/issues/491","repository_url":"https://api.github.com/repos/facebook/folly","labels_url":"https://api.github.com/repos/facebook/folly/issues/491/labels{/name}","comments_url":"https://api.github.com/repos/facebook/folly/issues/491/comments","events_url":"https://api.github.com/repos/facebook/folly/issues/491/events","html_url":"https://github.com/facebook/folly/issues/491","id":181477879,"number":491,"title":"folly::to<int_32t>(double) throws loss of precision exceptions","user":{"login":"marksweiss","id":58776,"avatar_url":"https://avatars.githubusercontent.com/u/58776?v=3","gravatar_id":"","url":"https://api.github.com/users/marksweiss","html_url":"https://github.com/marksweiss","followers_url":"https://api.github.com/users/marksweiss/followers","following_url":"https://api.github.com/users/marksweiss/following{/other_user}","gists_url":"https://api.github.com/users/marksweiss/gists{/gist_id}","starred_url":"https://api.github.com/users/marksweiss/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marksweiss/subscriptions","organizations_url":"https://api.github.com/users/marksweiss/orgs","repos_url":"https://api.github.com/users/marksweiss/repos","events_url":"https://api.github.com/users/marksweiss/events{/privacy}","received_events_url":"https://api.github.com/users/marksweiss/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-10-06T17:31:35Z","updated_at":"2016-10-06T17:31:35Z","closed_at":null,"body":"Here is a brief, reproducible code fragment example, written using `gtest` and `glog` syntax. It passes.\r\n\r\n```\r\nTEST_F(Test, TestCrashFollyConv) {\r\n  double y = 1.1;\r\n  int32_t x = (int32_t)y;\r\n  ASSERT_TRUE(x == 1);\r\n  x = floor(y);\r\n  ASSERT_TRUE(x == 1);\r\n  bool folly_threw = false;\r\n  try {\r\n    x = folly::to<int32_t>(y);\r\n  } catch (std::exception& e) {\r\n    LOG(ERROR) << \"CAUGHT ERROR IN folly::to<int32_t>(double): \" << e.what();\r\n    folly_threw = true;\r\n  }\r\n  ASSERT_TRUE(folly_threw);\r\n}\r\n```\r\nInformally experimenting it appears an arbitrary number of `double` values fail to cast, raising this same error.\r\n\r\nOf course there are multiple workarounds, such as `floor()` and `ceil()` in `cmath` specifically for this purpose. But the docs for `Conv` specifically claim \"converts anything to anything\" so I'm reporting it.\r\n\r\nTaking a look at the code, float to int comparisons use lookup tables per digit that throw out of range exceptions if a position in the table is reached that doesn't match an expected position that would yield a digit. This is possibly the culprit, as under some failure scenarios I saw `std::range_error` raised, and in some saw the error message `to<>: loss of precision when converting 1.1 to type i` \r\n"}}
{"actor":{"display_login":"marksweiss"}}