Как реализована арифметика c long double в gcc ?
Размер пишет 16 байт, но в интел такого аппаратного размера нет.
Или в современных уже есть ?
Регистры сопроцессора были по 80 бит.
Но последняя версия стандарта ieee-754 включает 128-битные дробные
Кто знает, оно уже в аппаратуре есть или нет ?
Версия gcc jn 8.1 до 11.0
С++17 по любому есть (хотя в 8.1 не совсем полный).
Здравствуйте, LaptevVV, Вы писали:
LVV>Как реализована арифметика c long double в gcc ? LVV>Размер пишет 16 байт, но в интел такого аппаратного размера нет.
LVV>>Как реализована арифметика c long double в gcc ? LVV>>Размер пишет 16 байт, но в интел такого аппаратного размера нет. AD>Выравнивание.
И что ?
Еще в i386 проблема выравнивания как-то была сильно сглажена.
И вообще-то размер параграфа был еще в 16-битной адресации равен 16 байтам.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
AD>>Выравнивание. LVV>И что ?
Что и что? long double занимает 16 байт, из них используется 10.
LVV>Еще в i386 проблема выравнивания как-то была сильно сглажена. LVV>И вообще-то размер параграфа был еще в 16-битной адресации равен 16 байтам.
AD>>>Выравнивание. LVV>>И что ? AD>Что и что? long double занимает 16 байт, из них используется 10.
1. Это я и хотел услышать
Но выравнивание здесь причем ?
Тут происходит усечение мантиссы. LVV>>Еще в i386 проблема выравнивания как-то была сильно сглажена. LVV>>И вообще-то размер параграфа был еще в 16-битной адресации равен 16 байтам. AD>Чо?
Это к 1 строке или к последней.
Если к последней, то параграф — это 16 байт.
Сегментный регистр, когда участвовал в вычислении адреса, сдвигался на 4 бита влево (становился 20 бит) и таким образом выравнивался на границу параграфа.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
LVV>>Как реализована арифметика c long double в gcc ? PD>Написать программу из 3 строчек, откомпилировать в режиме создания ассемблерного текста и посмотреть ?
Да, спасибо. Чего-то в голову как-то не пришло — редко до до ассемблера спускаться приходится.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>Как реализована арифметика c long double в gcc ? LVV>Размер пишет 16 байт, но в интел такого аппаратного размера нет. LVV>Или в современных уже есть ?
В документации, как в той Греции, есть всё:
'-m96bit-long-double'
'-m128bit-long-double'
These switches control the size of 'long double' type. The x86-32
application binary interface specifies the size to be 96 bits, so
'-m96bit-long-double' is the default in 32-bit mode.
Modern architectures (Pentium and newer) prefer 'long double' to be
aligned to an 8- or 16-byte boundary. In arrays or structures
conforming to the ABI, this is not possible. So specifying
'-m128bit-long-double' aligns 'long double' to a 16-byte boundary
by padding the 'long double' with an additional 32-bit zero.
In the x86-64 compiler, '-m128bit-long-double' is the default
choice as its ABI specifies that 'long double' is aligned on
16-byte boundary.
Notice that neither of these options enable any extra precision
over the x87 standard of 80 bits for a 'long double'.
В стандарте есть рекомендации на формат для любого размера числа, кратного 32 битам. Но 256 там явно не выделяется — это инициатива "на местах" от авторов википедии.
LVV>Но насколько они реализованы в железе ?
Здравствуйте, LaptevVV, Вы писали:
AD>>Что и что? long double занимает 16 байт, из них используется 10. LVV>1. Это я и хотел услышать LVV>Но выравнивание здесь причем ?
Чтобы ровно и четко все было, а не эти ваши 10 байт, которые и в массив не положишь.
LVV>Тут происходит усечение мантиссы.
А экспоненты нет? Чтобы что-то усеч, надо чтобы это что-то было. А его не было.
Ты смотришь на это как на то, что раз 16 байт, значит все они под значение использоваться должны. Тогда как по факту поддержали 80 битные числа, а потом добили их до приемлемого выравнивания в 128 бит.
И в intel x64 смешивать использование FPU, SSE и AVX не благославляется. При это 80bit регистры FPU чуть ли не depricated. Прямо большими буквами написано или то или другое иначе пи%&ец.
Здравствуйте, andrey.desman, Вы писали:
AD>Ты смотришь на это как на то, что раз 16 байт, значит все они под значение использоваться должны. Тогда как по факту поддержали 80 битные числа, а потом добили их до приемлемого выравнивания в 128 бит.
Получается, из двоичного файла я не смогу прочитать long double в gcc простым memcpy sizeof(long double)?
Здравствуйте, andrey.desman, Вы писали:
M>>Получается, из двоичного файла я не смогу прочитать long double в gcc простым memcpy sizeof(long double)?
AD>Почему нет? Если сам же и писал.
Ну, то есть, конечно можно, но тогда уже использовать sizeof(long double) не получится, надо магическую константу 10 использовать. И, видимо, структуру, где есть long double, одним махом не считать.
Когда сам писал, то всё просто, но двоичные форматы обычно даются нам свыше
Здравствуйте, Marty, Вы писали:
M>Ну, то есть, конечно можно, но тогда уже использовать sizeof(long double) не получится, надо магическую константу 10 использовать. И, видимо, структуру, где есть long double, одним махом не считать.
Почему? Что там в паддинге пофиг вообще. Как читать зависит исключительно от формата, 10 там байт или 16.
Здравствуйте, Marty, Вы писали:
M>Ну, то есть, конечно можно, но тогда уже использовать sizeof(long double) не получится, надо магическую константу 10 использовать. И, видимо, структуру, где есть long double, одним махом не считать.
Всё же проще записывать и считывать по 16 байт — особенно, если это массив, а не единичное значение. То, что из них значащих 80 бит — никак не помешает (если не заморачиваться упаковкой по размеру).
А вот разбивать массив long double на 10-байтные отрезки и сериализовать это — геморрой на ровном месте без практической пользы.
Здравствуйте, andrey.desman, Вы писали:
M>>Ну, то есть, конечно можно, но тогда уже использовать sizeof(long double) не получится, надо магическую константу 10 использовать. И, видимо, структуру, где есть long double, одним махом не считать.
AD>Почему? Что там в паддинге пофиг вообще. Как читать зависит исключительно от формата, 10 там байт или 16.
Не понял. Записали компилятором, у которого нет паддинга. Читаем компилятором с паддингом. Как я понимаю, какие опции pragma pack не используй, а в структуре это поле всегда 16 байт будет. Итого — структуру целиком не прочитать, только поля по отдельности. Ну и когда по отдельности long double читаешь, нельзя использовать sizeof(long double), а надо константу 10 использовать
Здравствуйте, flаt, Вы писали:
F>Всё же проще записывать и считывать по 16 байт — особенно, если это массив, а не единичное значение. То, что из них значащих 80 бит — никак не помешает (если не заморачиваться упаковкой по размеру).
F>А вот разбивать массив long double на 10-байтные отрезки и сериализовать это — геморрой на ровном месте без практической пользы.
В памяти — безусловно, там размер пофигу. А при обмене двоичными данными — по другому никак не получится, другие компиляторы имеют свой размер long double
Здравствуйте, Marty, Вы писали:
M>Не понял. Записали компилятором, у которого нет паддинга. Читаем компилятором с паддингом. Как я понимаю, какие опции pragma pack не используй, а в структуре это поле всегда 16 байт будет. Итого — структуру целиком не прочитать, только поля по отдельности. Ну и когда по отдельности long double читаешь, нельзя использовать sizeof(long double), а надо константу 10 использовать
Я б так сериализацию не делал, но если уж так хочется, то union {long double; char padding[16];} stuctMember;
Здравствуйте, andrey.desman, Вы писали:
M>>Не понял. Записали компилятором, у которого нет паддинга. Читаем компилятором с паддингом. Как я понимаю, какие опции pragma pack не используй, а в структуре это поле всегда 16 байт будет. Итого — структуру целиком не прочитать, только поля по отдельности. Ну и когда по отдельности long double читаешь, нельзя использовать sizeof(long double), а надо константу 10 использовать
AD>Я б так сериализацию не делал, но если уж так хочется, то union {long double; char padding[16];} stuctMember;
И как это решит проблему с данными, которые формирует кто-то другой?
Здравствуйте, Marty, Вы писали:
M>И как это решит проблему с данными, которые формирует кто-то другой?
По-хорошему, и сериализацию, и десериализацию должна выполнять одна и та же софтина, которая и обеспечивает портабельность, версионность, обратную совместимось и пр. (в том объеме, в котором это требуется).
--
Не можешь достичь желаемого — пожелай достигнутого.