| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Преобразование последовательности байтов во float |
| Автор: Hukuma 17.4.2009, 14:55 |
| Здравствуйте! Тема похожа на эту http://forum.vingrad.ru/topic-64014.html Исходные данные - есть последовательность из 4ых байтов - это части числа в формате float. Т.е. знак экспоненты,экспонент, мантисса. нужно из этих 4ых байтов собрать число в формате float.. я понял, что это можно сделать, использую побитовые операции, это как описано в теме, на которую я сослался.. а вопрос такой - а нельзя это сделать проще? Очень туго въезжаю в формат IEEE754. Или нет других путей? |
| Автор: UniBomb 17.4.2009, 15:04 | ||
как то так.... |
| Автор: Hukuma 17.4.2009, 15:12 |
| Unibomb,спасибо большое..интересный вариант, понравилс очень, сейчас попробую |
| Автор: InvalidProperty 17.4.2009, 15:12 |
| только, наверное, порядок байт в слове еще нужно учитывать |
| Автор: UniBomb 17.4.2009, 16:22 |
А теперь спроси у компилятора (у лбого), что он думает по поводу этой строчки. Компилятор ответит, что результатом будет содержимое этой переменной (data[0]), пробразованное во float. А копировать ничего не придётся, если массив data объявить в составе объединения. |
| Автор: InvalidProperty 17.4.2009, 16:29 | ||
это истина, ибо union это не какой-то там struct. Его поля одинаковой длины ссылаются на одно и то же значение |
| Автор: GoldFinch 17.4.2009, 16:53 |
| UniBomb, ок, return *(float*)data; |
| Автор: Rififi 17.4.2009, 23:00 |
| GoldFinch, Жесть какая, 4 байта копировать в 4 байта циклом %) return (float)data[0]; лучше жесть, чем неработающая кривизна ЖлолЖ |
| Автор: zim22 18.4.2009, 07:47 | ||
|
| Автор: GoldFinch 18.4.2009, 10:15 |
| Rififi, объясни, зачем читать через пост, а не все посты подряд? |
| Автор: mrbrooks 20.4.2009, 08:15 |
| zim22, может все таки лучше через reinterpret_cast имхо. по сабжу конечно объединения хороши, но и memcpy тоже не плохо. |
| Автор: Rickert 20.4.2009, 08:28 |
| А memcpy никто не пробовал? |
| Автор: zim22 20.4.2009, 08:29 |
я сначала сделал вариант с reinterpret_cast, но потом вспомнил, что это опасные преобразования. а static_cast - безопаснее. тем более с ним работает тоже |
| Автор: mrbrooks 20.4.2009, 08:50 | ||
опасные - для классов, для базовых типов - думаю не очень если так - то и славно - еще одно решение в копилку. |
| Автор: Rickert 20.4.2009, 09:58 | ||
Ау, извращенцы!
Какие Reinterpret'ы и доп. классы, не сходите с ума |
| Автор: mrbrooks 20.4.2009, 10:33 | ||
сам извращенец. если внимательно почитаешь посты - то memcpy уже предложили, до такого гениального парня, как ты. |
| Автор: Hukuma 20.4.2009, 10:55 |
| Огромное всем спасибо за участие! |
| Автор: Rickert 20.4.2009, 11:11 |
| mrbrooks, слеподыр! Не углядел! |
| Автор: GoldFinch 20.4.2009, 11:40 |
| Rickert, копировать 4 байта memcpy() - как минимум глупо |
| Автор: UniBomb 20.4.2009, 11:47 |
| эх, тема была бы ещё интересней, если бы тут не занимались членомерством, а предлагали бы новые вариаты фразой "а ещё можно так", вместо "так делат глупо - надо вот так".... |
| Автор: Lazin 20.4.2009, 12:07 | ||||
а можно вот так:
|
| Автор: zim22 20.4.2009, 12:50 |
нельзя. я уже так пробовал |
| Автор: mrbrooks 20.4.2009, 13:14 |
может он не в студии делал? |
| Автор: zim22 20.4.2009, 13:25 |
в Code::blocks тоже не работает. Вы сами подумайте, как оно может работать!? |
| Автор: GoldFinch 20.4.2009, 13:28 |
нормально может работать data, data + 4, &dest - указатели, должны неявно преобразовываться в итераторы |
| Автор: Lazin 20.4.2009, 13:33 |
| не должно работать, так как у указателей разный тип, нужно &dest привести к char |
| Автор: zim22 20.4.2009, 13:37 | ||
нет. оно не будет нормально работать. оно будет криво работать. теперь работает.
|
| Автор: UnrealMan 20.4.2009, 13:38 | ||
Факт есть факт: самый простой и правильный способ - использование memcpy. Финт с объединением - это ненужное усложнение кода, а касты к float* не соблюдают выравнивание. |
| Автор: mrbrooks 20.4.2009, 13:47 |
в чем усложнение то? в написание union. По мне так использование анонимного объединения ничем не хуже memcpy. |
| Автор: UnrealMan 20.4.2009, 14:03 | ||
А данные в объединении с воздуха берутся? Копировать байты по-любому приходится - либо циклом, как предложено выше, либо тем же memcpy, либо ещё чем-то аналогичным. Так зачем копировать данные в какое-то там объединение, если можно скопировать их сразу в переменную типа float? |
| Автор: mrbrooks 20.4.2009, 14:09 | ||
с этим согласный |
| Автор: GoldFinch 20.4.2009, 14:21 | ||
инструкцией mov в 32 разрядных системах 4байтовые переменные должны копироваться 1 инструкцией mov (или m2m) использование циклов, функций библиотек языка или апи для копирования 4 байт это бред %) |
| Автор: vinter 20.4.2009, 14:31 |
| GoldFinch, в С\С++ нет инструкции mov, там вообще нет никаких инструкций |
| Автор: Irdis 20.4.2009, 18:18 | ||
я тоже умею
|
| Автор: zim22 20.4.2009, 18:33 | ||
тогда уж так. хотя как уже выяснилось в этой теме - вариант с memcpy - оптимальный.
|
| Автор: GoldFinch 20.4.2009, 18:54 |
| zim22, в каком месте он оптимальный? по скорости? по объему кода? про числу строчек исходника? да ниразу |
| Автор: zim22 20.4.2009, 19:10 |
| GoldFinch, предлагайте тогда альтернативные варианты. не словом, а делом. |
| Автор: mes 20.4.2009, 19:23 | ||||||
a он разве не предложил ? и даже обосновал, почему этот вариант ему кажется самым привлекательным:
ну и не забыл охарактеризовать другие подходы :
Как видите и словом и делом |
| Автор: zim22 20.4.2009, 20:03 | ||||
Поставьте бряк на строке с memcpy и войдите внуть функции. Вас перекинет в файл memcpy.asm. Это же ваш любимый ассемблер! Ваши любимые команды! Мечты сбываются |
| Автор: vinter 20.4.2009, 20:35 | ||
круто, а когда надо будет строку с цифрами выражение парсить будем lua предлагать? |
| Автор: UnrealMan 20.4.2009, 21:53 | ||
Это не самый лучший способ увидеть результат оптимизации компилятора
Так что товарищи рукоблуды, занимающиеся оптимизацией посредством ассемблерных вставок, могут идти в баню. |
| Автор: GoldFinch 20.4.2009, 22:27 | ||
для этого используют push\pop, твой оптимизатор гуан* Добавлено через 6 минут и 13 секунд алсо такой код должен инлайниться, а идея использования отдельный функции для копирования 4 байт в 4 байта ничем не лучше чем если бы memcpy была отдельной функцией |
| Автор: mes 20.4.2009, 22:46 | ||
сорри, но не уловил смысла, нельзя ли иначе (попроще) изъясниться ? |
| Автор: UnrealMan 21.4.2009, 01:44 |
Смысл примерно следующий: операции со стеком push и pop выполняются типа быстрее, чем простые mov с дополнительным регистром, только вот тупые разработчики компиляторов в Intel и Microsoft об этом не знают. А ещё mov (в отличие от push и pop) занимает страшно много места (вынуждая несчастных пользователей покупать терабайтные винчестеры для хранения полученных таким варварским способом исполнительных файлов). Короче, продемонстрированная оптимизация - полный песец, и, поэтому, ясень пень, тут нужно скорей хвататься за ассемблер, чтобы на нём родить самый оптимальный по своему количеству, скорости и переносимости исходный код. Добавлено @ 01:45 Что касается приведённого мной кода, то он специально подобран так, чтобы всем сразу было видно, во что компилятор может превратить memcpy. Это не было предложением использовать на практике именно такой код. |
| Автор: Rickert 21.4.2009, 02:31 |
А вот теперь я слушаю оргаменты. |
| Автор: xvr 21.4.2009, 10:54 | ||||
Рукоблудием надо меньше заниматься - инструкции PUSH/POP выполняются ВДВОЕ/ВТРОЕ медленне, чем MOV Источник - Intel 64 and IA-32 Architectures Optimization reference manual (248966-016), таблица C-12 |