Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 26, средняя оценка - 5.00
insideone
Модератор
Автор FAQ
3639 / 918 / 49
Регистрация: 10.01.2010
Сообщений: 2,469
#1

Побитовое копирование double - C++

10.01.2010, 02:32. Просмотров 3413. Ответов 19
Метки нет (Все метки)

Доброго времени суток!
Преамбула: В целях интеграции Lua в движок C++ пытаюсь написать класс который может помещать в себя все типы данных в определенном порядке, чтобы можно было передать ссылку на этот класс в функцию которая отправит эти данные в обработчик Lua. Класс почти написал за исключением поддержи double - потому что для double нельзя использовать побитовые операции, через которые лаконично преобразуются остальные типы.
Собственно вопрос: как считать побитово double?
Файлы с кодом прилагаются....
0
Вложения
Тип файла: zip Stack.zip (2.7 Кб, 19 просмотров)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.01.2010, 02:32
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Побитовое копирование double (C++):

Побитовое копирование рисунка - C++ Builder
Есть задание на курсач: Разработать программу, демонстрирующую влияние установленного приоритета потока на скорость его...

Too few parametrs in call to '_fastcall LogN(cont log double, const long double)' - C++ Builder
void __fastcall TForm1::Button1Click(TObject *Sender) {int n; double y,a=1.5,b=0.7,z=3.2,x=StrToFloat(Edit1->Text); ...

Ошибка e2015 ambiguity between(double,double) в функции - C++ Builder
Функция: void gmdh1() ; { double poly; double work; unsigned short int ind; unsigned short int ma; double rms; double ww,...

Работа с double - C++ Builder
Здравствуйте! Подскажите... void __fastcall TForm1::Button37Click(TObject *Sender) { double z; ...

Double and Bin - C++ Builder
как правильно(или просто) записать в double n = двоичное число?? чтобы при double n='10'; char st; itoa(n, st,10); ...

String to double - C++ Builder
Пишу программу, для автоматических измерений на приборах Agilent. И столкнулся с такой проблемой. Прибор возвращает запрашиваемые...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
alex_x_x
бжни
2447 / 1652 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
10.01.2010, 02:57 #2
не очень понимаю что за побитовые операции, разместить в определенном порядке, чем memset не подойдет, обращатся можно к отдельным байтам путем приведения к (char*)?
вообщем, что значит побитово считать?
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
10.01.2010, 12:03 #3
Я тоже писал интеграцию Lua в С++. Много интересного нарисовал. Но доделать не успел, когда припекло. Надо было встроить набор дополнительных функций. И ничего, на чистом Lua API отлично всё написалось, быстро и без ошибок.
Что же касается битовых операций, то можно воспользоваться union:
C++
1
2
3
4
5
6
union BitDouble {
    double dbl;
//    __int64 bits64;                      // Ненужные члены можно просто закомментировать
    unsigned long bits32[2];
    unsigned char bits8[8];
};
0
insideone
Модератор
Автор FAQ
3639 / 918 / 49
Регистрация: 10.01.2010
Сообщений: 2,469
10.01.2010, 16:15  [ТС] #4
Цитата Сообщение от alex_x_x Посмотреть сообщение
не очень понимаю что за побитовые операции, разместить в определенном порядке, чем memset не подойдет, обращатся можно к отдельным байтам путем приведения к (char*)?
вообщем, что значит побитово считать?
Ну... задумываясь как можно было бы хранить различные данные я подумал о том что bool, char, и все int это простые числа над которыми можно производить побитовую операцию & 1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <class AnyType>
void WriteToDB(AnyType Var){
   unsigned char size = sizeof(Var)*8; получаем размер в БИТах
   unsigned char LastPos = GetCursor(); // последняя позиция в БД
   for (unsigned char CurPos = LastPos; CurPos < (LastPos + size); CurPos++)
   {
       this->DB[CurPos] = Var & 1; // отрываем последний БИТ от Var и записываем его в БД
       Var = Var >> 1; // делаем предпоследний БИТ последним БИТом =)
   }
   SetLink(LastPos, size); // устанавливаем метку где записались данные
}
// Результат работы WriteToDB((unsigned short int)3)
// исходные данные 3 = 0000 0000 0000 0011
// this->DB = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
// PS. БД bool массив[/B]
а вот double не разрешает над собой творить такого, хотя это глупо все же состоит из битов так или иначе

Добавлено через 1 час 27 минут
Цитата Сообщение от Nick Alte Посмотреть сообщение
Что же касается битовых операций, то можно воспользоваться union:
C++
1
2
3
4
5
6
union BitDouble {
    double dbl;
//    __int64 bits64;                      // Ненужные члены можно просто закомментировать
    unsigned long bits32[2];
    unsigned char bits8[8];
};
union хорош конечно... но тут не сделаешь автоматического выбора куда ему писать. вот если бы можно было
C++
1
BitDouble = 3;
... хотя то что сейчас там тоже все за счет кучи перегрузок делается. Хм... ну ещё минус то что union занимает максимум пространства из возможного
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
10.01.2010, 16:18 #5
Какой ещё максимум? Такой union займёт ровно столько же места, сколько занимает double. Ну а что до автовыбора, кучи перегрузок не понадобится. Достаточно сделать простейший класс и определить ему operator = (double);
0
insideone
Модератор
Автор FAQ
3639 / 918 / 49
Регистрация: 10.01.2010
Сообщений: 2,469
10.01.2010, 17:15  [ТС] #6
Цитата Сообщение от Nick Alte Посмотреть сообщение
Какой ещё максимум? Такой union займёт ровно столько же места, сколько занимает double. Ну а что до автовыбора, кучи перегрузок не понадобится. Достаточно сделать простейший класс и определить ему operator = (double);
Я имею ввиду что не хочу для double вводить отдельные какие то переменные\структуры. Необходимо создать систему которой все равно какие данные в неё вводятся.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class USTACK{
public:
    struct DATA{
        union A{
            int i;
            char c;
            double d;
            float f;
            bool b;
        } Data;
        unsigned char Type;
        
    } DB[USTACK_SIZE];
 
    unsigned char count;
 
    USTACK::USTACK();
 
    USTACK& operator<<(int var);
    USTACK& operator>>(int& var);
};
 
USTACK& USTACK::operator<<(int var){
    this->DB[this->count].Data.i = var;
    this->count++;
return (*this);
}
 
USTACK& USTACK::operator>>(int& var){
    unsigned char LastID = this->count-1;
    var = this->DB[LastID].Data.i;
    this->DB[LastID].Data.i = NULL;
    this->count--;
return (*this);
}
 
int main()
{
    // Переменные для тестирования работы
    bool bX = true, bY = false, bZ = true;
    char cX[100] = {NULL}, cY[100] = {NULL}; unsigned char cZ[100] = {NULL};
    int iX = 3; short int iY = 200; long long int iZ = 55;
 
    USTACK In;
    In << 4 << 6;
    In >> iX >> iY;
}
Т.е. я могу лишь искуственно выбирать куда мне ложить данные. Если переписать оператор = то для него нужно будет писать тоже входные данные, а они могут быть разными, т.е. все равно ручками. Может я чего то непонимаю, приведите пожалуйста код который демонстрирует функционал который вы имеете ввиду.
0
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
10.01.2010, 17:31 #7
почему бы не преобразовать любой поступивший тип в массив char той длины, которая будет возвращена оператором sizeof? и уже для char потом применять битовые операции.
0
insideone
Модератор
Автор FAQ
3639 / 918 / 49
Регистрация: 10.01.2010
Сообщений: 2,469
10.01.2010, 17:42  [ТС] #8
Цитата Сообщение от zim22 Посмотреть сообщение
почему бы не преобразовать любой поступивший тип в массив char той длины, которая будет возвращена оператором sizeof? и уже для char потом применять битовые операции.
Хм, очень интересно. В результате в каждом элементе массива будут хранится определенные байты входных данных? А как это сделать? И как лучше хранить остаток от double?
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
10.01.2010, 17:43 #9
Я-то предпочитаю вообще избегать таких конструкций. Смешение разнородных данных в одном и том же месте - не самый выигрышный ход. К динамической типизации и типам наподобие Variant надо прибегать лишь тогда, когда более подходящие варианты недоступны.
0
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
10.01.2010, 17:55 #10
Цитата Сообщение от insideone Посмотреть сообщение
В результате в каждом элементе массива будут хранится определенные байты входных данных?
наверно. я не знаю, как вещественный числа представлены в памяти ПК.

Цитата Сообщение от insideone Посмотреть сообщение
А как это сделать?
C++
1
2
3
4
5
6
7
double z = 33.228844649;
const int zSize = sizeof(z);
char zArray[zSize] = {0};
memcpy(zArray, &z, zSize);
 
double convertedZ = 0;
memcpy(&convertedZ, zArray, zSize);
Цитата Сообщение от insideone Посмотреть сообщение
И как лучше хранить остаток от double?
какой остаток?
1
insideone
Модератор
Автор FAQ
3639 / 918 / 49
Регистрация: 10.01.2010
Сообщений: 2,469
10.01.2010, 19:04  [ТС] #11
zim22: Большое спасибо за код, все таки я ещё плоховато знаю стандартные функции библиотек С++. Получается можно отлично приводить любой тип данных к char массиву, значит класс который сейчас есть будет использовать char DB[] а не bool DB[] и все будет ОК) небольшая потеря для bool типа думаю не особо страшна) Про остаток не актуально это я уже подумывал как бы извратиться хранить double отдельно целую и дробную части)

