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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 5.00
Russian_Dragon
10 / 11 / 0
Регистрация: 18.02.2012
Сообщений: 140
#1

Преобразование сверхбольшого двоичного числа в строку-десятичное_число. - C++

23.02.2012, 08:11. Просмотров 2156. Ответов 21
Метки нет (Все метки)

Пишу класс для хранение и операций над числами большой размерности.
Перепробовал несколько вариантов представления числа и на данный момент решил поработать с массивом типа __int8. Массив представляет собой непрерывное число.
Но тут возникает проблема: как показать число пользователю в десятичном виде.
Т.е. как перевести очень большое двоичное число в десятичное.

П.с. Надеюсь поняли ибо, на работе, одному математику долго пришлось объяснять суть проблемы.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.02.2012, 08:11
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Преобразование сверхбольшого двоичного числа в строку-десятичное_число. (C++):

Преобразование числа в строку - C++
Всем привет. Имеется следующая функция void LiquidCrystal_I2C_PrintString(char *str){ uint8_t i=0; while(str) { ...

Преобразование числа в строку - C++
Как преобразовать строку char *s, в которой записано число(возможно со знаком минус), в формат типа long 1) в строке десятичное число ...

Преобразование числа в строку!!!! - C++
Как в VS преобразовать число в строку!!! Через itoa что-то не выходит!!!

Преобразование числа в строку - C++
Всем доброго времени суток, помогите пожалуйста получить из числа 12345679 (int), строку string = {1, 2, 3, 4, 5, 6, 7, 8, 9}. т.е....

Преобразование числа в строку - C++
Подскажите как преобразовать число в строку, пожалуйста!

Преобразование целого числа в строку - C++
Написать функцию, которая выполняет преобразование целого числа в строку. Проиллюстрировать работу функции примером.

21
softmob
1248 / 698 / 155
Регистрация: 20.02.2010
Сообщений: 1,035
23.02.2012, 11:39 #2
вот может пригодится:
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#include <iostream>
#include <string>
#include <deque>
#include <locale>
using namespace std;
 
string integer(deque<int>& a ,int q, int p, string u)
{
    string res;
    int demolition, j, lena = a.size();
 
    do
    {
        j = 0;
        demolition = 0;      
 
        for(int i = 0; i < lena; i++)
        {       
            demolition *= q;        
            demolition += a[i];
 
            if (demolition < p && i && j) {a[j] = 0; j++;}
 
            if (demolition >= p) 
            {   
                a[j] = demolition / p;  
                demolition %= p;   
                j++;
            }
        } 
        a.resize(j);
        res = u[demolition] + res;
        lena = j;   
    }
    while(lena);
    return res; 
}
 
deque<int> addition(deque<int>& a, deque<int>& b, int q)
{ 
    deque<int> res;
    if (a.empty()) 
        res = b;
    else
    {
        int lena = a.size() - 1, lenb = b.size() - 1;
        int transfer = 0, anumber, bnumber, amount, i = 0;
 
        do 
        {
            if (lena >= i)
                anumber = a[lena-i];
            else
                anumber = 0;
 
            if (lenb >= i) 
                bnumber = b[lenb-i];
            else
                bnumber = 0;
 
            amount = anumber + bnumber + transfer;
 
            if (amount >= q)
            {
                transfer = amount / q;
                amount %= q;
            }
            else
                transfer = 0;
 
            res.push_front(amount);
            i++;
        }
        while(lena >= i || lenb >= i);
 
        if (transfer > 0) res.push_front(transfer);
    }
    return res;
}
 
deque <int> multiplication(deque<int>& aa, deque<int>& bb, int q)
{
    deque<int> r, res, a = aa, b = bb;
    if(a.size() > b.size()) swap(a, b);
    int transfer, product, h = 0, k = 0;
 
    while(!a.empty() && !a.back())  {a.pop_back(); h++;}    
    while(!b.empty() && !b.back())  {b.pop_back(); h++;}
 
    for(int i = a.size() - 1; i >= 0; i--)
    {
        r.clear(); 
        transfer = 0;       
 
        for (int j = b.size() - 1; j >= 0; j--)
        {                       
            product = a[i] * b[j] + transfer;
 
            if (product >= q) 
            {
                transfer = product / q;
                product %= q;
            }
            else
                transfer = 0;         
 
            r.push_front(product);
        }
 
        if (transfer > 0) r.push_front(transfer);
        r.resize(r.size() + k);
        res = addition(res, r, q);
        k++;
    }       
 
    res.resize(res.size() + h);
    return res;
}
 
string fractional(deque<int>& b, int q, deque <int>& p, int l, string u)
{       
    string res;
    int signs,LenInteger, i = 0, sum, SignsFractional = 0;
    deque<int> r;      
    while(!b.empty() && !b.front()) {b.pop_front(); SignsFractional++;}
 
    do  
    {
        i++;
        signs = b.size() + SignsFractional;
 
        r = multiplication(b, p, q);
        b.clear(); 
 
        LenInteger = r.size() - signs;
        sum = 0;
 
        if(LenInteger > 0) 
        {
            for (int t = 0; t < LenInteger; t++)
            { 
                sum *= q;
                sum += r.front();
                r.pop_front();
            }
        }
        else
        {
            sum = 0;
            SignsFractional = (-1) * LenInteger; 
        }
 
        res += u[sum];
 
        while(!r.empty() && !r.front()) 
        {
            r.pop_front();
            SignsFractional++;
        }
 
        b = r;
        r.clear(); 
    }
    while(i < l && !b.empty()); 
    return res;
}
 
string output(string a, int q, int p, int l)
{
    string u("0123456789ABCDEF"), b, res;
 
    if (a.find(',') != string::npos) a[a.find(',')] = '.';
 
    if (a.find('.') != string::npos) 
    {
        b = a.substr(a.find('.') + 1);
        a = a.substr(0, a.find('.'));  
    }
 
    deque<int> array;
    for (unsigned int i = 0; i < a.size(); i++)
        array.push_back(u.find(toupper(a[i])));
 
    res = integer(array, q, p, u);
 
    if (b.size())
    {
        deque<int> array2, pp;
        for (unsigned int i = 0; i < b.size(); i++) 
            array2.push_back(u.find(toupper(b[i])));
 
        for (int p2 = p; p2; p2 /= q) pp.push_front(p2 % q);
 
        res += "." + fractional(array2, q, pp, l, u);
    }    
    return res;
}
 
int main(void)
{     
    setlocale(LC_ALL,"Russian");
    string a;               
    int q, p;
    cout << "Введите число: "; cin >> a;  
    cout << "Введите исходную систему счисления: "; cin >> q;
    cout << "Введите конечную систему счисления: "; cin >> p;
    int l = 30; 
    cout << string(80, '_') << output(a, q, p, l) << endl;
    system("pause");
}
перевод длинных чисел между чисел между сс 2-16
1
Russian_Dragon
10 / 11 / 0
Регистрация: 18.02.2012
Сообщений: 140
23.02.2012, 12:06  [ТС] #3
Спасибо, сейчас буду разбираться, что тут к чему.
0
fasked
Эксперт С++
4948 / 2528 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
23.02.2012, 14:36 #4
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
Перепробовал несколько вариантов представления числа и на данный момент решил поработать с массивом типа __int8. Массив представляет собой непрерывное число.
Но тут возникает проблема: как показать число пользователю в десятичном виде.
Во-первых int8 неудачная идея, а во-вторых зачем его переводить? Только не говорите, что Вы храните фактически по одному биту в каждом разряде, то есть в каждой ячейке массива Какое количество бит вы называете сверхбольшим?
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6503 / 3142 / 307
Регистрация: 04.12.2011
Сообщений: 8,673
Записей в блоге: 5
23.02.2012, 14:39 #5
С праздником!
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
одному математику долго пришлось объяснять суть проблемы
солидарен с Вашим математиком, хотя не математик. Т.е. не возьму в толк и просится ответ - выберите Int64. А интересно, именно, в чем загвоздка?
0
Байт
Эксперт C
16548 / 10818 / 1640
Регистрация: 24.12.2010
Сообщений: 20,879
23.02.2012, 14:54 #6
Russian_Dragon, Судя по всему, вы умеете работать с длинными числами, те производить с ними арифметические операции. В данном случае требуется деление с остатком. Покажите, как вы делите, форму представления числа. Если пойму, попытаюсь вам помочь.
ЗЫ. Иногда бывает полезней переводить сначала в 1000-ричную
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6503 / 3142 / 307
Регистрация: 04.12.2011
Сообщений: 8,673
Записей в блоге: 5
23.02.2012, 15:05 #7
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
с массивом типа __int8
Извините за почемучество, но если это для двоичного, - почему не unsigned char (byte) ?
fasked, похоже я задал вопрос, который уже задан, - не увидел.
0
Russian_Dragon
10 / 11 / 0
Регистрация: 18.02.2012
Сообщений: 140
23.02.2012, 15:35  [ТС] #8
Цитата Сообщение от fasked Посмотреть сообщение
Во-первых int8 неудачная идея
Скажем так - я просто перестраховываюсь.

Цитата Сообщение от fasked Посмотреть сообщение
Только не говорите, что Вы храните фактически по одному биту в каждом разряде, то есть в каждой ячейке массива
Нет. Еще раз говорю, - массив - это единое число.
Вот пример __int8 mas[4] = {85, 85, 85, 85};
01010101 01010101 01010101 01010101
Но класс будет возвращать число: 1431655765.

Цитата Сообщение от fasked Посмотреть сообщение
Какое количество бит вы называете сверхбольшим?
больше чем 64 [на данный момент]

Добавлено через 1 минуту

Цитата Сообщение от IGPIGP Посмотреть сообщение
С праздником!
Спасибо. И тебя.
И всех остальных))

