2014-10-16 4 views
0

Я писал порт сетевой библиотеки из Java, и это последняя строка кода, которую я еще не расшифровал и не перешел. Строка кода выглядит следующим образом:C#, эквивалентный Java Float.floatToIntBits

Float.floatToIntBits(Float); 

Что возвращает целое число.

Код floatToIntBits в Java

public static int floatToIntBits(float value) { 
     int result = floatToRawIntBits(value); 
     // Check for NaN based on values of bit fields, maximum 
     // exponent and nonzero significand. 
     if (((result & FloatConsts.EXP_BIT_MASK) == 
       FloatConsts.EXP_BIT_MASK) && 
      (result & FloatConsts.SIGNIF_BIT_MASK) != 0) 
      result = 0x7fc00000; 
     return result; 
    } 

Я не столь опытный достаточно с памятью и шестнадцатеричные значения в порт этого по себе, не говоря уже о немного сдвигая это повсюду, что это было меня совершенно безумно.

+0

Не знаете, зачем вам нужен такой код ... Не имеет ли у C# эквивалента «ByteBuffer» Java (который может определять endianness), который вы можете использовать вместо этого? Или 'Data * Stream'? Вы не делаете все операции с энтианностью вручную, не так ли? – fge

+0

@fge - я преобразовываю сетевую библиотеку на C#, которая требует использования функций, поскольку она шифрует и дешифрует данные по-своему. – Hobbyist

ответ

0

Если вы можете скомпилировать с unsafe, это становится тривиальным:

public static unsafe uint FloatToUInt32Bits(float f) { 
    return *((uint*)&f); 
} 

Заменить uint с int если вы хотите работать с подписанными значениями, но я бы сказал, что unsigned имеет больше смысла. Это фактически эквивалентно Java floatToRawIntBits(); floatToIntBits() идентичен, за исключением того, что он всегда возвращает одну и ту же битовую маску для всех значений NaN. Если вы хотите эту функциональность, вы можете просто скопировать этот оператор if из версии Java, но это, вероятно, излишне.

Вам понадобится включить «небезопасную» поддержку для вашей сборки, так что вам решать, хотите ли вы пройти этот маршрут. Для высокопроизводительных сетевых библиотек небезопасно использовать небезопасный код.

+0

Теперь, чтобы выяснить, как сделать Unity3D Разрешить небезопасный код, спасибо за сообщение. Я бы хотел убедиться, что я это понимаю. Из небольшого количества изменений в игре, которые я сделал с созданием «хаков», я знаю, что оператор '*' объявляет значение адреса в памяти, я никогда не видел его вложенным совершенно так; Вы не возражаете объяснить? – Hobbyist

+0

Это действительно возврат к C-языку. Оператор '&' создает место хранения (адрес памяти) переменной, в данном случае - указатель на float ('float *'). Листинг говорит компилятору «это на самом деле указатель на значение« uint »(« uint * ')». Оператор '*' извлекает значение в месте хранения, указанном указателем. Итак, в основном, вы говорите компилятору, чтобы прочитать значение 'uint' из памяти, где хранится' f'. Вы получаете любое целое число, имеющее одно и то же поразрядное представление значения float. –

+0

Спасибо за информацию! – Hobbyist

3

Посмотрите на класс BitConverter. Для двойников он имеет методы DoubleToInt64Bits и Int64BitsToDouble. Для поплавков вы могли бы сделать что-то вроде этого:

float f = ...; 
int i = BitConverter.ToInt32(BitConverter.GetBytes(f), 0); 

Или меняется порядок байт:

byte[] bytes = BitConverter.GetBytes(f); 
Array.Reverse(bytes); 
int i = BitConverter.ToInt32(bytes, 0); 
+0

Спасибо. Я проведу его по сети за мгновение – Hobbyist

+0

Не работает, следующие данные были предоставлены 'Float: 5.2109E-41' от отправки значения float' 72.5f' через сеть. – Hobbyist

+0

Я попытался изменить континент и получил тот же результат для '72.5f':' 5.210868E-41'. Поэтому второй вариант в моем ответе ** должен работать **. – Dmitry

Смежные вопросы