Преобразование с плавающей точкой в ​​двоичное

Я написал программу для преобразования числа с плавающей запятой в его двоичное представление IEEE754 на C.

Любые улучшения приветствуются.

#include <stdio.h>
#include <stdlib.h>
void binary(float num) {
    int n = *(int *) &num; //Evil bit hack from Quake3 Q_sqrt function
    int size = sizeof(n) * 8; 
    char *s = malloc(1 + size); //A string which can hold 32 characters
    s[size] = '';
    int index = size - 1;
    while(index >= 0) {
        if (n & 1)
            *(s + index) = '1';
        else
            *(s + index) = '0';
        n >>= 1;
        index--;
    }
    printf("%sn", s);
    free(s);
}

int main(void) {
    float num;
    scanf("%f", &num);
    binary(num);
}

1 ответ
1

Соответствие IEEE754

Компиляторы не обязаны поддерживать десятичные дроби IEEE754. Большинство реализаций это делают, но, тем не менее, лучше проверить максимальную переносимость. Если вы используете C99 или новее, макрос __STDC_IEC_559__ определяется всякий раз, когда поддерживается IEEE754.


sizeof (число)

По аналогии, int не гарантируется, что это будет 32 бита. Компилятор гарантирует только минимальный размер 16 бит. Вы можете использовать целочисленные типы фиксированной ширины, определенные в stdint.h т.е. uint32_t или же int32_t.


Использовать size_t вместо int

Подходящий тип для sizeof выражение size_t. Как правило, любая переменная, представляющая размер или индекс, должна быть size_t.


Поскольку вы не используете s вне binary функцию, вы можете просто выделить фиксированный массив размером 33 в стеке, а не в куче, используя malloc.

static const size_t num_bits = 33;
char s[num_bits];

*(s + index) это просто причудливый способ написать s[index]. Последнее намного чище, IMO и намного проще для понимания тем, кто не знаком с арифметикой указателей.

  • Преимущество изменения использования стека нельзя недооценивать. Распределение памяти намного медленнее (даже просто накладные расходы на вызов функции), чем просто ссылка на пространство, которое компилятор выделил / оставил (затраты времени компиляции для удобства выполнения !!) .

    — г-н Р.

  • 1

    Ваша формулировка о соответствии IEEE754 немного неверна. Это стандарт C, который не требует реализации для поддержки IEEE754. Однако сами компиляторы не могут выбирать, что они реализуют, они связаны тем, что ABI платформы определяет формат float а также double должно быть. То же самое и с размером целочисленных типов.

    — Г. Сон


  • Хм, я не знал об этом, но это имеет смысл. Спасибо!

    — Риш

  • @Rish Спасибо за ответ, хотя я не понимаю, почему все компиляторы не используют представление IEEE 754 для хранения float. Если нет, то каков наиболее распространенный способ хранения чисел с плавающей запятой или двойной точности (точнее, литералов с одинарной / двойной точностью)? Кстати, я компилирую указанную выше программу на gcc, поставляемом с ubuntu LTS.

    — С—


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *