vvoid |
Отправлено: 15.11.2004, 16:42 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
Всем приветы!!!
Подскажите кто знает, как реализовать на Builder-e перевод числа ЛЮБОЙ РАЗРЯДНОСТИ из одной системы исчисления в другую. Замечу, что использование метода умножения на вес разряда не подходит, по причине ограничености числового диапазона целочисленных типов языка С++.
Заранее спасибо!!!
Жду методов решений.
Отредактировано vvoid — 16/11/2004, 18:49
|
|
Ajgor |
Отправлено: 15.11.2004, 17:31 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 23
|
Меня тоже это интересует... |
|
Konstantine |
Отправлено: 15.11.2004, 18:11 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
какие диапазоны чисел?
и какая макс. разрядность СИ
|
|
vvoid |
Отправлено: 15.11.2004, 18:29 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
Обычный Си билдер5 на 32-разрядном компе.
А разрядность ну к примеру числа порядка 62^10 ~ 62 ^15 (разрядность считать не охота). Да вообще разрядность не должна ограничивать алгоритм!
Отредактировано vvoid — 15/11/2004, 19:37
|
|
Konstantine |
Отправлено: 16.11.2004, 09:48 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
ну... предлагаю задавать числа в виде массива char, в которомм каждый байт — это цифра числа... разрядность сис-мы исчисления в 256 — хватит?
А далее (если случай общий) — необходимо применить обычный алгоритм перевода, если кто не знает — напишу, только необходимо применить его к алгоритмам компа.
ну.. что-то типа этого:
А — исходное число в сис-ме с порядком а ; Ai — i-ая цифра
В — результат сис-ме с порядком b
T — временное число в сис-ме с порядком а
/ — целочисленное деление в в сис-ме с порядком а
% — остаток от деления в в сис-ме с порядком а
A1-самый младший разряд числа А
CODE | i=1
do
T=A; Вi=T%b; T=T/b; i++
while (T>0)
|
остаётся только организавать вычисления с этими числами в СИ с нужным порядком
Отредактировано Konstantine — 16/11/2004, 10:58
|
|
Guest |
Отправлено: 16.11.2004, 10:44 |
|
Не зарегистрирован
|
Пришла пора вспомнить о двоично-десятичной арифметике процессора 86 (интересно, дожила она до пентиума?) |
|
Konstantine |
Отправлено: 16.11.2004, 11:03 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
нет, здесь нада все вычисления программно делать... а к чему тут 2-10 арифметика??? разве что посмотреть алгоритмы... ну сложение — знаю... вот:
все неописанные типы описаны в предыд. моём сообщении.
A,B,T — числа СИ с порядком а
size — макс. размерность (кол-во цифр) чисел
вот:CODE | short t=0;
for(int i=0;i<size;i++)
{
t=A[i]+B[i]+t/a;
T[i]=t%a;
}
| ну а деление — Я так просто (без компилятора) не напишу
|
|
Guest |
Отправлено: 16.11.2004, 11:10 |
|
Не зарегистрирован
|
QUOTE | а к чему тут 2-10 арифметика |
Да так, мысли в слух. Просто вычисления далет сразу процессор, а это всегда быстее набора его же команд. |
|
Konstantine |
Отправлено: 16.11.2004, 11:23 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
Я ж и говорю — в условии — общий случай (без привязки к порядку), а 2-10 арифметика — это как раз и есть привязка. Хотя то что Я предложил — подобно, и носит более общий характер
|
|
vvoid |
Отправлено: 16.11.2004, 15:48 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
QUOTE (Konstantine @ 16/11/2004, 10:50) | остаётся только организавать вычисления с этими числами в СИ с нужным порядком |
Это то и есть самая большая проблема. И чтоб не играться с этим я и затеял эту тему а форуме, может есть какой-нибудь более прикольный алгоритм перевода чисел!
А если такого алгоритма никто не значет, подскажите, как по-проще (классический метод довольно громоздкий для реализации)орагнизовать в данном случае деление и взятие модуля для этих байт-массивов!
Отредактировано vvoid — 16/11/2004, 16:54
|
|
Konstantine |
Отправлено: 16.11.2004, 16:06 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
ну чё громоздкий? если нада, то могу и посидеть.... за пиво
а камню за 10^8 оп.сек всё равна, если нада программеру
|
|
vvoid |
Отправлено: 16.11.2004, 17:16 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
2 Konstantine
А сам алгоритм не набросаешь??? А там может когда-нить встретимся, пива попьём. ;-)
|
|
Konstantine |
Отправлено: 16.11.2004, 17:23 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
эхх.. наверно пойдут безсонные ночи... а с пивом ... придётся
скажи сразу — то что Я писАл наброски — подойдут? или что-то поправить т.к. — (см. 1-ю подпись)
Отредактировано Konstantine — 16/11/2004, 18:27
|
|
vvoid |
Отправлено: 16.11.2004, 17:59 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
Да я думаю код — не главное, меня сами алгоритмы интересует.
Как организовать то же деление чисел, представленных, как массив байтов, причем в любой системе исчисления.
|
|
Konstantine |
Отправлено: 16.11.2004, 18:14 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
еле успел... на последней минуте Я прочитал
|
|
Serega |
Отправлено: 17.11.2004, 12:08 |
|
Не зарегистрирован
|
Ну что, ребят, разобрались с переводом чисел между системами исчисления? Если что — есть прога, написанная, правда, "очень" давно, "по молодости"; в универе лаба по "численным методам..." была такая. Прога написана для BC 3.1, но, главное, алгаритм... Ежели надо — пишите на мыло, поищу, пришлю. Переводит она между 0 и 36-тичной системами, но возможно доработать ;-) хотя сейчас уже на лучший вариант она, наверное, не претендует. |
|
Konstantine |
Отправлено: 17.11.2004, 12:16 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
Я уже написАл... правда не принёс (дискеты не было), но в ней нада алгоритмы пооптимизировать.
Serega, тут Я разрабатую класс для работы с числами любой системы исчисления (с переводом между ними) и любого количества цифр (пока мозгов в компе зватит).
Если есть алгоритм ускоренного деления — покажи, а то Я не могу найти у себя.. а где-то был
|
|
Serega |
Отправлено: 17.11.2004, 12:18 |
|
Не зарегистрирован
|
Мыльце забыл : tempfils@mail.ru |
|
Serega |
Отправлено: 17.11.2004, 12:33 |
|
Не зарегистрирован
|
А, кстати, вот и нашел енту прогу! Могешь сравнить алгоритмы...
воткну код, ежели модераторы не против:
CODE | [COLOR=green]
// Перевод в системы исчисления по схеме Горнера
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
int sys_isch(int SysIn,char *s,char *z,int SysOut);
int main()
{
int SysIn,SysOut;
char *s,temp,*z;
int x;
do{
clrscr();
cout<<"Перевод числа из одной системы исчисления в другую (0-36)";
cout<<"\nВведите соответственно число и его систему исчисления\n";
cin>>s;
cin>>SysIn;
if(SysIn>36){cout<<"\n\nИзвините, но основание должно быть не больше 36";getch();continue;}
cout<<"\nВведите основание системы исчисления, в которую нужно пеобразовать\n";
cin>>SysOut;
if(SysOut>36){cout<<"\n\nИзвините, но основание должно быть не больше 36";getch();continue;}
sys_isch(SysIn,s,z,SysOut);
cout<<"\nВ новой системе число = "<<z;
cout<<"\n\n\nДля выхода нажмите Q\n";
cin>>temp;
}while(temp!='q');
return 0;
}
int sys_isch(int SysIn,char *s,char *z,int SysOut)
{int x=0;
while(*s)x=x*SysIn+*s++-((*s>='0'&&*s<='9')?'0':'A'-10);
itoa(x,z,SysOut);
return 1;
}[/COLOR] |
-это, вероятно, и имел ввиду Konstantine ?! Возможно я не прав... |
|
Konstantine |
Отправлено: 17.11.2004, 12:55 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
ну функцию так сходу полностью не понял (мудрёно написано), но я вижу там всё равно через int идёт... а в задании говорится, что диапазон инта не подходит.
|
|
Guest |
Отправлено: 17.11.2004, 13:07 |
|
Не зарегистрирован
|
Konstantine
Ну разбирайся!!! А тот инт, который "бросился в глаза", там большой роли не играет, т.к. число изначально представляется строкой!!!!!!!!!!!!!!! , а потом преобразуется куда надо...
Мне хватало int'а. |
|
vvoid |
Отправлено: 17.11.2004, 16:27 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
В прогеSerega-и есть явное oграничение (и не одно).
Там идёт сначала перевод в десятичную систему, и результат пишется в тот злополучный int i. Этот перевод делается с использованием бычного умножения, сложения, вычитания интов. А разрядность типа int, как известно ограничивается разрядностью проца (32 бита, чаще всего. Пока что ) Тут и возникает первая проблема: полученное число не может быть больше (2^32) — 1 = 4 294 967 295.
Ну а вторая проблема — использование для перевода из десятичной в n-ричную функции itoa — не красиво это, криво!
|
|
vvoid |
Отправлено: 17.11.2004, 16:30 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
2 Konstantine
Набросай для начала хоть какой-нибудь алгоритм для деления чисел любой разрядности и в любой системе, не обязательно его жёстко оптимизить. Или скажи, где можно его подсмотреть!
Да и ещё, как ты в принципе организовываешь работу с этими числами?
Извини за настырность, нетерплячка муляет!!!
|
|
Konstantine |
Отправлено: 17.11.2004, 16:56 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
У меня — число запис. в байтовый(можно и увеличить) массив (1 цифра числа — в свой байт)... пока ограничение на 65кБ (size задан USHORT) -
но можно увеличить... также (кроме массива) в этом классе хранится размер и показатель системы измерения (базис)
перевод без других операций невозможен... уже есть:
- сложение
- вычитание
- сравнение
- деление
- взять число из:
- десятичного инта
- строки
- числа с другим базисом
не боись... наверно завтра принесу....
P.S.: пиво в хол-к поставь
|
|
vvoid |
Отправлено: 17.11.2004, 17:27 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
Ладно, наберусь терпения и буду ждать до посинения ))).
Я тут и по инету искал, но чё-то ничего путёвого яндекс мне не выкинул((
|
|
Konstantine |
Отправлено: 18.11.2004, 11:12 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
Ладна... держи вот.... разбирайся, развивай дальше и т.д. если есть вопросы — пиши...
P.S.: ВСЕМ, кто будет этот класс использовать — делать приписку "Created by Konstantine" во всей сопровождающей информации
Отредактировано Konstantine — 18/11/2004, 18:30
|
|
Konstantine |
Отправлено: 18.11.2004, 11:34 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
вот комментарии к методам класса:
CODE | class Huge
{
private:
UCHAR *digit;
USHORT size;
UCHAR basis;
public:
Huge(UCHAR basic=10,USHORT size=10);
Huge(const Huge &s);
~Huge();
void New(UCHAR basic=10,USHORT size=10,bool nul=true); 3-й параметр — обнуление числа
AnsiString ToStr();
void FromStr(AnsiString s); // взять из строки
Huge& operator =(const Huge &dest);
Huge& operator +=(const Huge &dest);
Huge& operator -=(const Huge &dest);
Huge& operator ++();
Huge& operator --();
bool operator >(const Huge &dest);
bool operator <(const Huge &dest);
bool operator >=(const Huge &dest);
bool operator <=(const Huge &dest);
bool operator ==(const Huge &dest);
bool operator !=(const Huge &dest);
Huge& operator <<(int c); // сдвиг влево (увелич.число) на с знаков
Huge& operator >>(int c); // сдвиг вправо (уменьш.число) на с знаков
void Multiple(UCHAR mul); // умножение на цифру
void Multiple(const Huge &mul); //умножение на число
UINT DivideP(const Huge &div); //деление перебором (при больших числах неэффективно)
UINT Divide(const Huge &div); //деление
UINT ToInt();
void FromInt(UINT in); // взять из инта
void FromHuge(const Huge &Dest); // взять из числа с другим базисом
USHORT Length(); // количество значащих цифр (без передних нулей)
void SetSize(USHORT NewSize); // изменить размер
void GetFrom(const Huge &Source,USHORT From,USHORT Len); // взять часть числа
}; |
в сдвиговых — если с=0, то до упора — сдвиг пока старший (младший) разряд станет ненулевым
Отредактировано Konstantine — 18/11/2004, 12:40
|
|
vvoid |
Отправлено: 18.11.2004, 15:54 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
2 Konstantine
Огромное спасибо, теперь надо время, чтоб разобраться.
Заглядывай, думаю вопросы будут ;-)
|
|
vvoid |
Отправлено: 18.11.2004, 17:15 |
|
Машинист паровоза
Группа: Участник
Сообщений: 171
|
Функции деления, я так понял, возвращают остаток от деления.
Верно?
|
|
Konstantine |
Отправлено: 18.11.2004, 17:26 |
|
Мастер участка
Группа: Модератор
Сообщений: 545
|
да, переведя в инт.... (я просто забыл как можно локальный класс вернуть)... названия переменных я старался понятными делать
P.S.(для тех что предыдущие сообщения уже не читает): ВСЕМ, кто будет этот класс использовать — делать приписку "Created by Konstantine" во всей сопровождающей информации
Отредактировано Konstantine — 18/11/2004, 18:34
|
|