{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/coreclr/issues/2285","labels_url":"https://api.github.com/repos/dotnet/coreclr/issues/2285/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/coreclr/issues/2285/comments","events_url":"https://api.github.com/repos/dotnet/coreclr/issues/2285/events","html_url":"https://github.com/dotnet/coreclr/issues/2285","id":121357604,"number":2285,"title":"Problems with thousands separators when parsing strings to numbers","user":{"login":"varocarbas","id":4943723,"avatar_url":"https://avatars.githubusercontent.com/u/4943723?v=3","gravatar_id":"","url":"https://api.github.com/users/varocarbas","html_url":"https://github.com/varocarbas","followers_url":"https://api.github.com/users/varocarbas/followers","following_url":"https://api.github.com/users/varocarbas/following{/other_user}","gists_url":"https://api.github.com/users/varocarbas/gists{/gist_id}","starred_url":"https://api.github.com/users/varocarbas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/varocarbas/subscriptions","organizations_url":"https://api.github.com/users/varocarbas/orgs","repos_url":"https://api.github.com/users/varocarbas/repos","events_url":"https://api.github.com/users/varocarbas/events{/privacy}","received_events_url":"https://api.github.com/users/varocarbas/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":66,"created_at":"2015-12-09T22:39:46Z","updated_at":"2015-12-11T12:31:26Z","closed_at":null,"body":"Since some months ago, I have been aware about the problems that the parsing methods (at least, ```Parse``` and ```TryParse```) of various numerical types (at least, ```Decimal``` and ```Double```) have when dealing with thousands separators (at least in .NET 4.5; in both C# and VB.NET). The following C# sample code illustrates the point well:\r\n```C#\r\nstring stringVal = \"1,1.1\";\r\ndecimal decVal = 0m;\r\nif (decimal.TryParse(stringVal, NumberStyles.Any, CultureInfo.InvariantCulture, out decVal))\r\n{\r\n    //This part will be reached, because decimal.TryParse thinks that 1,1.1 is a valid number\r\n}\r\n```\r\nSuch misbehaviour can be replicated under many different conditions. The basic idea is that the parsing approaches don't understand what the thousands separators really imply (i.e., groups of 3 numbers in the aforementioned example).\r\n\r\nToday, I focused my analysis of the code on the ```Decimal``` type and found ```ParseNumber``` (mscorlib\\src\\System\\Number.cs). The way in which this method treats the thousands separators (in all their forms) explains perfectly the observed behaviour: it focus the analysis on valid/invalid characters and doesn't bring into account the size of the group at any point.\r\n\r\nMy proposal consists in forcing the corresponding methods to trigger an error when the thousands separators aren't in the right positions. My intention is firstly focusing on the ```Decimal``` type (although the aforementioned method is most likely used by other types too). After having ready a good enough correction for ```Decimal```, I will analyse the remaining types in detail and perform additional changes if required.\r\n\r\nThe correction will consist in analysing the input string; in case of including thousands separators, their locations would be checked. If this analysis fails, no conversion to number would be performed. In principle, I am planning to take advantage from the current implementation (more specifically, a loop analysing all the characters) and rely on “low level” approaches; although I have still to think carefully about the exact algorithm.\r\n"},"comment":{"url":"https://api.github.com/repos/dotnet/coreclr/issues/comments/163927270","html_url":"https://github.com/dotnet/coreclr/issues/2285#issuecomment-163927270","issue_url":"https://api.github.com/repos/dotnet/coreclr/issues/2285","id":163927270,"user":{"login":"varocarbas","id":4943723,"avatar_url":"https://avatars.githubusercontent.com/u/4943723?v=3","gravatar_id":"","url":"https://api.github.com/users/varocarbas","html_url":"https://github.com/varocarbas","followers_url":"https://api.github.com/users/varocarbas/followers","following_url":"https://api.github.com/users/varocarbas/following{/other_user}","gists_url":"https://api.github.com/users/varocarbas/gists{/gist_id}","starred_url":"https://api.github.com/users/varocarbas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/varocarbas/subscriptions","organizations_url":"https://api.github.com/users/varocarbas/orgs","repos_url":"https://api.github.com/users/varocarbas/repos","events_url":"https://api.github.com/users/varocarbas/events{/privacy}","received_events_url":"https://api.github.com/users/varocarbas/received_events","type":"User","site_admin":false},"created_at":"2015-12-11T12:31:26Z","updated_at":"2015-12-11T12:31:26Z","body":"Some people have proven that my last comment was wrong: the bottom wasn't still reached by my previous comment (not sure how low can go some people still; let's see)."}}