home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / turbo4 / bcdreal.pas < prev    next >
Pascal/Delphi Source File  |  1987-12-08  |  5KB  |  156 lines

  1.  
  2. {           Copyright (c) 1985, 87 by Borland International, Inc.            }
  3.  
  4. unit BCDReal;
  5.  
  6. { Die BCD-Version von Turbo Pascal 3.0 (TURBOBCD.COM) unterstützt
  7.   binär codierte Dezimalzahlen mit 18 signifikanten Stellen und einem
  8.   Rechenbereich von 1E-63 bis 1E+63, die jeweils 10 Bytes Speicherplatz
  9.   belegen.
  10.   Der Datentyp BCD ist in der Version 4.0 nicht definiert - deshalb enthält
  11.   dieses Unit eine Routine, die BCD-Werte der Version 3.0 entweder in
  12.   Werte des Typs Real (mit jeweils 6 Bytes) oder in Werte des Typs Extended
  13.   (mit jeweils 10 Bytes) konvertiert. Für die Konvertierung in den Typ
  14.   Extended wird ein numerischer Coprozessor (8087) vorausgesetzt.
  15.  
  16.   Vor der Konvertierung eines 3.0-BCD-Programms sollten Sie den zukünftig
  17.   verwendeten Datentyp festlegen. Wenn Ihr Computer nicht mit einem 8087
  18.   ausgerüstet ist oder das Programm auf Computern ohne 8087 verwendet
  19.   werden soll, müssen Sie Variablen des Typs Real (6 Bytes, 11-12 Dezimal-
  20.   stellen Genauigkeit, Bereich 2.9E-39..1.7E+38) verwenden. Dieser Typ wird
  21.   auch von der Standard-Version des 3.0-Compilers unterstützt.
  22.   Wenn Sie über einen 8087 verfügen, sollten sie den Typ Extended anstelle
  23.   von BCD verwenden, der 10 Bytes belegt, 19-20 Dezimalstellen Genauigkeit
  24.   und einen Rechenbereich von 1.9E-4951..1.1E+4932 bietet.
  25.   Nach der Konvertierung des Programms sollten Sie ein weiteres Programm zur
  26.   Konvertierung existierender Dateien schreiben, das die in diesem Unit
  27.   deklarierte Routine zur Umsetzung verwendet.
  28.  
  29.   Der hier deklarierte Typ Decimal entspricht den BCD-Variablen der Version
  30.   3.0; die Routine DecToFloat konvertiert eine derartige Variable - je nach
  31.   Stand des Compiler-Schalters $N - in das Format Real bzw. Extended.
  32.  
  33.   Um ein Programm zu compilieren, das das Unit BCD benutzt, setzen Sie zuerst
  34.   den Schalter $N (mit O/C/Numeric processing) entsprechend (für Real: auf
  35.   "Software", für Extended: auf "Hardware") und rufen den Compiler dann
  36.   über C/Build auf. Dadurch wird auch das Unit BCD neu compiliert.
  37.  
  38.   Das folgende Programmbeispiel zeigt die Konvertierung einer 3.0-Datei,
  39.   deren Records einzelne BCD-Felder enthalten:
  40.     - Definition eines Äquivalents des 3.0-Records (OldDataRec) unter
  41.       Verwendung des Pseudo-Typs Decimal
  42.     - Definition eines 4.0-Records, desssen entsprechende Felder als
  43.       Typ Float deklariert sind. Float steht je nach Stand des Schalters
  44.       $N entweder für den Typ Real oder den Typ Extended.
  45.     - Während der Umsetzung werden alle Felder mit BCD-Werten über DecToFloat
  46.       konvertiert -- die restlichen Felder der Records werden dagegen direkt
  47.       in die neue Datei kopiert.
  48.  
  49.   program ConvertBCD;    (* Dieses Beispielprogramm ist Teil eines Kommentars *)
  50.   uses BCDReal;
  51.   type
  52.     OldDataRec = record
  53.                    Name: string[15];
  54.                    InPrice,OutPrice: Decimal;
  55.                    InStock,MinStock: Integer;
  56.                  end;
  57.     NewDataRec = record
  58.                    Name: string[15];
  59.                    InPrice,OutPrice: Float;
  60.                    InStock,MinStock: Integer;
  61.                  end;
  62.   var
  63.     OldFile: file of OldDataRec;
  64.     NewFile: file of NewDataRec;
  65.     Old: OldDataRec;
  66.     New: NewDataRec;
  67.   begin
  68.     Assign(OldFile,'OLDFILE.DTA'); Reset(F);
  69.     Assign(NewFile,'NEWFILE.DTA'); Rewrite(F);
  70.     while not Eof(OldFile) do
  71.     begin
  72.       Read(OldFile,Old);
  73.       New.Name     := Old.Name;
  74.       New.InPrice  := DecToFloat(Old.InPrice);
  75.       New.OutPrice := DecToFloat(Old.OutPrice);
  76.       New.InStock  := Old.InStock;
  77.       New.MinStock := Old.MinStock;
  78.       Write(NewFile,New);
  79.     end;
  80.     Close(OldFile);
  81.     Close(NewFile);
  82.   end.
  83.  
  84.   Der Rechenbereich einer BCD-Realvariablen ist größer als der des Typs
  85.   Real: DecToFloat begrenzt deshalb Werte > 1.0E+38 auf 1.0E+38; Werte kleiner
  86.   2.9E-39 werden als 0 konvertiert.
  87. }
  88.  
  89. interface
  90.  
  91. type
  92.   Decimal = array[0..9] of Byte;
  93. {$IFOPT N-}
  94.   Float = Real;   { kein Coprozessor }
  95. {$ELSE}
  96.   Float = Extended;
  97. {$ENDIF}
  98.  
  99. function DecToFloat(var D: Decimal): Float;
  100.  
  101. implementation
  102.  
  103. function DecToFloat(var D: Decimal): Float;
  104. var
  105.   E,L,P: Integer;
  106.   V: Float;
  107.  
  108. function Power10(E: Integer): Float;
  109. var
  110.   I: Integer;
  111.   P: Float;
  112. begin
  113.   I:=0; P:=1.0;
  114.   repeat
  115.     if Odd(E) then
  116.     case I of
  117.       0: P:=P*1E1;
  118.       1: P:=P*1E2;
  119.       2: P:=P*1E4;
  120.       3: P:=P*1E8;
  121.       4: P:=P*1E16;
  122.       5: P:=P*1E32;
  123.     end;
  124.     E:=E shr 1; Inc(I);
  125.   until E=0;
  126.   Power10:=P;
  127. end;
  128.  
  129. begin
  130. {$IFOPT N-}
  131.   if D[0] and $7F>38+$3F then V:=10E37 else
  132. {$ENDIF}
  133.   begin
  134.     V:=0.0; L:=1;
  135.     while (L<=9) and (D[L]=0) do
  136.      Inc(L);
  137.     if L<=9 then
  138.     begin
  139.       for P:=9 downto L do
  140.       begin
  141.         V:=V*100.0+((D[P] shr 4)*10+D[P] and $0F);
  142.       end;
  143.       E:=D[0] and $7F-($3F+(10-L)*2);
  144.       if E>=0 then V:=V*Power10(E)
  145.        else begin
  146.         if E<-32 then V:=V/1E32; E:=E+32;
  147.         V:=V/Power10(-E);
  148.        end;
  149.     end;
  150.   end;
  151.   if D[0] and $80=0 then DecToFloat:=V
  152.     else DecToFloat:=-V;
  153. end;
  154.  
  155. end.
  156.