Самое быстрое преобразование UInt32 в int в С#

У меня есть быстрая подпрограмма на уровне битов, которая вычисляет значение и возвращает UInt32. Мне нужно сохранить это значение в SQL Server в 32-битном поле int. Я не хочу увеличивать размер поля, а просто хочу сохранить «байты» из этой функции в поле int.

Одновременно запрашиваются сотни таких записей, поэтому мне нужен самый быстрый способ преобразовать UInt32 в int в цикле. Если крайний левый бит установлен в UInt32, он должен установить бит знака int (или сделать что-то «повторяемое», на самом деле, но бит знака, вероятно, будет проще всего).

Другими словами, я просто хочу, чтобы 4 байта UInt32 стали 4 байтами 32-битного целого числа. Я мог бы использовать класс BitConverter, но я не уверен, что это самый быстрый способ. Было бы быстрее сделать это с непроверенной областью, например:

UInt32 fld = 4292515959;
unchecked {
    return (int)fld;
    // -2451337
}

Я вижу, что здесь был задан обратный вопрос, и мне просто было интересно, будет ли ответ таким же в другом направлении:

Самый быстрый способ побитового приведения int к UInt32?


person Flipster    schedule 02.01.2011    source источник
comment
То же самое, вы можете думать о C# как о C с проверками безопасности. Поэтому, если вы хотите преобразовать unsigned int в int, просто используйте приведение типов. Но сначала заключите его в unchecked, сигнализируя компилятору не проверять ваше намерение, иначе компилятор выдаст вам ошибку, что присвоение несовместимо, несовместимо, это означает, что точность значения может быть потеряна при переводе ( например, 4292515959 уже не то же самое, станьте отрицательным 2451337 (они одинаковы с точки зрения ученого-компьютерщика [xkcd 541]))   -  person Michael Buen    schedule 02.01.2011
comment
Спасибо, Майкл. Если бы вы не сделали это комментарием, я бы сразу проголосовал за это как за ответ.   -  person Flipster    schedule 02.01.2011


Ответы (2)


Я бы сказал, что непроверенная версия (например, unchecked((int)x)) является самым быстрым способом, поскольку нет вызова метода. Я не верю, что есть более быстрый способ.

Кстати, UInt32 - это просто другое имя для uint... идти в одну сторону - это то же самое, что и в другую с точки зрения производительности, так что это действительно то же самое, что и ссылка, которую вы разместили.


Редактировать: я помню, как лично наблюдал пример теста, где checked был быстрее, чем unchecked (и нет, это была не отладочная сборка, это была сборка релиза с оптимизацией). Я не знаю, почему это произошло, но в любом случае не думайте, что вы получите что-то измеримое, отключив проверку переполнения.

person user541686    schedule 02.01.2011
comment
Спасибо Ламберт. Как раз то утешение, которое мне было нужно. - person Flipster; 02.01.2011

unchecked((int)x) требуется только приведение констант, а проверенное и непроверенное дает одинаковые результаты (если код может компилироваться).

Например этот код

uint data = 4292515959;
int uncheckedData;
int checkedData;
unchecked {
    uncheckedData = (int)data;
}
checkedData = (int)data;

Console.WriteLine(data);
Console.WriteLine(uncheckedData);
Console.WriteLine(checkedData);

производит этот вывод

4292515959
-2451337
-2451337

Чтобы быть более кратким, этот код можно скомпилировать (тот же результат, что и unchecked((int)data))

uint data = 4292515959;
checkedData = (int)data;

Этот код (обратите внимание на const) не может быть скомпилирован (требуется снятие флажка)

const uint data = 4292515959;
checkedData = (int)data;

Этот код также не может быть скомпилирован (требуется снятый флажок)

checkedData = (int)4292515959;
person bubi    schedule 20.03.2019