Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add trailing zero check to NumberBuffer.CheckConsistency #48418

Open
pgovind opened this issue Feb 17, 2021 · 1 comment
Open

Add trailing zero check to NumberBuffer.CheckConsistency #48418

pgovind opened this issue Feb 17, 2021 · 1 comment

Comments

@pgovind
Copy link
Contributor

pgovind commented Feb 17, 2021

For floating point numbers, we don't keep track of trailing zeros that occur after a decimal point. This check needs to be added to the NumberBuffer.CheckConsistency method. My first attempt to do this was

                uint totalDigits = (uint)(DigitsCount);
                uint positiveExponent = (uint)(Math.Max(0, Scale));
                uint integerDigitsPresent = Math.Min(positiveExponent, totalDigits);
                uint fractionalDigitsPresent = totalDigits - integerDigitsPresent;

                // For a number like 1.23000, verify that we don't store trailing zeros in Digits
                // However, if the number of digits exceeds maxDigCount and rounding is required, we store the trailing zeros in the buffer.
                if (fractionalDigitsPresent > 0 && !HasNonZeroTail)
                {
                    Debug.Assert(Digits[DigitsCount - 1] != '0', ToString());
                }

However while this works for double.Parse, it doesn't work for double.Format because of how the number buffer is populated. Example error below:

["21474836470000000", Length = 17, Scale = 10, IsNegative = True, HasNonZeroTail = False, Kind = FloatingPoint]
   at System.Number.FormatDouble(ValueStringBuilder& sb, Double value, ReadOnlySpan`1 format, NumberFormatInfo info) in /_/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs:line 554
   at System.Number.FormatDouble(Double value, String format, NumberFormatInfo info) in /_/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs:line 383
   at System.Double.ToString(String format) in /_/src/libraries/System.Private.CoreLib/src/System/Double.cs:line 266
   at System.Numerics.Tests.BigIntegerConstructorTest.VerifyCtorDouble(Double value) in /_/src/libraries/System.Runtime.Numerics/tests/BigInteger/ctor.cs:line 548
   at System.Numerics.Tests.BigIntegerConstructorTest.RunCtorDoubleTests() in /_/src/libraries/System.Runtime.Numerics/tests/BigInteger/ctor.cs:line 402

The likely fix here is to either turn on the trailing zero check only for the *Parse methods, or to improve the trailing zero check to better track a decimal point in the input/format.

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Numerics untriaged New issue has not been triaged by the area owner labels Feb 17, 2021
@ghost
Copy link

ghost commented Feb 17, 2021

Tagging subscribers to this area: @tannergooding, @pgovind
See info in area-owners.md if you want to be subscribed.

Issue Details

For floating point numbers, we don't keep track of trailing zeros that occur after a decimal point. This check needs to be added to the NumberBuffer.CheckConsistency method. My first attempt to do this was

                uint totalDigits = (uint)(DigitsCount);
                uint positiveExponent = (uint)(Math.Max(0, Scale));
                uint integerDigitsPresent = Math.Min(positiveExponent, totalDigits);
                uint fractionalDigitsPresent = totalDigits - integerDigitsPresent;

                // For a number like 1.23000, verify that we don't store trailing zeros in Digits
                // However, if the number of digits exceeds maxDigCount and rounding is required, we store the trailing zeros in the buffer.
                if (fractionalDigitsPresent > 0 && !HasNonZeroTail)
                {
                    Debug.Assert(Digits[DigitsCount - 1] != '0', ToString());
                }

However while this works for double.Parse, it doesn't work for double.Format because of how the number buffer is populated. Example error below:

["21474836470000000", Length = 17, Scale = 10, IsNegative = True, HasNonZeroTail = False, Kind = FloatingPoint]
   at System.Number.FormatDouble(ValueStringBuilder& sb, Double value, ReadOnlySpan`1 format, NumberFormatInfo info) in /_/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs:line 554
   at System.Number.FormatDouble(Double value, String format, NumberFormatInfo info) in /_/src/libraries/System.Private.CoreLib/src/System/Number.Formatting.cs:line 383
   at System.Double.ToString(String format) in /_/src/libraries/System.Private.CoreLib/src/System/Double.cs:line 266
   at System.Numerics.Tests.BigIntegerConstructorTest.VerifyCtorDouble(Double value) in /_/src/libraries/System.Runtime.Numerics/tests/BigInteger/ctor.cs:line 548
   at System.Numerics.Tests.BigIntegerConstructorTest.RunCtorDoubleTests() in /_/src/libraries/System.Runtime.Numerics/tests/BigInteger/ctor.cs:line 402

The likely fix here is to either turn on the trailing zero check only for the *Parse methods, or to improve the trailing zero check to better track a decimal point in the input/format.

Author: pgovind
Assignees: -
Labels:

area-System.Numerics, untriaged

Milestone: -

@pgovind pgovind removed the untriaged New issue has not been triaged by the area owner label Feb 17, 2021
@pgovind pgovind self-assigned this Feb 17, 2021
@tannergooding tannergooding added this to the Future milestone Jun 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants