Расчет log2, союзы - PullRequest
       9

Расчет log2, союзы

0 голосов
/ 03 октября 2018

Я нашел следующий код, который вычисляет log2 из float x:

union { float f; unsigned int i; } vx = { x };
float y = vx.i;
y *= 1.0 / (1 << 23);
y = y - 126.94269504f;
return y;

Параметр объединения f инициализируется для ввода x, а затем использует i?Я не могу понять, как он использует то, что не инициализировано.А какое значение vx.i на самом деле?Спасибо.

Ответы [ 4 ]

0 голосов
/ 03 октября 2018

Не могу понять, как он использует то, что не инициализировано.

На самом деле vx.i инициализируется.Объединение будет занимать ту же область памяти.Поэтому vx.i инициализируется одновременно с инициализацией vx.f.

А какое значение vx.i на самом деле?

Чтобы получить действительное значениеvx.i вам нужно понять, как поплавок хранится в памяти.См. Отличный ответ здесь Как числа с плавающей запятой хранятся в памяти?

Из связанного ответа

Если vx.f равно 1.0, то vx.iбудет 3f800000 (в шестнадцатеричном формате)

0 голосов
/ 03 октября 2018

Союзы - это то, что происходит с того времени, когда память была дорогой.Они используются для экономии памяти.

Когда вы объявляете объединение, оно будет достаточно большим, чтобы вместить самого большого члена.Таким образом, в этом случае размер vx будет max(sizeof(f), sizeof(i)).

. Поэтому при использовании vx = {x} значение x будет занесено в память, зарезервированную для vx.Когда вы используете vx.f, то все, что находится в этой памяти, будет интерпретироваться как float, но когда вы используете vx.i, оно будет интерпретироваться как unsigned integer, но необработанные двоичные данные одинаковы.

0 голосов
/ 03 октября 2018

ключевое слово union в основном означает, что float f и unsigned int i совместно используют одну и ту же память.инициализация члена объединения f и затем чтение i в основном определяется реализацией.

В результате получается двоичное представление переменной с плавающей точкой.Затем умный кодер использует это двоичное представление и масштабирует значение, чтобы вы получили log2 входного значения.

0 голосов
/ 03 октября 2018

Ваши float и int находятся в одной и той же ячейке памяти.Таким образом, байты, занятые float, совпадают с байтами int.Но они имеют в виду нечто совершенно иное, поскольку двоичный формат float отличается от int.Таким образом, если вы присваиваете значение с плавающей точкой, оно изменит int, но его значение будет совершенно другим.

...