-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Intrinsic arithmetic function overloads #8710
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
Conversation
|
Two things: Before we merge this, it'd be nice to validate that the fast path code now aligns properly with what would happen without the fast path. To do that, can you try ripping it all out and making sure all the tests pass as expected? (We'd want the fast path back before merging, of course.) Second, although long division truncating values is what we've advertised in our documentation, it isn't what we're currently doing, and someone may have taken a dependency on 10/3 being 3.33... Can you add a ChangeWave for division? I haven't looked too closely at your code yet, but the tests you posted in your comment look great to me. Thanks for working on this! |
|
When testing with the fast path disabled, the Example: produces a result of 9.22337203685478E+18 instead of the expected -9223372036854775808. I'll make a change to I'll make the ChangeWave cover integer versus real for addition, subtraction, multiplication, and division. (I also need to add tests for multiplication overflow.) |
This was a bit surprising to me, but I can see why it would do that. Rather than any overly complicated logic, can we just reorder the Add methods, for instance, such that it tries to coerce the arguments to integers, then longs, then doubles? I'm trying to minimize the impact of the change while still getting the desired outcome. |
|
Yes, the methods in the |
|
The changes are using change wave 17.8 as a placeholder pending discussion. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This mostly looks good to me. Thanks for the improvements iterations on this!
I'd only like to see the handling of attempts of large doubles to long conversions and explicit unit test(s) for integer literals outside long bounds. Then I'm ready to sign off
…g double to long; add tests for values that exceed long min/max
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the contribution and iterations on it!
I think it's good to go now (we'll just need to properly docuemnt the behavior after merging)
|
@JanKrivanek Was there feedback on the decimal separator? |
Not yet. I suppose we'll discuss this on Monday |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall. I've Added a few comments inline.
|
New commits to address #8798 within the scope of this work - i.e. code touched or changed by this PR now uses a different overload of double.TryParse(str, NumberStyles.Number | NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out arg)This may not close #8798. The issue could be in other places. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies for the delay, the changes look great. I've added one question inline. Also, when you get a chance, can you please update the description - I believe that some parts got out of sync with the change.
|
The description has been updated. |
Fixes #8698
Context
The MSBuild property functions for Add(), Subtract(), Multiply(), Divide(), and Modulo() have overloads for
longanddouble. The 'fast path' resolution for the functions supports thedoubleversions only. Both overloads should be supported.Design
The changes are focused on the 'fast path' for intrinsic functions. To determine which overload to call, the arguments are checked to see if they can be converted to a
longor, for astring, parsed to along. If the arguments can belong, thelongoverload is called. Otherwise, thedoubleoverload is called.From MSBuild XML, invocation of the
doubleoverload can be ensured by using a real literal, e.g.$([MSBuild]::Add(1, 0.0))invokes thedoubleoverload.With the
longoverload an overflow result that wraps is kept, e.g.-9223372036854775808is the result of the following function call.Preserve Existing Behavior for
EqualsandCompareToThe following two code examples currently work because
Add()always returns adoublebut there is an issue when thelongoverride is invoked.The
Microsoft.Build.Evaluation.Expander<P, I>.Function<T>.Execute()method has an existing special case for handlingEqualsandCompareTowhere the type of the argument toEqualsorCompareTois converted to match the type of the 'lhs' of the comparison.3.0can't be converted to along. To preserve the existing behavior, the argument is tested and if it is a real literal the lhs of the comparison is converted to adouble.In the MSBuild XML the
doubletodoublecomparison can be explicit by using a real literal or by converting to double as in the following examples.Changes Made
Implementation
Modified the
Microsoft.Build.Evaluation.Expander<P, I>.Function<T>class:TryConvertToLong().TryConvertToInt()andTryConvertToDouble().IsFloatingPointRepresentation().TryExecute*()methods, e.g.TryExecuteAdd().TryExecuteWellKnownFunction()to call the appropriateTryExecute*()method.Execute()to support existing behavior for comparisons withEqualsandCompareTo.LateBindExecute()to support selecting the correct overload to call.IntrinsicFunctionOverloadto provide cached comparer for sorting candidate overloads.Unit Tests
Modified the
Microsoft.Build.UnitTests.Evaluation.Expander_Testsclass:PropertyFunctionStaticMethodIntrinsicMaths()that was commented "test for overflow wrapping" but was testing for adoubleresult. Overflow wrapping is covered inPropertyFunctionMSBuildAdd().Medley()to add some tests. The change toMedley()are related to the comparison behavior withEqualsandCompareTo.PropertyFunctionMSBuildAdd()to testdoubleandlongincluding integer overflow wrapping.PropertyFunctionMSBuildSubtract(),PropertyFunctionMSBuildMultiply(),PropertyFunctionMSBuildDivide()to testlonganddouble.PropertyFunctionMSBuildModulo().Added the
ExpanderFunction_Testsunit test class.Added the
IntrinsicFunctionOverload_Testsunit test class.PR #8853
The changes in PR 8853 to use the InvariantCulture with double.TryParse have been included in this PR as well. If this PR is accepted and merged first, then issue #8798 and PR #8853 can also be closed based on this PR. But PR #8853 is smaller and can be accepted ahead of this PR.
Testing
Tested on Windows 11 and macOS 12.
Added new unit tests, extended existing tests, and ran all unit tests. The existing unit tests revealed the
Equals/CompareTocomparison behavior.Ran a test MSBuild XML project file. See below.
Notes
Negates PR #8649.
Test Project File