Цитата Сообщение от IGPIGP Посмотреть сообщение
А интересно, именно, в чем загвоздка?
чтобы работать с числами которые не помещаются __int64.

Добавлено через 7 минут
Цитата Сообщение от Байт Посмотреть сообщение
Russian_Dragon, Судя по всему, вы умеете работать с длинными числами, те производить с ними арифметические операции. В данном случае требуется деление с остатком. Покажите, как вы делите, форму представления числа. Если пойму, попытаюсь вам помочь.
ЗЫ. Иногда бывает полезней переводить сначала в 1000-ричную
Что-то не совсем понял.
Пока я пытаюсь представить массив как единое число. Пример чуть выше.

Добавлено через 3 минуты
Цитата Сообщение от IGPIGP Посмотреть сообщение
Извините за почемучество, но если это для двоичного, - почему не unsigned char (byte) ?
fasked, похоже я задал вопрос, который уже задан, - не увидел.
Сначала небольшое отступление.
Я, пред всеми, извиняюсь я использую не __int8, а "unsigned __int8".

Что касается "unsigned char", то суть от этого не меняется.
http://msdn.microsoft.com/en-us/library/s3f49ktz%28v=VS.80%29.aspx
Просто для меня так наглядней.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6503 / 3142 / 307
Регистрация: 04.12.2011
Сообщений: 8,673
Записей в блоге: 5
23.02.2012, 15:48 #9
Цитата Сообщение от Байт Посмотреть сообщение
Судя по всему, вы умеете работать с длинными числами
Тогда, присоединяюсь. Если вопрос только во внешнем отображении, а библиотеки для арифметики у Вас уже есть, то можно, например, выбрать для внутреннего double, а потом выводить в строку. Или я опять не понимаю?
1
Russian_Dragon
10 / 11 / 0
Регистрация: 18.02.2012
Сообщений: 140
23.02.2012, 15:56  [ТС] #10
Цитата Сообщение от IGPIGP Посмотреть сообщение
Если вопрос только во внешнем отображении
Вопрос пока только в этом.

