Здравствуйте, LaptevVV, Вы писали:
LVV>Как реализована арифметика c long double в gcc ? LVV>Размер пишет 16 байт, но в интел такого аппаратного размера нет.
Если ты про long double, то не знаю
Если про __float128, то эмуляция, причём в десятки раз медленнее нативных типов
Эта проблема присуща не только long double.
Каждый компилятор даже на одной платформе может использовать разные размеры для примитивных типов.
Например, wchar_t 4 байта в GCC но 2 байта в MSVC.
А может быть, что и long double всего 8 байт в MSVC.
Или ещё упрощенней 32 битный компилятор с размеров указателя 32 бит.
Резьмирая, если вы хотите записать в файл прямо из памяти и также читать, то тут надо хорошо заранее продумать кто будет читать и кто писать.
А лучше всего сериализовать так, чтобы не нужно было думать о таких нюансах.
Здравствуйте, _NN_, Вы писали:
_NN>Эта проблема присуща не только long double. _NN>Каждый компилятор даже на одной платформе может использовать разные размеры для примитивных типов. _NN>Например, wchar_t 4 байта в GCC но 2 байта в MSVC. _NN>А может быть, что и long double всего 8 байт в MSVC. _NN>Или ещё упрощенней 32 битный компилятор с размеров указателя 32 бит.
Есть всякие std::int/uintXX_t.
wchar обычно в двоичном виде не читают, особенно линуксовый 4х-байтный, там это никто так не хранит
С целыми это всегда можно настроить тайпдефами
_NN>Резьмирая, если вы хотите записать в файл прямо из памяти и также читать, то тут надо хорошо заранее продумать кто будет читать и кто писать. _NN>А лучше всего сериализовать так, чтобы не нужно было думать о таких нюансах.
Конечно, лучше всего сдялат сразу без ошибок, кто бы спорил
Здравствуйте, Marty, Вы писали:
M>Есть всякие std::int/uintXX_t.
Ну дык, это ж нужно еще не забывать при сериализации/десериализации делать доп. преобразования. Потому как в объектных моделях, помимо этих типов, в полный рост используются всякие int, long, size_t и т.п. У нас на протяжении многих лет, пока поддерживали 32-битные конфигурации (одновременно с 64-битными) это было прямо болячкой. Хоть и знали все об этом, но, как какое-нибудь расширение модели, так обязательно кто-нибудь прощелкает этот момент.
--
Не можешь достичь желаемого — пожелай достигнутого.
_NN>Каждый компилятор даже на одной платформе может использовать разные размеры для примитивных типов. _NN>Например, wchar_t 4 байта в GCC но 2 байта в MSVC. _NN>А может быть, что и long double всего 8 байт в MSVC.
Совершенно верно.
Именно так у них и сделано с незапямятных времен.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Marty, Вы писали:
M>Здравствуйте, _NN_, Вы писали:
_NN>>Эта проблема присуща не только long double. _NN>>Каждый компилятор даже на одной платформе может использовать разные размеры для примитивных типов. _NN>>Например, wchar_t 4 байта в GCC но 2 байта в MSVC. _NN>>А может быть, что и long double всего 8 байт в MSVC. _NN>>Или ещё упрощенней 32 битный компилятор с размеров указателя 32 бит.
M>Есть всякие std::int/uintXX_t. M>wchar обычно в двоичном виде не читают, особенно линуксовый 4х-байтный, там это никто так не хранит M>С целыми это всегда можно настроить тайпдефами
_NN>>Резьмирая, если вы хотите записать в файл прямо из памяти и также читать, то тут надо хорошо заранее продумать кто будет читать и кто писать. _NN>>А лучше всего сериализовать так, чтобы не нужно было думать о таких нюансах.
M>Конечно, лучше всего сдялат сразу без ошибок, кто бы спорил
А что мешает взять простое готовое решение, скажем Protobuf, а не создавать своё полуработающее поделие.
Здравствуйте, Marty, Вы писали:
M>Здравствуйте, andrey.desman, Вы писали:
M>>>Ну, то есть, конечно можно, но тогда уже использовать sizeof(long double) не получится, надо магическую константу 10 использовать. И, видимо, структуру, где есть long double, одним махом не считать.
AD>>Почему? Что там в паддинге пофиг вообще. Как читать зависит исключительно от формата, 10 там байт или 16.
M>Не понял. Записали компилятором, у которого нет паддинга. Читаем компилятором с паддингом. Как я понимаю, какие опции pragma pack не используй, а в структуре это поле всегда 16 байт будет. Итого — структуру целиком не прочитать, только поля по отдельности. Ну и когда по отдельности long double читаешь, нельзя использовать sizeof(long double), а надо константу 10 использовать
Следующим открытием для вас будут понятия low endian/big endian. Лучше берите готовый сериализатор.
Здравствуйте, Marty, Вы писали:
M>Здравствуйте, _NN_, Вы писали:
_NN>>А что мешает взять простое готовое решение, скажем Protobuf, а не создавать своё полуработающее поделие.
M>Потому что в 90% случаев данные приходят и уходят от/в сторонный софт
А как этот сторонний софт решил проблему сериализации?
Вряд ли записывает данные которые невозможно прочитать будет на другой платформе.
Здравствуйте, _NN_, Вы писали:
M>>Потому что в 90% случаев данные приходят и уходят от/в сторонный софт
_NN>А как этот сторонний софт решил проблему сериализации? _NN>Вряд ли записывает данные которые невозможно прочитать будет на другой платформе.
Сериализовали тупо структурами. Просто компилятор был другой. Вот тебе простой пример
Здравствуйте, Marty, Вы писали:
M>Здравствуйте, _NN_, Вы писали:
M>>>Потому что в 90% случаев данные приходят и уходят от/в сторонный софт
_NN>>А как этот сторонний софт решил проблему сериализации? _NN>>Вряд ли записывает данные которые невозможно прочитать будет на другой платформе.
M>Сериализовали тупо структурами. Просто компилятор был другой. Вот тебе простой пример
В таком случае это конечно боль.
Надо в своём коде определить всё в точности как в другом.
Даже при одном компиляторе с разным порядком заголовочных файлов и разных флагов можно получить неправильную сериализацию.
Здравствуйте, SaZ, Вы писали:
SaZ>Следующим открытием для вас будут понятия low endian/big endian. Лучше берите готовый сериализатор.
Ага. Только big endian мертв на всех популярных десктопных и серверных платформах если мы про передачу файлов говорим. Даже IBM Power на их собственных процессорах и ОС перешли на little endian.
У Лаптева контекста кроме x86 не бывает (покамест)
А на POWER много хитрого есть, даже десятичная плавучка в железе.
_>И в intel x64 смешивать использование FPU, SSE и AVX не благославляется. При это 80bit регистры FPU чуть ли не depricated. Прямо большими буквами написано или то или другое иначе пи%&ец.
Тем не менее их тоже лечат. Например, примерно с 2008 стали лечить старые проблемы с непредсказуемо большим временем работы с денормализованными. Видимо, кто-то из крупных клиентов додавил.
Здравствуйте, LaptevVV, Вы писали:
LVV>Но насколько они реализованы в железе ?
А зачем обязательно в железе-то? В железе есть хотя бы float и все остальные операции
можно свести к нему. Ну и что, что в 10 раз медленее. Зачем вообще long double -- ещё вопрос.
Числа с плавающей точкой затем и придуманы, чтоб не нужны были очень длинные целочисленные.
Здравствуйте, fk0, Вы писали:
LVV>>Но насколько они реализованы в железе ?
fk0> А зачем обязательно в железе-то? В железе есть хотя бы float и все остальные операции fk0>можно свести к нему. Ну и что, что в 10 раз медленее. Зачем вообще long double -- ещё вопрос.
Если вы уж хотите эмулировать double, например, на float... легче на целых эмулировать.
fk0>Числа с плавающей точкой затем и придуманы, чтоб не нужны были очень длинные целочисленные.
Здравствуйте, LaptevVV, Вы писали:
LVV>Еще в i386 проблема выравнивания как-то была сильно сглажена. LVV>И вообще-то размер параграфа был еще в 16-битной адресации равен 16 байтам.
В SSE/AVX часть команд толерантно относятся к выравниванию, а часть прям требуют выравнивание на размер соответствующего регистра (т.е., 128/256/512 бит, в зависимости от команды).
Здравствуйте, Marty, Вы писали:
M>Получается, из двоичного файла я не смогу прочитать long double в gcc простым memcpy sizeof(long double)?
Не надо так вообще делать, оставлять чтение-запись в файл на усмотрение компилятора. Чиселки в файле должны в каком-то стандарте быть (IEEE 754 с выбранной тобой, а не компилятором, битностью и byte ordering — хороший вариант), но никто тебе не обещал, что в памяти на хосте они у тебя будут в таком же виде.