Разложение с плавающей запятой двойной точности на байты с использованием объединения в C

#c #types #unions

#c #типы #объединения

Вопрос:

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

У меня определено объединение, которое выглядит следующим образом:

 union meh {
    double foo;
    char bar[8];
};
  

Затем я делаю что-то вроде этого:

 meh firstOne;
meh otherOne;

char blah[8];
double whatever;

firstOne.foo = 0.12345;
blah = firstOne.bar;

otherOne.bar = blah;
whatever = otherOne.foo;
  

И что я пытаюсь выяснить: будет ли ‘whatever’ равно 0.12345?

(Просто для уточнения — sizeof(double) на моей машине 8 байт — не знаю, везде ли это так.)

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

Большое спасибо за ваше время и помощь — это высоко ценится!

РЕДАКТИРОВАТЬ: Судя по комментариям, похоже, что я идиот и

 blah = firstOne.bar;
  

должно быть

 strcpy(blah, firstOne.bar);
  

вместо этого. Извините за это!

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

1. «Я знаю, что очевидным решением было бы просто запустить его любым способом самостоятельно, но, к сожалению, я не в состоянии это сделать». Почему бы и нет? Нетрудно загрузить gcc или Visual C (или clang или …) и использовать их.

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

3. Это потрясающе, я обязательно попробую это в будущем. Спасибо!

Ответ №1:

Да, whatever будет 0.12345 , если вы исправите ошибки. Если у вас есть время протестировать это самостоятельно, вот несколько примеров кода без искажений:

 #include <assert.h>
#include <string.h>

// use more descriptive names
union d2b
{
    double value;
    char bytes[sizeof (double)]; // avoid magic numbers
};

int main(void)
{
    const double TEST_VALUE = 0.12345;

    // don't omit the union keyword in C (not necessary in C  )
    union d2b src, dest;
    src.value = TEST_VALUE;

    // arrays are not lvalues, ie you can't assign to array variables
    // use memcpy() instead of strcpy() for arbitrary binary data
    memcpy(dest.bytes, src.bytes, sizeof dest.bytes);

    // assert, the foundation of test-driven development in C
    assert(dest.value == TEST_VALUE);

    return 0;
}
  

Ответ №2:

Я не думаю, что blah = firstOne.bar будет компилироваться — вы пытаетесь скопировать весь массив, чего бы ему не хотелось, чтобы вы делали. Вам нужно было бы использовать memcpy для копирования всех данных массива. Но, говоря, что вы это сделали (в обоих местах вы пытаетесь скопировать массив char), я бы сказал, что whatever это в конечном итоге равно 0.12345.

Ответ №3:

Сделайте так, чтобы:

 union meh {
    double foo;
    char bar[ sizeof(double) ];
};