-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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]: Add AllBitsSet to the IBinaryNumber Interface #69676
Comments
Tagging subscribers to this area: @dotnet/area-system-numerics Issue DetailsBackground and motivationConceptually, The following types would explicitly implement Design of the implementation for all of these types is trivial except for API Proposalnamespace System.Numerics
{
public partial interface IBinaryNumber<TSelf>
{
static abstract TSelf AllBitsSet { get; }
}
} API UsageT genericAlgorithm(T input)
where T : IBinaryNumber<T> {
return input + T.AllBitsSet;
} Alternative DesignsWhen deciding whether a method is implemented explicitly or implicitly for Generic Math, we have used the following rule: if the concept is trivially handled by knowing the concrete type, it's implemented explicitly. In other words, it is not exposed on the concrete type. This way, the implementation is only available when working with the generic interface. In this case, we follow this logic and implement RisksCurrently, refactoring
|
namespace System.Numerics
{
public partial interface IBinaryNumber<TSelf>
{
static abstract TSelf AllBitsSet { get; }
}
} |
Background and motivation
Conceptually,
T.AllBitsSet
returns an instance of the binary number typeT
where every bit is set to 1. For example,Int32.AllBitsSet
is0xFFFFFFFF
, or-1
. This concept is generally useful for masking purposes. For example, Vectors useAllBitsSet
often for Conditional Select, as bitwise-anding a number withAllBitsSet
will produce the same number, in contrast to bitwise-anding a number withZero
. As brought up by #60882,AllBitsSet
would be a nice addition to theIBinaryNumber
interface, potentially enabling future generic refactoring ofScalar<T>
.The following types would explicitly implement
AllBitsSet
:Double
,Half
,NFloat
,Single
,Byte
,Char
,Int16
,Int32
,Int64
,IntPtr
,SByte
,UInt16
,UInt32
,UInt64
,UIntPtr
,BigInteger
,Int128
,Uint128
.Design of the implementation for all of these types is trivial except for
BigInteger
. ForBigInteger
, the most obvious implementation would be to returnMinusOne
, as despite the internal bit representation not being literallyAllBitsSet
(due toBigInteger
having unbounded size), it behaves as such for bitwise operations.API Proposal
API Usage
Alternative Designs
When deciding whether a method is implemented explicitly or implicitly for Generic Math, we have used the following rule: if the concept is trivially handled by knowing the concrete type, it's implemented explicitly. In other words, it is not exposed on the concrete type. This way, the implementation is only available when working with the generic interface.
In this case, we follow this logic and implement
AllBitsSet
explicitly, as knowing the concrete type leads to a trivial implementation (https://source.dot.net/#System.Private.CoreLib/Scalar.cs,11). However, it could be argued thatAllBitsSet
is conceptually tricky enough for some of these types that a implicit implementation is warranted.Additional Notes
Currently, refactoring
Scalar<T>
to take advantage of this is not possible without a language change. More specifically, the language doesn't have a way to "bridge" type constraints. So, sinceVector<T>
iswhere T : struct
but we'd wantScalar<T>
to bewhere T : struct, IBinaryNumber<T>
, we'd need the language to provide some way to allowVector<T>
to useScalar<T>
despite the mismatching type requirements.The text was updated successfully, but these errors were encountered: