LINUX.ORG.RU

преобразование raw куска данных (C++)


0

1

Здравствуйте, вопрос по C++.
Есть у меня буфер данных char* например 50 байт.
Я знаю что в куске между 10 и 18 лежит 8 быйтный double
Подскажите как извлеч пожалуйста.
След, код не помогает:
double dbl = 0;
char* cdbl = (char*) &dbl;
for(int i=0;i<8;i++)
cdbl[i] = buf[i+10];
return dbl;

Ответ на: комментарий от anonymous

Спасибо вам всем =) а если у меня в raw лежит число 6 байтовое и мне в double запихнуть надо как быть? Показанный вами код приведет к выходу за границы массива?

pozitiffcat ★★★
() автор топика
Ответ на: комментарий от pozitiffcat

может можно самому создать 6 быйтовый числовой тип? Вернее можно, но как?

pozitiffcat ★★★
() автор топика
Ответ на: комментарий от pozitiffcat

Начнем с того, что с-style cast в С++ недопустим. Значит надо использовать reiterept_cast

второе - читать double не проверяя его валидности плохо. если вдруг невалидный double (а это может быть легко) даже в результате оптимизации пересылки double через регистры упадет в матсопроцессор, жди exception на уровне мат сопроцессора

namezys ★★★★
()
Ответ на: комментарий от namezys

ну это все понятно, мне бы примитивно как нибуть для начала преобразовать, а то работа стоит, плиз кто знает..

pozitiffcat ★★★
() автор топика
Ответ на: комментарий от pozitiffcat

Ну раз все понятно, то парсить надо полноценно, а не надеется, что там intel формат лежит. И что компилятор на той машине ее так же положит

namezys ★★★★
()
Ответ на: комментарий от namezys

int64_t evalint64(unsigned char *str, int len)
{
int64_t result = 0;
while(len--)
{
result <<= 8;
result += str[len];
};
return result;
}

такой код еще есть, со смещением побайтно, но он почемуто только для int работает, а для int64_t double и long long не пашет, я уже хз че делать

pozitiffcat ★★★
() автор топика
Ответ на: комментарий от pozitiffcat

организация которая делала устройство написала протокол и там ясно показано что такие то байты это число, т.е. 6 байт число О_о, как бы вытащить оттуда...

pozitiffcat ★★★
() автор топика
Ответ на: комментарий от pozitiffcat

Господи. Что вы делаете.

Что написано про float point. Читаем битовый массив, интерпретируем необходимые биты, и строим свой double. Профит

namezys ★★★★
()
Ответ на: комментарий от namezys

float point нету..

Читаем битовый массив, интерпретируем необходимые биты, и строим свой double. Профит

я не понял

pozitiffcat ★★★
() автор топика
Ответ на: комментарий от anonymous

>в С++ надо явно приводить тип указателя

Да, забыл совсем! :)

Daeloce
()
Ответ на: комментарий от pozitiffcat

>Спасибо вам всем =) а если у меня в raw лежит число 6 байтовое и мне в double запихнуть надо как быть? Показанный вами код приведет к выходу за границы массива?

Ну есть костыльный способ, копировать эти 6 байт в новый 8 байтовый массив, а оставшиеся 2 байта забить 0, но нужно учитывать big или little endian у вас процессор.

Daeloce
()
Ответ на: комментарий от Daeloce

>Ну есть костыльный способ,
Я его гдето в теме описал, с приведениями типов
напр если я int хочу запихнуть в raw 6 ,байт, то работает, но забрать 6 байт обратно не как!!!

pozitiffcat ★★★
() автор топика
Ответ на: комментарий от pozitiffcat

Давай по порядку.

Что надо сделать?

у тебя есть поток буфер, точнее 6 байт, в которых записано число. В каком формате оно там записано? целое, дробное с фиксированной точкой, с плавающей точкой. Далее, если целое: big endian или litle endian Если с плавающей точкой, то уже надо точно знать, какой тип и как форматируется на железе

namezys ★★★★
()

Не слушай их - они чёртовы еретики. НЕЛЬЗЯ обращаться по невыровненой память, НЕЛЬЗЯ. Только memcpy.

runtime ★★★★
()

И да, про другие проблемы тебе тоже намекнул оратор выше.

runtime ★★★★
()
Ответ на: комментарий от runtime

> НЕЛЬЗЯ обращаться по невыровненой память

Только memcpy.


чем аргументируешь, кроме зажатого шифта?

anonymous
()
Ответ на: комментарий от runtime

можно подумать хоть кто-то, из задающих подобные ТС вопросы, пишет под arm, или вообще хоть что-то, отличное от x86[-64]

Love5an
()
Ответ на: комментарий от namezys

Скажите, а такой код корректно отобразить содержимое памяти в BigEndian системе c uint в 32 бита?


unsigned int to_bits = 256;
unsigned int shifter = 1;

for( int i = 0; i < 32; ++i )
{
    if( 0 == ( i % 8 ) ) std::cout << ' ';

    if( to_bits & shifter ) std::cout << '1';
    else std::cout << '0';

    shifter <<= 1;
}

должно быть что-то в роде:

 00000000 00000000 10000000 00000000
?

whatfor
()
Ответ на: комментарий от namezys

>у тебя есть поток буфер, точнее 6 байт, в которых записано число. В каком формате оно там записано?

целое, про endian ничего не знаю =)

pozitiffcat ★★★
() автор топика
Ответ на: комментарий от pozitiffcat

решена проблема: вот код можт кому пригодится


int64_t evalint64(unsigned char *str, int len) //функция преобразования
{
int64_t result = 0;
while(len--)
{
result <<= 8;
result += str[len];
};
return result;
}

// гденить в основном коде
long long l = (long long)evalint64((unsigned char*)&a.buff + 42,6);

&a.buff это полученный буффер char[]
42 Это начало откуда брать символы
6 это длинна байт

pozitiffcat ★★★
() автор топика
Ответ на: комментарий от whatfor

а на функции разбивать не учили.

Вообще указанный у вас код не зависит от архитектуры, но на экран выводит в обратном по сравнению с привычным (снача старшие биты, потом младшие) порядке.

то есть результат 00000001 00000000 00000000 00000000

namezys ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.