Konwersja między dowolnymi systemami liczbowymi

0

Witam panowie

mam ciekawy problem i może ktoś mi pomoże zrozumieć i wyjaśni jak go rozwiązać. Sprawa na pierwszy rzut oka wydaje się banalna.
Już spieszę z tłumaczenie.

Pytanie brzmi jak zamienić dowolny system liczbowy na dowolny system liczbowy ?

czyli np jak zamienić system siódemkowy na system dwunastkowy, albo system piątkowy na system trójkowy itp ....
W sieci jest mnóstwo przykładów dotyczących zamiany systemu 2 na 8 i na 16 etc etc ble ble ble .. To mnie nie interesuje
szukam algorytmu na zamianę jednego systemu liczbowego na inny i nie chodzi mi o system 10 .

Ogólnie użytkownik podaje dane czyli liczbę dowolną i podaje w jakim ona jest systemie i na jaki system ma być zamieniona ot co ?

Jest na to jakiś algorytm czy się muszę głowić ?
I proszę nie przedstawiajcie przykładów jak zamieniać dwójkowy na ósemkowe etc bo tego się naczytałem w sieci . Teoretycznie czytałem też o schemacie hornera ale to jest algorytm pozwalający zwiększyć szybkość wykonania konwersji z dowolnego systemu na dziesiątkowy ... .

0

Zamieniasz z siódemkowego na dziesiętny i potem z dziesiętnego na dwunastkowy?

1

Najpierw musisz wczytać liczbę od użytkownika. Użytkownik podaje string, nie liczbę. Liczba, sama w sobie, jest niezależna od tego w jakim systemie jest zapisana. Czyli robisz:

liczba wczytaj(string, base):
    liczba wynik = 0
    for i = 0; i < string.size; i++:
        wynik = base * wynik + get_digit(string[i], base)
    return wynik

Ok, teraz masz już liczbę. Pozostaje ją wypisać w wymaganym systemie (tak, to wypisuje znaki w odwrotnej kolejności - odwrócić można np. tablicą):

void print(liczba, base):
    while liczba > 0:
        print_char liczba % base
        liczba = liczba / base

I... tyle.

W sieci jest mnóstwo przykładów dotyczących zamiany systemu 2 na 8 i na 16 etc etc ble ble ble .. To mnie nie interesuje
Gdybyś zrozumiał co tam się dzieje, nie miałbyś problemu z napisaniem własnej konwersji...

czytałem też o schemacie hornera ale to jest algorytm pozwalający zwiększyć szybkość wykonania konwersji z dowolnego systemu na dziesiątkowy
Ciekawa definicja, szkoda że zupełnie błędna...

1

Najpierw schematem Hornera zamieniasz ciąg na liczbę, np mamy system siódemkowy i ciąg 3, 2, 5, 0 - ze schematu Hornera dostajemy ((((3) * 7 + 2) * 7 + 5) * 7 + 0) = 1162
Potem dzielisz aż dostaniesz zero i spisujesz reszty w kolejności odwrotnej, czyli:
1162 / 12 = 96 r 10
96 / 12 = 8 r 0
8 / 12 = 0 r 8
wynik = 80A (zakładając, że A to cyfra 10, a B to cyfra 11, analogicznie jak w hexach)

edit:
no i znowu za późno. idę do sklepu, bo się spóźnię.

ps:
pamiętaj o rozróżnieniu dwóch rzeczy:

  1. ciąg cyfr w jakiejś tam podstawie
  2. liczba (której reprezentacja cię nie interesuje)
0

No tak ale to jest tak na okrętke trochę nie sądzicie najpierw zamienić na liczbę w systemie(10) a potem skonwertować na inną.

Nie ma bezpośredniej drogi ???

0
brudy napisał(a):

No tak ale to jest tak na okrętke trochę nie sądzicie najpierw zamienić na liczbę (10) a potem skonwertować na inną.

Nie ma bezpośredniej drogi ???

To jest bezpośrednia droga.

Liczby w komputerze na których operujesz nie mają systemu, nie konwertujesz w żaden sposób napisu na liczbę (10).

Myślisz błędnie o napisie (ciąg znaków) jak o liczbie - napisanie funkcji konwertującej napis w dowolnym systemie liczbowym na napis w innym systemie liczbowym dopiero byłoby drogą na około (i wymyślaniem koła od nowa).

0
brudy napisał(a):

No tak ale to jest tak na okrętke trochę nie sądzicie najpierw zamienić na liczbę w systemie(10) a potem skonwertować na inną.

Nie ma bezpośredniej drogi ???

Najpierw musisz wczytać liczbę od użytkownika. Użytkownik podaje string, nie liczbę. Liczba, sama w sobie, jest niezależna od tego w jakim systemie jest zapisana. Czyli robisz:

of usera dostaję 3 parametry

  1. number - podana liczba oddzielona np. umownym znakiem powiedzmy - bo np mając system "trzydziestko-wo-dwójkowy" możemy mieć tak 12_31_23 czyli musi być string
  2. w jakim systemie jest ta liczba przekazana czyli np w moim przypadku 32
  3. w jakim systemie ma być skonwertowana , powiedzmy osiemnastko wym

Wibowicie napisałeś :

Najpierw schematem Hornera zamieniasz ciąg na liczbę

ale liczba w naszym zadaniu jest pojęciem względnym , w ludzkim doslownym języku jeśli ktoś mówi o liczbie ma na myśli liczbę w postaci 10 . a my tu mówiąc o liczbie musimy podać także w jakim jest ona systemie .