Цитата Сообщение от IGPIGP Посмотреть сообщение
а библиотеки для арифметики у Вас уже есть,
Нет пока еще логики операций.

Цитата Сообщение от IGPIGP Посмотреть сообщение
то можно, например, выбрать для внутреннего double, а потом выводить в строку.
Есть такая у меня мысля для временного решения отображения.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6503 / 3142 / 307
Регистрация: 04.12.2011
Сообщений: 8,673
Записей в блоге: 5
23.02.2012, 16:04 #11
Цитата Сообщение от IGPIGP Посмотреть сообщение
Тогда, присоединяюсь. Если вопрос только во внешнем отображении, а библиотеки для арифметики у Вас уже есть, то можно, например, выбрать для внутреннего double, а потом выводить в строку. Или я опять не понимаю?
"выбрать для внутреннего double, а потом выводить в строк" - Это, похоже, опять глупость, - не подумал (мало знаков в мантиссе- 14).

Добавлено через 6 минут
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
Нет пока еще логики операций
Это главный вопрос, мне кажется. Представление ему и в подмётки не годится. ИМХО решив его, - получите решение для вывода без труда.
1
Russian_Dragon
10 / 11 / 0
Регистрация: 18.02.2012
Сообщений: 140
23.02.2012, 17:06  [ТС] #12
Всем спасибо за беспокойство.
Но походу игра не стоит свеч.
Суть в том, что на подготовку расчетов будет уходить столько же времени, что и в текущем варианте класса. А расчет более хитрый чем текущий.

