Skip to content

The mask of shiftAmount in IShiftOperators<byte, int, byte> should be 7 instead of 31 #103506

Closed
@skyoxZ

Description

@skyoxZ

Description

/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_LeftShift(TSelf, TOther)" />
static byte IShiftOperators<byte, int, byte>.operator <<(byte value, int shiftAmount) => (byte)(value << shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_RightShift(TSelf, TOther)" />
static byte IShiftOperators<byte, int, byte>.operator >>(byte value, int shiftAmount) => (byte)(value >> shiftAmount);
/// <inheritdoc cref="IShiftOperators{TSelf, TOther, TResult}.op_UnsignedRightShift(TSelf, TOther)" />
static byte IShiftOperators<byte, int, byte>.operator >>>(byte value, int shiftAmount) => (byte)(value >>> shiftAmount);

Reproduction Steps

using System;
using System.Numerics;

BinaryIntegerWrapper<byte> a = new(2);
Console.WriteLine((a << 11).Value);

public struct BinaryIntegerWrapper<T> : IShiftOperators<BinaryIntegerWrapper<T>, int, BinaryIntegerWrapper<T>>
            where T : IBinaryInteger<T>
{
    public T Value;

    public BinaryIntegerWrapper(T value) => Value = value;

    public static implicit operator BinaryIntegerWrapper<T>(T value) => new BinaryIntegerWrapper<T>(value);

    public static BinaryIntegerWrapper<T> operator <<(BinaryIntegerWrapper<T> value, int shiftAmount) => value.Value << shiftAmount;
    public static BinaryIntegerWrapper<T> operator >>(BinaryIntegerWrapper<T> value, int shiftAmount) => value.Value >> shiftAmount;
    public static BinaryIntegerWrapper<T> operator >>>(BinaryIntegerWrapper<T> value, int shiftAmount) => value.Value >>> shiftAmount;
}

Expected behavior

16

Actual behavior

0

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

Per this comment from @tannergooding:

This is also notably an issue with sbyte, short, and ushort. It is also, unfortunately, a breaking change and will need a bar check.

The intent had indeed been to correctly mask, which is being done in other operations but was missed for these ones.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-System.Numericsbreaking-changeIssue or PR that represents a breaking API or functional change over a prerelease.bugin-prThere is an active PR which will close this issue when it is mergedneeds-breaking-change-doc-createdBreaking changes need an issue opened with https://github.com/dotnet/docs/issues/new?template=dotnet

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions