Как работает Float.intBitsToFloat?

#java #binary #floating-point

#java #двоичный #с плавающей запятой

Вопрос:

Кто-нибудь может объяснить мне или дать ссылку на какой-нибудь полезный ресурс, чтобы понять алгоритм, лежащий в основе метода Java Float.intBitsToFloat(int) ?

Комментарии:

1. Хм … разве это не означало бы просто перенести все, что осталось, в мантиссу?

2. чего вы не понимаете в javadoc?

3. моя ошибка, я только что пропустил javadocs! 🙂

Ответ №1:

Java использует IEEE 754 с плавающей запятой. Float.intBitsToFloat(int) работает, интерпретируя 32 бита своего аргумента так, как если бы они указывали 32-разрядное значение с плавающей запятой в формате, описанном здесь.

Double.longBitsToDouble(long) работает аналогично для 64-разрядных файлов с плавающей запятой, как описано здесь .

В C вы могли бы достичь того же эффекта следующим образом:

 #include <stdint.h>

union int_float_bits {
    int32_t int_bits;
    float float_bits;
};

float intBitsToFloat(int32_t x)
{
    union int_float_bits bits;
    bits.int_bits = x;
    return bits.float_bits;
}
  

(Хотя технически это было бы неопределенным поведением, фактически оно практически всегда работает так, как ожидалось.)

Ответ №2:

Документы JDK6 довольно хороши, а сам исходный код довольно поучителен (он просто использует объединение C):

 JNIEXPORT jfloat JNICALL
Java_java_lang_Float_intBitsToFloat(JNIEnv *env, jclass unused, jint v)
{
    union {
        int i;
        float f;
    } u;
    u.i = (long)v;
    return (jfloat)u.f;
}    
  

Ответ №3:

На подавляющем большинстве современных платформ размер целого числа в процессорах по умолчанию равен 32 битам, как и размер числа с плавающей точкой, поэтому мы будем считать, что преобразование между ними не дает неожиданных результатов. Вы, вероятно, уже знаете это, но в Java целые числа не могут быть объявлены как беззнаковые, хотя вы можете указать шестнадцатеричное значение, соответствующее единице. Фактическое преобразование, продемонстрированное rlibby и мистером Пауэрсом, тривиально, поскольку биты просто интерпретируются по-разному. Однако этот метод может быть полезен в нескольких сценариях, когда вы пытаетесь возиться с двоичными данными. Существует несколько полезных нестандартных приемов, таких как те, которые описаны здесь, которые основаны на использовании представления float в соответствии с IEEE 754; возможно, где-то по ходу дела этот метод может пригодиться, когда возникнет необходимость в переводе между целочисленными представлениями битов и представлениями битов с плавающей запятой.