Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Susenin от Октябрь 04, 2013, 23:45



Название: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: Susenin от Октябрь 04, 2013, 23:45
Здравствуйте.
Как средствами Qt преобразовать unsigned int во float c сохранением двоичного представления данных? Т.е из unsigned int со значением 1078984704 сделать float значением 3.25.
Это можно сделать с помощью union, но вдруг есть нативный Qt способ?

Может лыжи не едут, но у меня не получилось ни с помощью QVariant, ни с помощью QDataStream (что очень странно).


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: LisandreL от Октябрь 05, 2013, 07:10
Код
C++ (Qt)
   quint32 i = 1078984704;
   float f;
   memcpy(&f, &i, sizeof(float));


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: Old от Октябрь 05, 2013, 08:47
Это можно сделать с помощью union, но вдруг есть нативный Qt способ?
union нативный способ C (и по наследству C++), нет никакой необходимости в каких-то способах Qt.


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: Igors от Октябрь 05, 2013, 09:03
union лучше но можно и так
Код
C++ (Qt)
float f = *(float *) &i;
И повеяло чем-то родным  :) Кстати ноль одинаков, что бывает удобно


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: Old от Октябрь 05, 2013, 09:37
Код
C++ (Qt)
float f = *(float *) &i;
И это же на C++
Код
C++ (Qt)
float &f = reinterpret_cast<float&>( i );


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: LisandreL от Октябрь 05, 2013, 10:56
Мой вариант без варнингов. :P


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: sergek от Октябрь 05, 2013, 11:09
Код
C++ (Qt)
float f = *(float *) &i;
Код
C++ (Qt)
memcpy(&f, &i, sizeof(float));
Есть вероятность, что на платформах, где sizeof(int) < sizeof(float), будет "погода в Африке".


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: Susenin от Октябрь 05, 2013, 11:25
Всем спасибо!
reinterpret_cast (как для меня оказывается  :) ) как раз и предназначен для сохранения bit pattern.
А то, что sizeof(float) может быть != sizeof(unsigned int), как обычно, пусть заботятся следующие поколения поддерживающим мою программу.


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: Old от Октябрь 05, 2013, 11:32
А то, что sizeof(float) может быть != sizeof(unsigned int), как обычно, пусть заботятся следующие поколения поддерживающим мою программу.
Ну ыв им ассертов не забудьте наставить. :)


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: Igors от Октябрь 05, 2013, 11:58
Мой вариант без варнингов. :P
Как и все остальные (вспоминается "без холестерина" на этикетке  :))

Есть вероятность, что на платформах, где sizeof(int) < sizeof(float), будет "погода в Африке".
Явный перегиб м фобия мифической платформы. Впрочем если таковая появится, академичность не спасет.

Да и вообще, люди давно используют 2-байтовые флоты, и все хорошо


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: LisandreL от Октябрь 05, 2013, 13:39
Как и все остальные
MinGW ругается: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: Old от Октябрь 05, 2013, 13:47
MinGW ругается: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
Это на какой вариант?


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: LisandreL от Октябрь 05, 2013, 16:03
На оба варианта и reinterpret_cast и на c-style cast предупреждение одинаковое.

Что ожидаемо с промежуточным void* позволяет кастовать без предупреждений:
Код
C++ (Qt)
   quint32 i = 1078984704;
   float f;
   void* v = static_cast< void* >( &i );
   f = *static_cast< float* >( v );
Но вот стоит «сократить» запись, как опять тот же варнинг:
Код
C++ (Qt)
   quint32 i = 1078984704;
   float f;
   f = *static_cast< float* >( static_cast< void* >( &i ) );

P.S. Да, я понимаю, что писать без варнингов не самоцель.


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: Old от Октябрь 05, 2013, 16:19
На оба варианта и reinterpret_cast и на c-style cast предупреждение одинаковое.
Странно, а ключи какие используете при компиляции? И версия компилятора какая?
У меня ни звука не издает, ни с моим вариантом, ни с вашими.
g++ (GCC) 4.8.1 20130725 (prerelease)


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: sergek от Октябрь 05, 2013, 16:56
Явный перегиб м фобия мифической платформы. Впрочем если таковая появится, академичность не спасет.
Зачем оттягивать ветку идущему следом за тобой?
Кто мешает сделать примерно так:
Код:
    void* ptr = calloc(1, std::max(sizeof(int),sizeof(float)));
    memcpy(ptr, &i, sizeof(int));
    f = *(float *) ptr;


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: Old от Октябрь 05, 2013, 17:10
Кто мешает сделать примерно так:
Это union вручную. :)


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: sergek от Октябрь 05, 2013, 17:29
Это union вручную. :)
Увы, нет :( То, что обе переменные располагаются в одной области памяти, не гарантирует инициализацию незанятой памяти (а там - погода в Африке). В моем примере ключевое слово - calloc.


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: Old от Октябрь 05, 2013, 17:34
Увы, нет :( То, что обе переменные располагаются в одной области памяти, не гарантирует инициализацию незанятой памяти (а там - погода в Африке). В моем примере ключевое слово - calloc.
Так а кто мешает "занулить" юнион?
Хотите через calloc, хотите через memset.
Выделять память в куче для такой примитивной операции очень накладно.

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


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: sergek от Октябрь 05, 2013, 17:51
Так а кто мешает "занулить" юнион?
Вот! Ведь можете, когда захотите  ;)


Название: Re: Преобразовать quint32 во float сохраняя двоичное представление
Отправлено: Old от Октябрь 05, 2013, 17:56
Так а кто мешает "занулить" юнион?

Вот! Ведь можете, когда захотите  ;)
Что можете?
Я сильно сомневаюсь, что кто-то будет заниматься подобными занулениями в реальной жизни, в связи с их ненужностью.