dotnet / docs

This repository contains .NET Documentation.
https://learn.microsoft.com/dotnet
Creative Commons Attribution 4.0 International
4.28k stars 5.91k forks source link

[Breaking Change] Generic math shifts should use the appropriate mask #43303

Open tannergooding opened 1 week ago

tannergooding commented 1 week ago

Description

Introduced with https://github.com/dotnet/runtime/pull/103900

Version

.NET 10 Preview 1

Previous Behavior

The behavior when utilizing generic math to perform a shift on a T could differ based on the type. In some case it would appropriately mask the shift amount by sizeof(T) - 1 and in other cases it would do no masking. This meant that "overshifting" (such as shifting a byte by 8) could result in different answers being produced than expected.

New Behavior

The implementations were updated to mask the shift amount, as appropriate, to ensure consistent behavior across all built-in integer types and with the behavior documented by the IShiftOperators interface.

Reason for change

The behavior differed from the designed behavior due to a difference in how masking works for small integer types in C#.

Feature Area

Numerics

Affected APIs

operator <<, operator >>, and operator >>> for byte, char, sbyte, short, and ushort when used via Generic Math, which requires a T constrained to where T : IShiftOperators<T, int, T> or a similar interface.

skyoxZ commented 1 week ago

A small correct: The mask was 31 (not no mask) because they were converted to int.