Здравствуйте, Vamp, Вы писали:
V>Здравствуйте, Kven, Вы писали:
K>>Есть некий файл, он заливается в битовый буффер, в файле хранятся данные разных типов K>>DWORD int CHAR и float. Нужно данные float вытащить из битового буффера отредактировать и K>>запихнуть обратно.
V>Очень просто.
V> V>
V>byte b[BUFFER_SIZE];
V>//b is initialized
V>//....
V>float *pfNum;
V>pfNum=(float *)(b+nOffset); //nOffset - offset in byte array of our number
V>*pfNum=*pfNum+2003;
V>
V>
Так будут проблемы с выравниванием. То есть, если в буфере хранится byte а потом float (nOffset нечётный), то мы получим указатель на float по нечётному адресу.
Так что извлекать нужно так:
Суть проблемы:
Есть некий файл, он заливается в битовый буффер, в файле хранятся данные разных типов
DWORD int CHAR и float. Нужно данные float вытащить из битового буффера отредактировать и
запихнуть обратно.
Здравствуйте, Kven, Вы писали:
K>Есть некий файл, он заливается в битовый буффер, в файле хранятся данные разных типов K>DWORD int CHAR и float. Нужно данные float вытащить из битового буффера отредактировать и K>запихнуть обратно.
Очень просто.
byte b[BUFFER_SIZE];
//b is initialized
//....float *pfNum;
pfNum=(float *)(b+nOffset); //nOffset - offset in byte array of our number
*pfNum=*pfNum+2003;
Здравствуйте, Vamp, Вы писали:
V>Насколько я понял условия задачи, так вообще ничего не выйдет. А из общих соображений — только reinterpret_cast и не хватает для полного счастья.
А как ты понял условие задачи?
Спрашиваю, так как пользовался таким способом не один раз и все было замечательно.
Кроме того, может хоть каплю конструктива добавишь? Или хотя бы аргументов в пользу своей точки зрения.
Здравствуйте, Артур, Вы писали:
А>Так будут проблемы с выравниванием. То есть, если в буфере хранится byte а потом float (nOffset нечётный), то мы получим указатель на float по нечётному адресу.
Ну и пусть он лежит по нечетному адресу, какая разница? Проблем с выравниванием не будет.
А>memcpy(&a,b+nOffset,sizeof(float));
Здравствуйте, Михаил Можаев, Вы писали:
А>> Так будут проблемы с выравниванием.
ММ> Ну и пусть он лежит по нечетному адресу, какая разница? Проблем с ММ> выравниванием не будет.
Строго говоря, Артур прав. Если, например, для некоей платформы значения float
должны находиться по адресам, кратным, скажем, 4, а в буфере одно из значений
находится по адресу, не соответствующему этому требованию, работа с этим адресом
как с указателем на float, может привести к аппаратному исключению.
С другой стороны, я в значительной степени уверен, что автору вопроса в данном
случае никакого дела до выравнивания нет, т.к., скорее всего, он имеет дело с
Windows on Intel
Posted via RSDN NNTP Server 1.4.6 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
V>> Насколько я понял условия задачи, так вообще ничего не выйдет.
ПК>Можно здесь поподробнее?..
Я так понял, что в битовом массиве лежит много-много всего и где-то не в начале, по определенному смещению находится требуемый флоат. Здесь же никакого смещения.
V>> А из общих соображений — только reinterpret_cast и не хватает для полного счастья.
ПК>А какие альтернативы? Functional cast? — А какая разница?
Любое приведение типов — команда компилятору в стиле "я тут хреново написал, но ты не обращай внимания". Отключается проверка типов компилятора. Приведение указателей — еще туда-сюда, реинтерпрет — совсем плохо, потому что отключает всякие проверки. Поэтому лучше всяческих приведений избегать. И последнее — как я понимаю, реинтерпрет — чисто плюсовая штука. А указатели можно в анси-с приводить.
Здравствуйте, Артур, Вы писали:
А>Так будут проблемы с выравниванием. То есть, если в буфере хранится byte а потом float (nOffset нечётный), то мы получим указатель на float по нечётному адресу.
Вопрос. Как я понимаю, в Intel-архитектуре для увеличения скорости доступа ВСЕ значения имеет смысл выравнивать на размер ЕАХ. Но можно этого и не делать, ничего страшного за исключением падения скорости не произойдет, чему доказательством служит директива pack — можно выравнивать и по единице. Или я где-то неправ?
[]
V>Любое приведение типов — команда компилятору в стиле "я тут хреново написал, но ты не обращай внимания". Отключается проверка типов компилятора. Приведение указателей — еще туда-сюда, реинтерпрет — совсем плохо, потому что отключает всякие проверки. Поэтому лучше всяческих приведений избегать. И последнее — как я понимаю, реинтерпрет — чисто плюсовая штука. А указатели можно в анси-с приводить.
Хм, а чем в данном случае reinterpret_cast<float*>(b) отличается от вашего
(float *)(b+nOffset);
за исключением смещения? Оно что, "всякие проверки" не отключает?
Здравствуйте, Vamp, Вы писали:
V>Здравствуйте, Артур, Вы писали:
А>>Так будут проблемы с выравниванием. То есть, если в буфере хранится byte а потом float (nOffset нечётный), то мы получим указатель на float по нечётному адресу.
V>Вопрос. Как я понимаю, в Intel-архитектуре для увеличения скорости доступа ВСЕ значения имеет смысл выравнивать на размер ЕАХ. Но можно этого и не делать, ничего страшного за исключением падения скорости не произойдет, чему доказательством служит директива pack — можно выравнивать и по единице. Или я где-то неправ?
Здравствуйте, Vamp, Вы писали:
V> Приведение указателей — еще туда-сюда, реинтерпрет - V> совсем плохо, потому что отключает всякие проверки.
То, что ты называешь "приведением указателей", может выполняться
одним из следующих способов: reinterpret_cast, static_cast, const_cast или
их комбинацией. В случае, если написан reinterpret_cast, компилятор слепо
следует инструкциям программиста. В случае "приведения указателей" компилятор
подбирает одну из работающих комбинаций, оставляя не больше проверок, нежели
с reinterpret_cast (на деле даже меньше). В данном случае "приведение указателей"
будет выполняться именно через reinterpret_cast, только в коде будет выглядеть
чуть безобиднее. Таким образом, из всех "опасных" приведений типов то,
что ты назвал "приведением указателей" — самое опасное.
V> реинтерпрет — чисто плюсовая штука. А указатели можно в анси-с приводить.
Это — да, аргумент
Posted via RSDN NNTP Server 1.4.6 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
ПК>То, что ты называешь "приведением указателей", может выполняться ПК>одним из следующих способов: reinterpret_cast, static_cast, const_cast или ПК>их комбинацией.
Если ты в этом уверен, значит так оно и есть. Хоть на С, хоть на С++ — только cast-семейство. Я все равно, конечно, не понимаю — что значит "может выполняться" с точки зрения компилятора. Я считал, что приведение типов проосто сообщает компилятору, что данное присваивание корректно и вообще ничего не выполняет (случаи с переопределениями приведения типов а-ля CString рассматривать не будем), но значит, я жестоко ошибался.
ДН>>А кто сказал, что здесь про Intel говорят?
V>А про что тогда тут говорят? А то как-то неконкретно.
Был задан вопрос:
Суть проблемы:
Есть некий файл, он заливается в битовый буффер, в файле хранятся данные разных типов
DWORD int CHAR и float. Нужно данные float вытащить из битового буффера отредактировать и
запихнуть обратно.
Упоминания про конкретную платформу не было. Поэтому, как сказал Миша Можаев:
Только что, за чашкой чая, пришли к этому же
мы обсуждали ситуацию, про которую сказал Павел Кузнецов:
Строго говоря, Артур прав. Если, например, для некоей платформы значения float
должны находиться по адресам, кратным, скажем, 4, а в буфере одно из значений
находится по адресу, не соответствующему этому требованию, работа с этим адресом
как с указателем на float, может привести к аппаратному исключению.
Конечно можно сказать — "в моем случае все и так работает, и я не хочу делать лишних телодвижений". Только потом наступает момент, когда вы вынуждены перенести свой код (который, как вам кажется, полностью ANSI С compliant) на другую платформу и с удивлением обнаружить большие проблемы с выравниванием, познакомиться с двумя индейцами — Big & Little и со множеством других проблем.
Здравствуйте, Дмитрий Наумов, Вы писали: ДН>мы обсуждали ситуацию, про которую сказал Павел Кузнецов: ДН>
ДН>Строго говоря, Артур прав. Если, например, для некоей платформы значения float
ДН>должны находиться по адресам, кратным, скажем, 4, а в буфере одно из значений
ДН>находится по адресу, не соответствующему этому требованию, работа с этим адресом
ДН>как с указателем на float, может привести к аппаратному исключению.
Вопрос только в том, для какой. Существуют ли платформы, на которых флоаты должны распологаться по четным адресам? Потому, что если таких платформ никто назвать не может, то спор беспредметен.
ДН>познакомиться с двумя индейцами — Big & Little и со множеством других проблем.
Те будут не индейцы, а оконечники Свифтовские — тупые и острые. Но это к делу не относится.
Здравствуйте, Vamp, Вы писали:
V> Если ты в этом уверен, значит так оно и есть.
Вовсе не обязательно верить мне на слово ты волен прочитать стандарт самостоятельно (пункты 5.2.3, 5.2.7, 5.2.9, 5.2.10, 5.2.11, 5.4).
V> Хоть на С, хоть на С++ — только cast-семейство.
Естественно, речь шла о C++. В C присутствует только C-style cast. В C++ последний, как уже было сказано, является самой опасной формой преобразований типов.
V> Я все равно, конечно, не понимаю — что значит V> "может выполняться" с точки зрения компилятора.
"Выполняться" — мой вольный перевод слова "perform", употребляющегося в стандарте C++.
Posted via RSDN NNTP Server 1.4.6 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[7]: Как преобразовать BYTE в FLOAT?
От:
Аноним
Дата:
19.03.03 14:58
Оценка:
" с точки зрения компилятора. Я считал, что приведение типов проосто сообщает компилятору, что данное присваивание корректно и вообще ничего не выполняет (случаи с переопределениями приведения типов а-ля CString рассматривать не будем), но значит, я жестоко ошибался.
Ты и впрямь жесточайше ошибался. Представь себе приведение указателя производного класса к базовому, причем к такому, который не первый в списке наследования.
V>Вопрос только в том, для какой. Существуют ли платформы, на которых флоаты должны распологаться по четным адресам? Потому, что если таких платформ никто назвать не может, то спор беспредметен.
Здравствуйте, Vamp, Вы писали:
V>Вопрос только в том, для какой. Существуют ли платформы, на которых флоаты должны распологаться по четным адресам? Потому, что если таких платформ никто назвать не может, то спор беспредметен.
Если есть куча платформ на которых может выполнятся любая комбинация из:
char — 16 битовый
все что больше байта должно быть выровнено по четным адресам
плюс то что я назвал индейцами (я их так называю, но раз тебе нравится больше Свифтовский вариант то Big Endian & Little Endian — для меня Endian == оконечники не очевидно, хотя может это твой персональный перевод)
Итак, все перечисленые вещи существуют на той или иной платформе. Так как ты думаешь, вероятность того, что существует платформа, на которой float должен быть выровнен как то по особому больше нуля??? Мне кажется да.