Nick Alte: Ну да Variant это конечно плохо, память используется неоптимально и все такое, но я делаю класс который является массивом информации (любой) а не единцей информации. И при этом для хранения элемента класса требуется столько байт сколько он весит. Накладные расходы - байт с информацией о местонахождении элемента в массиве класса.
0
Evg
Эксперт CАвтор FAQ
17810 / 6016 / 388
Регистрация: 30.03.2009
Сообщений: 16,531
Записей в блоге: 26
10.01.2010, 19:23 #12
Цитата Сообщение от Nick Alte Посмотреть сообщение
Я-то предпочитаю вообще избегать таких конструкций. Смешение разнородных данных в одном и том же месте - не самый выигрышный ход. К динамической типизации и типам наподобие Variant надо прибегать лишь тогда, когда более подходящие варианты недоступны.
В случае с Lua такие варианты неприемлимы, т.к. нужно транзитом передать данные через код, который "ничего не знает" ни про какие типы

Цитата Сообщение от insideone Посмотреть сообщение
Ну да Variant это конечно плохо, память используется неоптимально и все такое, но я делаю класс который является массивом информации (любой) а не единцей информации. И при этом для хранения элемента класса требуется столько байт сколько он весит. Накладные расходы - байт с информацией о местонахождении элемента в массиве класса.
Боязнь потерять 10 байт (30 байт, 100 байт) на фоне нескольких десятков или сотен килобайт (а то и больше), отжираемых интерпретатором Lua - как-то смешно выглядит. Экономить память хорошо, но в разумных пределах.

