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

Перевод числа из hex в dec - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Запрет запуска второй копии приложений http://www.cyberforum.ru/cpp-beginners/thread1778654.html
Нужно запретить запуск второй копии чужого приложения. Т.е. пользователь ткнул 5 раз на ярлык GTA5 в результате в процессе висит 2 GTA5, что не есть хорошо. Как этого можно избежать? Пока что идея...
C++ Final для вложенной структуры class A{ class B {..} final; }; так класс B теперь входит в размер A, но не инициализируется. это баг? потому что я нигде не нашел про такое использование http://www.cyberforum.ru/cpp-beginners/thread1778648.html
C++ Stack. определение шаблона функции testStack. (хочу разобраться в коде)
Вот эта программа. Хочу разобраться в коде. #include <iostream> #include <string> #include <Stack> using namespace std; template <typename T> void testStack( Stack< T > &theStack,//...
C++ Ошибка компилятора C2784
Код: #include <iostream> #include <conio.h> using namespace std; int main(void) { cout >> "Hello, world" >> endl;
C++ Сложение чисел типа long long http://www.cyberforum.ru/cpp-beginners/thread1778607.html
Пыталась сложить 2 больших числа (в пределах long long), не получилось. В чем дело? #include <cmath> #include <cstdio> #include <vector> #include <iostream> #include <algorithm> using...
C++ Передвижение коня по доске и сбор букв Добрый день! Не могу разобраться, в чём проблема =( Нужно решить задачу: есть шахматная доска. На ней, в каждой клетке, расположены буквы. По доске "ходит" конь (буквой "г", соответственно), и... подробнее

Показать сообщение отдельно
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6503 / 3142 / 307
Регистрация: 04.12.2011
Сообщений: 8,673
Записей в блоге: 5
15.07.2016, 17:59
Ferrari F1,
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
И я ума не приложу, как так в голове продумать алгоритм, чтобы он был обобщенным, а не охватывал лишь частные случаи..
Это я говорю не только о делении, а вообще обо всех возникающих задачах...
Ferrari F1, промышленное программирование предполагает поиск библиотек и сшивание их минимальным кодом.
Но когда интересно покодировать велосипед, приходится решать всё самому. Тогда имеет смысл начать с самых простых кирпичиков, из которых потом построится дом. Тут можно задать вопрос : "Без чего в дальнейшем не обойтись". Тогда появляются функции вроде:
C++
1
2
3
4
5
6
7
8
9
10
//полезная простая функция
//когда непонятно ещё куда бечь можно начать с таких вещей:
char decimal_from_hex_char(char hex)
{
char ret;
if(hex>'0'-1 && hex < '9'+1) ret = hex-'0';
if((hex>'A'-1 && hex < 'F'+1)) ret = 10 + hex - 'A';
if((hex>'a'-1 && hex < 'f'+1)) ret = 10 + hex - 'a';
return ret;
}
или
C++
1
2
3
4
5
6
7
8
9
10
11
12
//такой вектор нужен так как в строках числа более одного знака "растворяются" с потерей информации
void make_vec_from_hexStr(string &srcStr, vector<char> &vec)
{
vec.clear();
typedef string::size_type Str_t;
Str_t len = srcStr.size();
if(len>0)
for(Str_t i=0; i<len; ++i)
{
vec.push_back(decimal_from_hex_char(srcStr[i]));
}
}
Если задача объёмистая не стоит мелочиться в написании средств вывода промежуточных результатов. Функции show_vec - средство вывода основной структуры данных в реализации (векторов чар).
Когда появляется инструментарий решающий простые части задачи, её решение осмысливается в терминах данных инструментовабстракций и не кажется таким уж сложным. Но и далее принцип - от простого к сложному, это надёжный путь к победе. Это потому, что наш мозг имеет ограниченные ресурсы, но в отличие от компьютера умеет конструировать (собирать из одних структур другие более сложные структуры).
Результат в моём варианте очень громоздок и неэффективен, по сравнению с предложенными, но может оказаться легче для понимания, не только самого алгоритма (он не суть важен), сколько для визуализации процесса построения алгоритма.
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
#include <iostream>
#include <vector>
#include <string>
using namespace std;
 
//полезная простая функция
//когда непонятно ещё куда бечь можно начать с таких вещей:
char decimal_from_hex_char(char hex)
{
char ret;
if(hex>'0'-1 && hex < '9'+1) ret = hex-'0';
if((hex>'A'-1 && hex < 'F'+1)) ret = 10 + hex - 'A';
if((hex>'a'-1 && hex < 'f'+1)) ret = 10 + hex - 'a';
return ret;
}
 
//такой вектор нужен так как в строках числа более одного знака "растворяются" с потерей информации
void make_vec_from_hexStr(string &srcStr, vector<char> &vec)
{
vec.clear();
typedef string::size_type Str_t;
Str_t len = srcStr.size();
if(len>0)
for(Str_t i=0; i<len; ++i)
{
vec.push_back(decimal_from_hex_char(srcStr[i]));
}
}
 
//разогнался но для char это не нужно ( в этом коде не используется )
template<typename T>
void show_vec(typename vector<T> &vec, string name="")
{
if(name!="")cout<<name<<endl;
if(vec.size()>0)
for(size_t i=0; i<vec.size(); ++i)cout<<vec[i]<<' ';
cout<<endl;
}
 
//это использовано при отладке ( в коде не тоже вызывается )
void show_vec(vector<char> &vec, string name="")
{
if(name!="")cout<<name<<endl;
if(vec.size()>0)
for(size_t i=0; i<vec.size(); ++i)cout<<(short)vec[i]<<' ';
cout<<endl;
}
 
//имея сложение можно ещё умножать и возводить в степень
//это не эффективно, но будет работать
//потом можно пересмотреть код и поработать над эффективностью
//реализовав уменожение не посредством сложения, а как-то быстрее
void long_add(vector<char> &first, vector<char> &second, vector<char> &retV)
{
retV.clear();
vector<char> retVec;
typedef vector<char>::size_type Vec_t ; 
Vec_t flen=first.size();
Vec_t slen=second.size();
 
Vec_t biglen=max(flen, slen);
Vec_t smallen=min(flen, slen);
 
 
vector<char> bigVec = first;
vector<char> smallVec = second;
 
if(biglen!=smallen)
{
bigVec = biglen==first.size()? first : second;
smallVec = smallen==first.size()? first : second;
}
 
if(!smallen)
{   
retVec=bigVec;
return;
}
 
int  overlap=0, current, numFromSmall, indInSmall = smallen-1, rate=10;
for(int i = (int)biglen-1; i>-1; --i)
{
 
if(indInSmall>-1) numFromSmall = smallVec[indInSmall--];
else numFromSmall = 0;
current=overlap+bigVec[i]+numFromSmall;
 
overlap=current/rate;
retVec.push_back(current%rate);
 
}
if(overlap>0)
{
current=overlap;
overlap=current/rate;
retVec.push_back(current%rate);
}
if(overlap>0)retVec.push_back(overlap);
 
Vec_t l_rev = retVec.size();
 
for(int i=(int)l_rev-1; i>-1; --i)
retV.push_back(retVec[i]);
}
 
//умножение использует сложение
void long_multiply(size_t n, vector<char> &src, vector<char> &retV) 
{
retV.clear();
if(n==0)
{
retV.push_back(0);
return;
}
if(n==1)
{
retV=src;
return;
}
 
vector<char> to_add=src;
for(size_t i=1; i<n; ++i)
{
long_add(src, to_add, retV);
to_add=retV;
}
}
 
//вначале src это вектор из одного символа представляющий число в 16-ричной строке 
//n - номер разряда (считая справа и начиная с нуля)
//фактически src умножается на 16 n раз 
//на каждом шаге растёт длина src а цифры разрядов не превышают 9 (то есть переполнения нет)
//это и есть длинная арифметика
//и получается результирующий вектор соответствующий числу в позиции исходного вектора
//эти число придётся сложить чтобы получить результат представляющий:
//An * 16^n + An-1 * 16^(n-1) + ... + A1 * 16 + A0
void long_vec_from_hex_position(size_t n, vector<char> &src, vector<char> &retV) 
{
retV.clear();
if(n==0)
{
retV=src;
return;
}
long_multiply(16, src, retV);//для изменения счисления можно ввести дополнительный арумент и заменить число 16
src=retV;
long_vec_from_hex_position(n-1, src, retV);
}
 
void long_vec_from_hex_position(vector<char>::size_type n, vector<char> &src) 
{
vector<char> retV;
if(n==0)
{
return;
}
 
for(vector<char>::size_type i=0; i<n; ++i)
{
long_multiply(16, src, retV);
src=retV;
}
}
 
//используя всё перечисленное выше конвертируем 16-ричную строку в 
//десятиричную
void convert_hex_string_to_decimal(string &hex_str, string &dec_str)
{
 
vector<char> vdec, vtemp, vrestmp, vres;
make_vec_from_hexStr(hex_str, vdec);
vrestmp.push_back(0);
typedef vector<char>::size_type Vec_t ; 
Vec_t vdlen=vdec.size();
 
for(Vec_t i=0; i<vdlen; ++i)
{
vtemp.clear();
 
vtemp.push_back(vdec[i]);
long_vec_from_hex_position(vdlen-i-1, vtemp); 
long_add(vtemp, vrestmp, vres);
vrestmp=vres;
}
 Vec_t vreslen=vres.size();
 dec_str.clear();
 for(int i=0; i<vreslen; ++i)dec_str+=vres[i]+'0';
}
 
int main(int argc, char* argv[])
{
 
string hexStr="ABCDEF1";
 
string dec_str;
convert_hex_string_to_decimal(hexStr, dec_str);
 
cout<<dec_str<<endl;
system("pause");
return 0;
}
0
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru