Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Преобразования с плавающей запятой к целым числам теперь имеют насыщенное поведение на компьютерах x86 и x64. Насыщенность поведения означает, что если преобразованное значение слишком мало или большое для целевого типа, то значение присваивается минимальному или максимальному значению соответственно для этого типа.
Прежнее поведение
В следующей таблице показано предыдущее поведение при преобразовании или float значенииdouble.
| Преобразуйте в ... | Значение параметра x |
(Предыдущий) результат |
|---|---|---|
int скалярные и упакованные |
int.MinValue <= x <= int.MaxValue |
(int)x |
< int.MinValue или > int.MaxValue |
int.MinValue |
|
long скалярные и упакованные |
long.MinValue <= x <= long.MaxValue |
(long)x |
< long.MinValue или > long.MaxValue |
long.MinValue |
|
uint скалярные и упакованные |
Любое значение | (((long)x << 32) >> 32) |
ulong скалярные и упакованные |
<= 2^63 |
(long)x |
> 2^63 |
(long)(x - 2^63) + 2^63 |
Новое поведение
В следующей таблице показано новое поведение при преобразовании или float значенииdouble.
| Преобразуйте в ... | Значение параметра x |
Результат .NET 9+ |
|---|---|---|
int скалярные и упакованные |
int.MinValue <= x <= int.MaxValue |
(int)x |
< int.MinValue |
int.MinValue |
|
> int.MaxValue |
int.MaxValue |
|
NaN |
0 | |
long скалярные и упакованные |
long.MinValue <= x <= long.MaxValue |
(long)x |
< long.MinValue |
long.MinValue |
|
> long.MaxValue |
long.MaxValue |
|
NaN |
0 | |
uint скалярные и упакованные |
0 <= x <= uint.MaxValue |
(uint)x |
x > uint.MaxValue |
uint.MaxValue |
|
x < 0 |
0 | |
ulong скалярные и упакованные |
0 <= x <= ulong.MaxValue |
(ulong)x |
x > ulong.MaxValue |
ulong.MaxValue |
|
x < 0 |
0 |
Представленные версии
.NET 9( предварительная версия 4)
Тип критического изменения
Причина изменения
Это изменение было сделано, чтобы стандартизировать все преобразования с плавающей запятой к целым числам, чтобы иметь насыщенное поведение и сделать поведение детерминированным.
Рекомендуемое действие
Если вы использовали значения, отображаемые в разделе "Предыдущее поведение ", возвращаемые из преобразования, даже если они были неверными, обновите код, чтобы ожидать, что значения, отображаемые в разделе "Новое поведение ".
Если затраты на производительность нового поведения нежелательны для вашего сценария, можно использовать новые ConvertToIntegerNative<TInteger> методы для одного, double и half , которые быстро. В большинстве случаев поведение этих методов соответствует предыдущему поведению преобразования с плавающей запятой к целым числам. Однако эти методы имеют поведение, зависящее от платформы , которое не гарантирует соответствие предыдущему поведению преобразования (которое уже было недетерминированным). Вместо этого эти методы делают все, что наиболее эффективно для собственной платформы. В частности, результат не гарантируется для значений, которые находятся за пределами представляющего диапазона TInteger типа.
В редких случаях, когда требуется производительность и строгая гарантия соответствия предыдущему поведению преобразования, можно использовать встроенные компоненты оборудования для конкретной платформы. Например, для обработки (int)valможно использовать float). Перед использованием необходимо проверить if (Sse.IsSupported) . Однако использование этих встроенных функций сложно, так как другие целевые платформы (такие Arm64) уже дают различные результаты.
Затронутые API
Все явные и неявные приведения из плавающей точки в целое число:
-
(int)valгдеvalнаходитсяfloatилиdouble Vector.ConvertToInt32(Vector<float> val)-
(long)valгдеvalнаходитсяfloatилиdouble Vector.ConvertToInt64(Vector<double> val)-
(uint)valгдеvalнаходитсяfloatилиdouble Vector.ConvertToUInt32(Vector<float> val)-
(ulong)valгдеvalнаходитсяfloatилиdouble Vector.ConvertToUInt64(Vector<double> val)