А что по постановке задачи - я так и не понял, в чём конкретно состоит проблема
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
10.01.2010, 19:29 #13
Variant плох не потерями памяти, а безопасностью типов и нежелательными побочными эффектами. Насчёт его необходимости в случае с Lua мне можно не рассказывать, я преспокойно обхожусь без таких вещей. Функции Lua API о типах превосходно осведомлены.
insideone, а так ли уж и нужен такой класс? Какой в нём прок? Какие есть причины, по которым без него нельзя обойтись?
0
insideone
Модератор
Автор FAQ
3639 / 918 / 49
Регистрация: 10.01.2010
Сообщений: 2,469
10.01.2010, 20:16  [ТС] #14
Хочется как то обеспечить себе удобство написав высокоуровневые функции. Конечно для кого то я извращаюсь, но мне нравится экспериментировать. С++ сложен и осваивается не быстро, тем более я учусь для себя, а так я студент даже не IT специальности. С интеграцией Lua знаком со вчера так что...
Я писал функцию Call вызывающую Lua функцию, там нужно передать через push параметры, при этом они могут быть разных типов и для этого используются разные функции lua API. Были написаны следующие перегрузки
C++
1
2
3
4
    void Push(const bool& arg);
    void Push(const double& arg);
    void Push(const int& arg);
// etc
Хотелось бы реализовать Call так...
C++
1
STACK& Call(char* FuncName, STACK* InData);
вызов
C++
1
StackVar = Call("TestFunc", StackVar << 2 << 4 << 5);
... В смысле через написаный стек класс мы передаем параметры и обратно принимаем через него же.

В принципе можно обойтись без всего этого но наверное будет не так красиво =)
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
10.01.2010, 20:55 #15
Ну да, всегда приходится чем-то жертвовать. Я по этому поводу пытаюсь исхитрить так, чтобы операторы << сразу помещали значения на стек Lua, без посредников.
Впрочем, после того, как я обнаружил, что и на чистом Lua API мои задачи решились быстро, гладко и без проблем, стремление допилить сей binding несколько поутихло. Может, когда-нибудь соберусь и доделаю...
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.01.2010, 20:55
Привет! Вот еще темы с ответами:

AnsiString to double - C++ Builder
как перевести строку типа 23-е4 в double

vecror<double> в string - C++ Builder
Добрый день! Есть у меня vector&lt;double&gt;. Можете подсказать как записать всё его содержимое в одну строку string?

Побитовое сложение двух чисел - Visual C++
Помогите решить. С клавиатуры вводятся 2 числа. Надо их побитово обработать (сложить). Проблема в том, что нужно работать с типом unsigned...

CString в double - Visual C++
CEdit *editBoxPtr1 = (CEdit *)(this-&gt;GetDlgItem(IDC_EDIT1)); editBoxPtr1-&gt;GetWindowText(rString); Нужно CString преобразовать в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
10.01.2010, 20:55
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru