-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
[API Proposal]: Support General Math value creation without sign propagation #106927
Comments
If you need a delta between two numbers, use |
I need to get TTo(255) from TFrom(-1). Abs(-1) is equal to 1 but not 255. |
This isn't valid given an arbitrary Given If all values are within range of |
Can you provide a more concrete example and explicitly lay out the constraints/assumptions of What you'd want to do if It also differs based on whether |
Yes When For example when |
This doesn't sound correct, as you could have a negative result produced for the scenario I gave, such as The only case it would be safe is if you knew that
When you have negatives covering the full range like this, there isn't really any fix you can do. You have lost information the moment you did You can't use the For types with a representable range smaller than |
Yes
I don't know in advance when
It works for |
I propose to expand the API for this case so that it always works. |
Which means its not an API we can provide in box.
This would be a breaking change and is not something we're interested in doing.
If you can guarantee that length = int.CreateTruncating(end - start);
if (length < 0)
{
length = int.CreateTruncating(end) - int.CreateTruncating(start);
} |
No breaking change in my suggestion. |
The breaking change is that we cannot provide such a DIM without requiring some behavioral breaking change due to the fact that the output of Such as for There's no API we could provide here because there is no way to do the conversion and have it always behave as you're intending. |
@tannergooding I didn't look at how |
There are two This ensures that some concrete type is always defining the correct conversion behavior, because it at least understands its own definition and that is enough to ensure correct deterministic behavior in most scenarios. The number types were designed to work by understanding the exact represented value of a |
@tannergooding As far as I understood your explanation, the proposed API can be implemented. I'm not suggesting using serialization. |
You're going to have to give the code you believe will work here. I do not see a way that a |
@tannergooding Assert.Equal(unchecked((int)0xFFFFFF80), NumberBaseHelper<int>.CreateTruncating<sbyte>(unchecked((sbyte)0x80), true));
Assert.Equal(unchecked((int)0xFFFFFFFF), NumberBaseHelper<int>.CreateTruncating<sbyte>(unchecked((sbyte)0xFF), true));
Assert.Equal(unchecked((int)0x80), NumberBaseHelper<int>.CreateTruncating<sbyte>(unchecked((sbyte)0x80), false));
Assert.Equal(unchecked((int)0xFF), NumberBaseHelper<int>.CreateTruncating<sbyte>(unchecked((sbyte)0xFF), false)); runtime/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.GenericMath.cs Lines 1980 to 1999 in 47c68c6
|
Background and motivation
I want to calculate the difference between two values as a non-negative
max - start
number.TFrom start
, andTFrom max
define a range whose length is from0
toint.MaxValue - 1
.0 <= length < int.MaxValue
When
TFrom
is wider thanint
, calculate the length simply aslength = int.CreateTruncating(end - start)
, because the differenceend - start
is always positive.When
TFrom
is narrower thanint
and has a sign, the difference between them can be a negative number, which is difficult to convert to a positive value. For example whenTFrom
issbyte
andstart = -128; max = 127
thenlength = 128 + 127 = 255 = -1 (signed byte)
.It isn't not easy to convert TFrom(-1) to positive TTo(255)
int.CreateTruncating(TFrom(-1))
creates int(-1)uint.CreateTruncating(TFrom(-1))
creates uint.MaxValue. This made the sign propagation!So I made the next workaround code.
API Proposal
API Usage
See also
runtime/src/libraries/System.Linq/src/System/Linq/Range.cs
Lines 30 to 49 in e689e2a
Alternative Designs
No response
Risks
No response
The text was updated successfully, but these errors were encountered: