Parse double precision using InvariantCulture#2722
Parse double precision using InvariantCulture#2722stephenquan wants to merge 12 commits intoCommunityToolkit:mainfrom
Conversation
src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs
Outdated
Show resolved
Hide resolved
| @@ -362,7 +362,7 @@ bool ParsePrimary() | |||
| if (ParsePattern(EvaluateNumberPattern())) | |||
There was a problem hiding this comment.
It might be good to turn on the CA1305 analyzer in the project to avoid similar bugs.
There was a problem hiding this comment.
@MartyIX based on your feedback, I applied the CA1305 analyzer and found multiple conversions in MathExpression.shared.cs that needed updates to satisfy the analyzer. After the changes all unit tests for the math converters still passed.
The CA1305 analyzer also picked up new issues which isn't part of the scope of this PR. Would you like me to create split 3 issues to look? (Camera CA1305, SpeechToText CA1305, Badge CA1305)?
F:\Maui\src\CommunityToolkit.Maui.Camera\CameraInfo.shared.cs(99,4): error CA1305: The behavior of 'StringBuilder.Append(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CameraInfo.ToString()' with a call to 'StringBuilder.Append(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
F:\Maui\src\CommunityToolkit.Maui.Camera\CameraInfo.shared.cs(99,4): error CA1305: The behavior of 'StringBuilder.Append(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CameraInfo.ToString()' with a call to 'StringBuilder.Append(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
F:\Maui\src\CommunityToolkit.Maui.Camera\CameraInfo.shared.cs(99,4): error CA1305: The behavior of 'StringBuilder.Append(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CameraInfo.ToString()' with a call to 'StringBuilder.Append(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
F:\Maui\src\CommunityToolkit.Maui.Camera\CameraInfo.shared.cs(99,4): error CA1305: The behavior of 'StringBuilder.Append(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CameraInfo.ToString()' with a call to 'StringBuilder.Append(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
F:\Maui\src\CommunityToolkit.Maui.Camera\CameraInfo.shared.cs(99,4): error CA1305: The behavior of 'StringBuilder.Append(ref StringBuilder.AppendInterpolatedStringHandler)' could vary based on the current user's locale settings. Replace this call in 'CameraInfo.ToString()' with a call to 'StringBuilder.Append(IFormatProvider, ref StringBuilder.AppendInterpolatedStringHandler)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
F:\Maui\src\CommunityToolkit.Maui.Core\Essentials\SpeechToText\OfflineSpeechToTextImplementation.android.cs(188,56): error CA1305: The behavior of 'int.ToString()' could vary based on the current user's locale settings. Replace this call in 'RecognitionSupportCallback.OnError(int)' with a call to 'int.ToString(IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
F:\Maui\src\CommunityToolkit.Maui.Core\Essentials\Badge\BadgeImplementation.windows.cs(22,40): error CA1305: The behavior of 'uint.ToString()' could vary based on the current user's locale settings. Replace this call in 'BadgeImplementation.SetCount(uint)' with a call to 'uint.ToString(IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
Build failed with 7 error(s) and 81 warning(s) in 3.8s
There was a problem hiding this comment.
You can change the pattern to something like this:
@"^-?\d+[.,]?\d*$"
It should match:
- 123
- -123.45
- -123,45
There was a problem hiding this comment.
Hi @VladislavAntonyuk, sorry it's been awhile since I've replied to your comment. The struggle I have with your suggestion is that we're trying to make the expressions follow InvariantCulture so that the expressions are deterministic and will not be influence by language changes. The other reason is that the comma (,) is already part of the expression for delimiting functional arguments (e.g. atan2).
There was a problem hiding this comment.
Hi @VladislavAntonyuk, I watched this month's standup and noted two key discussions:
- Whether developers can pass CultureInfo as a parameter as a new parameter to the MathExpressionConvertre/MultiMathExpressionConverter
- Whether the CultureInfo parameter passed to IValueConverter/IMultiValueConverter convert methods can be used (which, from my limited understanding/testing, seems to follow whatever CultureInfo.CurrentUICulture is set to)
Just to reiterate my application's use case: the application supports runtime switching between 30+ languages, which updates CultureInfo.CurrentCulture and CultureInfo.CurrentUICulture. However, our UI uses MultiMathExpressionConverter for some spinner logic (e.g., x0 ? -90 : 0) which needs to be language agnostic. In Arabic, parsing the negative sign causes a crash. The crash can be understood because of Arabic not recognizing the minus sign.
CultureInfo.CurrentCulture = new CultureInfo("ar-AR");
var value = double.Parse("-90"); // Throws System.FormatException: 'The input string '-90' was not in a correct format.'In our application, we have worked around this problem by coming up with alternates ways to specify -90.
Head branch was pushed to by a user without write access
|
@VladislavAntonyuk I've pushed a new commit that introduces the The original issue, however, supporting Arabic as the numeric culture, is currently out of scope. Properly handling Arabic number formatting would require a significantly more robust parsing strategy to accommodate all relevant symbols. The example below highlights the mapping we need to consider to convert Arabic number format to Western number format (including swapping the decimal with the comma). 🧮 Arabic Number Formatting Summary (Culture:
|
| Component | Arabic Format | Unicode | Notes |
|---|---|---|---|
| Digits | Arabic-Indic (٠١٢٣٤٥٦٧٨٩) |
U+0660–U+0669 | Replaces Western digits (0–9) |
| Decimal Separator | Arabic decimal ٫ |
U+066B | Replaces the Western . |
| Thousands Separator | Arabic comma ٬ |
U+066C | Replaces the Western , |
| Minus Sign | Unicode minus − |
U+2212 | Replaces the Western Hyphen-minus - |
src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs
Outdated
Show resolved
Hide resolved
src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpression.shared.cs
Show resolved
Hide resolved
src/CommunityToolkit.Maui/Converters/MathExpressionConverter/MathExpressionConverter.shared.cs
Outdated
Show resolved
Hide resolved
|
Adding #2665 |
Description of Change
Parse a double using InvariantCulture to avoid issues when CurrentCulture changes, such as to 'ar-AR'.
Linked Issues
PR Checklist
approved(bug) orChampioned(feature/proposal)mainat time of PRAdditional information
None