Перевод вещественных чисел в разные системы счисления
Поставлена задача:
Разработать программу представления вещественного числа в одной из четырех систем счисления (двоичная, десятичная, восьмеричная, шестнадцатеричная).
Программа должна выполнять чтение числа в одной из систем счисления и переводить в остальные системы счисления на выбор пользователя. Реализовать интерфейс пользователя.
Я пытался решить поставленную задачу различными способами, но не догадался как можно решить проблему с переводом в десятичную часть, для дальнейшей программы.
#include <iostream>
#include <cmath>
#include <locale.h>
using namespace std;
char digit(int num) // Отображение шестнадцатеричной цифры
{
switch (num) {
case 0: return '0';
case 1: return '1';
case 2: return '2';
case 3: return '3';
case 4: return '4';
case 5: return '5';
case 6: return '6';
case 7: return '7';
case 8: return '8';
case 9: return '9';
case 10: return 'A';
case 11: return 'B';
case 12: return 'C';
case 13: return 'D';
case 14: return 'E';
case 15: return 'F';
}
}
using namespace std;
int end_ch_int(int a, int p, char *s)// Получение целой части числа
{
int num = a;
int rest = num % p;
num /= p;
if (num == 0)
{
s[0] = digit(rest); return 1;
}
int k = end_ch_int(num, p, s);
s[k++] = digit(rest);
return k;
}
void end_ch_double(double a, int p, char *s)// Получение дробной части числа
{
int iter = 0;
int k = 0;
double a1 = a;
do {
a1 = a1 * p;
int num = (a1);
s[k++] = digit(num);
a1 -= a1;
iter++;
} while (a1 > 0.00000001 && iter < 10);
s[k] = '\0';
}
int main()
{
double a;
char s[80] = { 0 };
int p,d;
system("cls");
cout << "Введите число: ";
cin >> a;
cout << "Введите начальную системы счисления: ";
cin >> d;
cout << "Введите конечную систему счисления: ";
cin >> p;
int k = end_ch_int(a, p, s);
s[k++] = ',';
end_ch_double(a-a, p, &s[k]);
cout << s;
cin.get(); cin.get();
return 0;
}
Ответы (1 шт):
Ну, я тут попробовал набросать. Погрешность накапливается быстро...
Вобщем, только для положительных чисел, только для систем от 2 до 36, с ограниченным количеством переводов между системами (накопление ошибки)...
int num(char c) // цифра в некоторой системе счисления
{
const char digs[] = "0123456789abcdefghijklmnopqrstuvwxyz";
return int(strchr(digs, tolower(c)) - digs);
}
// Строка с числом в системе счисления base в double
// Защиты от дурака нет!
double toNum(const char* s, int base)
{
if (base < 2 || base > 36) throw range_error("Wrong base");
const char* c;
double r = 0;
for (c = s; *c && *c != '.'; ++c)
r = r * base + num(*c);
if (*c == '.')
{
for (double bs = base; *++c && bs > 0; bs *= base)
r += num(*c) / bs;
}
return r;
}
// Число double в строку в системе счисления base, с prec знаков после точки
// Защиты от дурака нет!
string fromNum(double x, int base, int prec = 6)
{
const char digs[] = "0123456789abcdefghijklmnopqrstuvwxyz";
if (base < 2 || base > 36) throw range_error("Wrong base");
int d = floor(x);
string r;
if (d == 0) r = "0";
else
{
while (d)
{
r += digs[d % base];
d /= base;
}
reverse(r.begin(), r.end());
}
x = x - floor(x);
if (x && prec > 0)
{
r += '.';
for (int i = 0; i < prec; ++i)
{
x *= base;
r += digs[int(x)];
x = x - floor(x);
}
}
return r;
}
// Простенький тест...
int main(int argc, char* argv[])
{
string seven = "1234.56";
cout << "orig: " << seven << endl;
double x = toNum(seven.c_str(), 7);
cout << "x = " << x << endl;
string elev = fromNum(x, 11, 20);
cout << "11: " << elev << endl;
x = toNum(elev.c_str(), 11);
cout << "x = " << x << endl;
elev = fromNum(x, 4, 20);
cout << "4: " << elev << endl;
x = toNum(elev.c_str(), 4);
cout << "x = " << x << endl;
elev = fromNum(x, 7, 20);
cout << "7: " << elev << endl;
}
Смотреть здесь...