Algorytmy które podajecie rozumiem i wiem jak działają , chodzi mi tylko o bezpośrednią zamianę . Rozumiecie o co mi chodzi ???

0

Możesz dzielić pisemnie. 12 w systemie siódemkowym to 15. A więc:

  165
 -----
 3250 : 15
-15
 --
 145
-132
  ---
  130
 -114
  ---
   13

13 w systemie siódemkowym to A w systemie dwunastkowym.

No to jedziemy dalej:

  11
 ---
 165 : 15
-15
 --
  15
 -15
 ---
  ==

0 w systemie siódemkowym to 0 w systemie dwunastkowym. No i na koniec oczywiste:

  0
 --
 11 : 15
- 0
 --
 11

11 w systemie siódemkowym to 8 w systemie dwunastkowym.

Składając reszty w odwrotnej kolejności dostajemy 80A czyli to co powinniśmy dostać.

Jest to algorytm bezpośredni, ale moim zdaniem dużo wolniejszy niż algortym 'pośredni', na który autor tematu narzeka.

Innym sposobem mogłoby być stablicowanie, tzn np tablicujemy liczby siódemkowe: 1, 2, ... 6, 10, 20, ... 60, 100, 200, ... 600, itd tzn ich reprezentację dwunastkową, a następnie mapujemy cyfry wejściowe na te reprezentacje dwunastkowe i je dodajemy w słupku. To mogłoby być szybsze jeśli nie liczyć złożoności tablicowania. To dodawanie, mapowanie i tablicowanie można dodatkowo zrównoleglić.

Teoretycznie czytałem też o schemacie hornera ale to jest algorytm pozwalający zwiększyć szybkość wykonania konwersji z dowolnego systemu na dziesiątkowy ... .

Ale dlaczego dziesiątkowy? Co ma takiego system dziesiątkowy, że algorytmy bez niego nie działają?

0

Wątek powinien wylecieć do kosza za temat, ale że jest dużo merytorycznych odpowiedzi, to tylko temat zmieniłem.
Następnym razem za zły temat będzie 50zł mandatu.

0

Tak dla zainteresowanych na przyszłość. Prosta metoda - i prosta implementacja na dowolny język programowania.

Dla liczby całkowitej:

  • dzielimy liczbę przez podstawę nowego systemu i odpisujemy resztę z tego dzielenia (to kolejne cyfry w liczbie w nowym systemie), a z całkowitym wynikiem dzielenia postępujesz tak samo (rekurencyjnie)

Dla liczby ułamkowej

  • mnożymy część ułamkową liczby przez podstawę nowego systemu i odpisujemy od wyniku część całkowitą (to kolejne cyfry po przecinku w liczbie ułamkowej w nowym systemie), a z pozostałą częścią ułamkową postępujesz tak samo (rekurencyjnie)

Można sobie przeliczać na stronce www on line - z różnych systemów na inne, dowolne liczby:

http://systemyliczbowe.urfu.pl

0

Tu masz konwersje z dowolnego na dowolny system: http://4programmers.net/Forum/C_i_C++/228212-konwersja_systemow_liczbowych?p=1005274#id1005274
Co prawda w C zaś w javie będzie podobnie.

Może dodam przykładowy kod:

import java.io.*;
import java.util.*;
 
class sys
  {
   static String digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
   public static boolean inrange(int left,int value,int right)
     {
      return (left<=value)&&(value<right);
     }
   public static boolean good(int sys)
     {
      return inrange(2,sys,37);
     }
   public static boolean good(String inp,int sys)
     {
      if(!good(sys)) return false;
      for(int i=0;i<inp.length();++i) if(!inrange(0,digits.indexOf(inp.charAt(i)),sys)) return false;
      return true;
     }
   public static String conv(int sysin,int sysout,String inp)
     {
      StringBuilder out=new StringBuilder("0");
      for(int i=0;i<inp.length();++i)
        {
         int m=0,p=digits.indexOf(inp.charAt(i));
         for(int r=out.length()-1;r>=0;--r)
           {
            m=digits.indexOf(out.charAt(r))*sysin+p;
            p=m/sysout;
            out.setCharAt(r,digits.charAt(m-p*sysout));
           }
         for(m=p;p>0;m=p)
           {
            p=m/sysout;
            out.insert(0,digits.charAt(m-p*sysout));
           }
        }
      return out.toString();
     }
  }

public class SysConvAlg
  {
   private static Scanner sin=new Scanner(System.in);
   
   public static void main(String[] args) throws Exception
     {
      while(true)
        {
         try
           {
            int sysin,sysout;
            String inp;
            System.out.print("\rsystem wejsciowy: ");
            sysin=sin.nextInt();
            System.out.print("\rsystem wyjsciowy: ");
            sysout=sin.nextInt();
            if((sysin==0)&&(sysout==0)) break;
            System.out.print("\rliczba wejsciowa: ");
            inp=sin.next().toUpperCase();
            if(sys.good(inp,sysin)&&sys.good(sysout)) System.out.print(sys.conv(sysin,sysout,inp)+"\n");
            else System.out.print("Blad wprowadzenia\n");
           }
         catch(Exception e)
           {
            sin.next();
            System.out.print("\rBlad wprowadzenia\n");
           }
        }
     }
  }

1 użytkowników online, w tym zalogowanych: 0, gości: 1