Russian Qt Forum

Qt => Общие вопросы => Тема начата: romank от Апрель 19, 2011, 12:34



Название: Float on 64-bit
Отправлено: romank от Апрель 19, 2011, 12:34
Добрый день.
Подскажите как создать float тип размером гарантированно 4 байт на 64 битной машине?
Проблема такая - надо прочитать бинарный файл, где числа представлены как 4 байтные float числа. На win32 проблем нет (использую QDataStream >> (float)), но на 64 битах sizeof(float)=8 что подобрать под 4 байта не могу найти.


Название: Re: Float on 64-bit
Отправлено: Пантер от Апрель 19, 2011, 12:37
Все уже сделано:
qint8
qint16
qint32
qint64


Название: Re: Float on 64-bit
Отправлено: zenden от Апрель 19, 2011, 12:43
romank
кто вас так жестоко обманул?
sizeof(float)==4 как в win32 так и в win64

По стандарту IEEE 754  он имеет размер 32 бита

Вот кстати таблица сравнения платформ, ни слова про float и double.
Все интегральные типы в Win64 (не связанные с указателями) имеют такой же размер, как и в Win32.

(http://habreffect.ru/files/b40/46ab24d4b/screenshot_2011-04-19_001.png)
(Linux  - LP64, Windows - LLP64)


Название: Re: Float on 64-bit
Отправлено: Igors от Апрель 19, 2011, 13:11
romank
кто вас так жестоко обманул?
sizeof(float)==4 как в win32 так и в win64
Добавлю что так же и на Mac платформе.


Название: Re: Float on 64-bit
Отправлено: romank от Апрель 19, 2011, 13:14
Да, точно 4. Неверно диагностировал проблему. Не могу понять.

Код
C++ (Qt)
...
   QDataStream in;
...
   float qfloat;
   inline float readSingle()
   {
       in >> qfloat;
       return qfloat;
   }
 
   qint32 qint;
   inline int readInt32()
   {
       in >> qint;
       return qint;
   }
 

Почему они читают разное количество байтов?
Хотя сколько точно читает readSingle() я не замерил, но точно не по четыре байта.


Название: Re: Float on 64-bit
Отправлено: romank от Апрель 19, 2011, 13:19
Проверил. in >> (float) читает 8 байт.


Название: Re: Float on 64-bit
Отправлено: Пантер от Апрель 19, 2011, 13:22
На сколько я помню, размер float зависит от платформы. Так же как и int.


Название: Re: Float on 64-bit
Отправлено: romank от Апрель 19, 2011, 13:28
Вопрос тогда не к float, а к DataStream.
Если sizeof(float) = 4, почему in >> (float) читает 8, и как прочесть 4.


Название: Re: Float on 64-bit
Отправлено: romank от Апрель 19, 2011, 13:30
А вот и ответ:

void QDataStream::setFloatingPointPrecision ( FloatingPointPrecision precision )
The default is DoublePrecision.


Название: Re: Float on 64-bit
Отправлено: Пантер от Апрель 19, 2011, 13:33
А, точно, я когда-то на такое тоже напоролся. :)


Название: Re: Float on 64-bit
Отправлено: Sancho_s_rancho от Апрель 19, 2011, 13:44
Я тоже вставлю свои 5 копеек.
Люби и знай свой язык. Понимание приходит через фтыкание в строчки стандарта ISO С++. Все иное от лукавого.
Согласно IEEE 754 (IEC 559) float - 4 байта и double - 8 байт. Но ежели вы прочли предидущее предложение, то знаете, что IEEE 754 (IEC 559) не есть стандарт приплюснутого си. С++ может положить болт на Standard for Floating-Point Arithmetic (IEEE 754). Как жить дальше? Используйте limits : numeric_limits. Кстати там есть такая штука: static const bool is_iec559.


Название: Re: Float on 64-bit
Отправлено: romank от Апрель 19, 2011, 13:49
Я с трудом понимаю о чем вы. Проблема была в DataStream, который "по умолчанию" кушает float двойного размера.


Название: Re: Float on 64-bit
Отправлено: Igors от Апрель 19, 2011, 13:58
Я с трудом понимаю о чем вы. Проблема была в DataStream, который "по умолчанию" кушает float двойного размера.
Ну и что тут плохого? Размер данных на диске не обязан совпадать с их размером в памяти


Название: Re: Float on 64-bit
Отправлено: Sancho_s_rancho от Апрель 19, 2011, 14:01
Я с трудом понимаю о чем вы. Проблема была в DataStream, который "по умолчанию" кушает float двойного размера.
Это ваши слова?
Цитировать
Подскажите как создать float тип размером гарантированно 4 байт на 64 битной машине?
На что вам было сказано, что каким быть float решает компилятор, а не вы. Все остальное пользовательские типы.


Название: Re: Float on 64-bit
Отправлено: GreatSnake от Апрель 19, 2011, 14:26
Цитировать
Размер данных на диске не обязан совпадать с их размером в памяти
Это как это  ???


Название: Re: Float on 64-bit
Отправлено: Igors от Апрель 19, 2011, 14:43
Цитировать
Размер данных на диске не обязан совпадать с их размером в памяти
Это как это  ???
Как хотим - так и храним. Захотели float сохранили как double - или наоборот. Частенько храню bool как int. Порядок байтов тоже может быть разный (хотя большая ендиана уже история)

Люби и знай свой язык. Понимание приходит через фтыкание в строчки стандарта ISO С++. Все иное от лукавого.
Ой как нравится разговаривать "в повелительном наклонении" :) Значит, я так понимаю, Вы-то уж свой язык любите и знаете. Тогда поясните мне пожалуйста: кто быстрее работает: float или double ?
Спасибо 


Название: Re: Float on 64-bit
Отправлено: romank от Апрель 19, 2011, 14:45
Зачем вы ещё пишете в эту тему?
Решение найдено и решение не касается стандарта ISO, компилятора и, как это часто бывает, собственно темы.
Пять копеек с повелительными наклонениями засуньте обратно и перечитывайте _полностью_ обсуждение.

P.S. У меня бл большая ендиана!


Название: Re: Float on 64-bit
Отправлено: maxxant от Апрель 19, 2011, 14:50
но на 64 битах sizeof(float)=8 что подобрать под 4 байта не могу найти.

начиная с версии Qt 4.6 сериализация float идет в 8 байт по умолчанию. Nokia писали об этом в Labs.

Код:
QDataStream &QDataStream::operator>>(float &f)
{    
    if (version() >= QDataStream::Qt_4_6
        && floatingPointPrecision() == QDataStream::DoublePrecision) {
        double d;
        *this >> d;
        f = d;
        return *this;
    }

    f = 0.0f;
    CHECK_STREAM_PRECOND(*this)
    if (dev->read((char *)&f, 4) != 4) {
        f = 0.0f;
        setStatus(ReadPastEnd);
    } else {
        if (!noswap) {
            union {
                float val1;
                quint32 val2;
            } x;
            x.val2 = qbswap(*reinterpret_cast<quint32 *>(&f));
            f = x.val1;
        }
    }
    return *this;
}

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

Код:
  QDataStream stream(&data, QIODevice::WriteOnly);
  stream.setVersion(QDataStream::Qt_4_5);
  ...


Название: Re: Float on 64-bit
Отправлено: romank от Апрель 19, 2011, 14:54
Спасибо за грамотный ответ.