Bergervei/Pascal-Dualzahlen

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Pascal</language>
== Umwandlung einer dezimalen Gleitkommazahl in eine Dualzahl ==

Die nachfolgende Abbildung demonstriert die Algorithmen für die Umwandlung des ganzzahligen bzw. gebrochenen Anteils der Dezimalzahl in den jeweiligen Anteil der Dualzahl:

<blockquote>[[Bild: DezimalToDual1.gif]]</blockquote>

Dualzahlen mit Nachkommastellen sowie ihre ganzzahligen und gebrochenen Anteile werden als Zeichenketten (''Strings'') repräsentiert.

<code id="4d347fb2625b0">
function ganztodual(zahl: real): string;
 var dualstring    : string;
     rest, ganzzahl: integer;
 begin
  ganzzahl:=trunc(zahl);
  while ganzzahl>0 do
  begin
   rest:=ganzzahl mod 2;
   ganzzahl:=ganzzahl div 2;  
   dualstring:=inttostr(Rest)+dualstring;
  end;
  if length(dualstring)=0 then dualstring:='0';
  result:=dualstring;
 end;

function gebrtodual(zahl: real): string;
 var dualstring: string;
     zaehler   : integer;
     gebrzahl  : real;
 begin
  dualstring:='';
  zaehler:=0;
  gebrzahl:= frac(Zahl);
  while (gebrzahl>0) and (zaehler<32) do
  begin 
   gebrzahl:=gebrzahl*2;
   dualstring:=dualstring+inttostr(trunc(gebrzahl));
   gebrzahl:=frac(gebrzahl);
   zaehler:=zaehler+1;
  end;
  result:=dualstring;
 end;

function dezimaltodual(zahl: real): string;
 begin
  if frac(zahl)=0 then
   result:=ganztodual(zahl)
  else
   result:=ganztodual(zahl)+'.'+gebrtodual(zahl);
 end;
</code>

<run id="4d347fb2626b5">
writeln(dezimaltodual(12.625));
</run>

== Umwandlung einer Dualzahl in eine dezimale Gleitkommazahl ==

In ähnlicher Weise können auch Dualzahlen mit Nachkommastellen, die ebenfalls als Zeichenketten vorliegen, in Dezimalzahlen konvertiert werden. Das nachfolgende Schema verdeutlicht wieder die entsprechenden Algorithmen:

<blockquote>[[Bild: DualToDezimal1.gif]]</blockquote>

<code id="4d34be1822ca6">
function korrekt(dualstring: string): boolean;
 var teststring: string;
     nr, i     : integer;
     test      : boolean;
 begin
  nr:=pos('.',dualstring);
  teststring:=copy(dualstring,0,nr-1);
  if nr>0 then
   teststring:=teststring+copy(dualstring,nr,length(dualstring)-nr);
  test:=true;
  for i:=1 to length(teststring) do
   test:=test and ((teststring[i]='0') or (teststring[i]='1'));
  result:=test;
 end;

function ganzzerlegen(dualstring: string): string;
 var teilstring: string;
     nr        : integer;
 begin
  teilstring:='';
  if korrekt(dualstring) then
  begin
   teilstring:=dualstring;
   nr:=pos('.',dualstring);
   if nr>0 then teilstring:=copy(dualstring,0,nr-1);
  end;
  result:=teilstring;
 end;

function gebrzerlegen(dualstring: string): string;
 var teilstring: string;
     nr        : integer;
 begin
  teilstring:='';
  if korrekt(dualstring) then
  begin
   nr:=pos('.',dualstring);
   if nr>0 then teilstring:=copy(dualstring,nr,length(dualstring)-nr);
  end;
  result:=teilstring;
 end;

function dualtodezimal(dualstring: string): real;
 var teilstring1, teilstring2: string;
     summe1, summe2, potenz  : real;
     i: integer;
 begin
  teilstring1:=ganzzerlegen(dualstring);
  teilstring2:=gebrzerlegen(dualstring);
  summe1:=0; potenz:=1;
  for i:=length(teilstring1) downto 1 do
  begin
   summe1:=summe1+potenz*strtoint(teilstring1[i]);
   potenz:=potenz*2;
  end;
  summe2:=0; potenz:=1;
  for i:=1 to length(teilstring2) do
  begin
   potenz:=potenz/2;
   summe2:=summe2+potenz*strtoint(teilstring2[i]);
  end;
  result:=summe1+summe2;
 end;
</code>

<run id="4d347fb26270f">
writeln(dualtodezimal('1100.101'));
</run>