На данный момент я реализую класс, в котором, в каждом элементе массива храниться одна цифра числа.
Он умудряется складывать два вот таких числа
543084287902034787623400527233469834534870234899872312754123908723484755430842879020347876234005272334698345348702348998 723127541239087234847554308428790203478762340052723346983453487023489987231275412390872348475543084287902034787623400527 23346983453487023489987231275412390872348475.543084287902034787623400527233469834534870234899872312754123908723484755430 842879020347876234005272334698345348702348998723127541239087234847554308428790203478762340052723346983453487023489987231 27541239087234847554308428790203478762340052723346983453487023489987231275412390872348475
за 6 тысячных секунды [0.006].
На ноуте с i7 c частой 1.7Ггц на ядро.
Кстати, если кто не заметил, число не целое.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6503 / 3142 / 307
Регистрация: 04.12.2011
Сообщений: 8,673
Записей в блоге: 5
23.02.2012, 18:16 #13
Цитата Сообщение от Russian_Dragon Посмотреть сообщение
Он умудряется складывать два вот таких числа
Russian_Dragon, это для меня тема интересная. Есть у меня программка рассчитывающая определители матриц для получения полиномиальных коэффициентов методом Гауса, для интерполяции функции заданной конечным количеством пар точек.
При размерах матрицы >15x15 double уже не хватает даже для гладких кривых...
Может где-то есть библиотеки, для работы с рациональными числами большей точности и порядка, хоть на Fortran-e? В данной ситуации, для меня скорость на 3-м плане.
0
Russian_Dragon
10 / 11 / 0
Регистрация: 18.02.2012
Сообщений: 140
23.02.2012, 18:49  [ТС] #14
Цитата Сообщение от IGPIGP Посмотреть сообщение
Может где-то есть библиотеки, для работы с рациональными числами большей точности и порядка, хоть на Fortran-e?
Говорят, что есть, но я даже не пробовал искать самому интересно реализовать.
Если руки дойдут нормально реализовать операции, то потом скину исходники.

Цитата Сообщение от IGPIGP Посмотреть сообщение
В данной ситуации, для меня скорость на 3-м плане.
Если скорость на 3-м, то вот мой курсовая 3 курса учебы. Тут я больше выёживался чем оптимизировал, то приведенное выше число она считает где-то за 0.15 секунды.
chislo.rar
Пользоваться так:
C++
1
2
3
4
5
#include "CHISLO.h"
...
char* str = "123.456\n";// символ новой строки обязателен.
Irracionalnoe Cislo1_f(str);
cout << Cislo1_f << '\n';
Там +, -, *, /, % реализованы.
Есть один нюанс. При делении: если группа чисел повторяются более 2 раз расчет останавливается.
т.е.
C++
1
2
Irracionalnoe Cislo1_f(2), Cislo2_f(3);
cout << Cislo1_f/Cislo2_f << '\n';
мы получим 0,67.
Более нормальную логику времени не хватило реализовать.
Кстати, обойти можно так:
C++
1
2
Cislo1_f.ProverkaDeleny_c = false;
Cislo2_f.ProverkaDeleny_c = false;
Обязательно у обоих чисел, но тогда может зациклиться пока память не кончится.
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6503 / 3142 / 307
Регистрация: 04.12.2011
Сообщений: 8,673
Записей в блоге: 5
23.02.2012, 19:49 #15
Спасибо, обязательно посмотрю.
0
23.02.2012, 19:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.02.2012, 19:49
Привет! Вот еще темы с ответами:

Преобразование двоичного кода в текст - C++
есть код: struct home { char name; long number; int dom; int kvartira; };

Преобразование двоичного кода в ASCII - C++
Ребята, у меня вопрос. Вот я, например, имею строку &quot;10011001&quot; или подобную из восьми единиц и нулей. Вопрос: как преобразовать эту строку...

Преобразование двоичного массива int в символ - C++
Здравствуйте. У меня вопрос. Как преобразовать числовой массив, в котором, к примеру, 8 элементов, в символ? В массиве только нули и...

Преобразование текстового файла в двоичный и чтение исходных данных из двоичного файла. - C++
#include&lt;iostream&gt; #include&lt;fstream&gt; #include&lt;locale.h&gt; #include&lt;iomanip&gt; #include &lt;cstdlib&gt; using namespace std; struct...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

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