home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / turbo55 / tp55 / turbo3 / bcd.pas next >
Encoding:
Pascal/Delphi Source File  |  1989-05-02  |  4.8 KB  |  158 lines

  1.  
  2. { Turbo BCD }
  3. { Copyright (c) 1985, 1989 by Borland International, Inc. }
  4.  
  5. unit BCD;
  6.  
  7. { The BCD version of Turbo Pascal 3.0 (TURBOBCD.COM) supports
  8.   10-byte binary coded decimal reals with 18 significant digits
  9.   and a range of 1E-63 to 1E+63. The BCD real data type is not
  10.   supported by Turbo Pascal 5.5, and this unit provides a routine
  11.   for converting 3.0 BCD reals to 6-byte reals (software reals)
  12.   or 10-byte 8087 extended reals.
  13.  
  14.   Before you convert a Turbo Pascal 3.0 BCD program to run under
  15.   5.5, you need to select a 5.5 real data type for your floating
  16.   point values. If you do not have an 8087, or if your program is
  17.   to run on machines without an 8087, your only option is to use
  18.   the familiar 6-byte Real, which provides 11-12 significant digits
  19.   with a range of 2.9E-39 to 1.7E+38. This type is also supported by
  20.   the standard version of Turbo Pascal 3.0. If you are planning to
  21.   use the 8087, we suggest you select the 10-byte Extended type,
  22.   which provides 19-20 significant digits with a range of 1.9E-4951
  23.   to 1.1E+4932. Once you have selected a data type, you need to write
  24.   a conversion program that translates your old data files using the
  25.   conversion routine provided here.
  26.  
  27.   The Decimal type defined by this unit corresponds to the 3.0 BCD
  28.   Real, and the DecToFloat routine converts a Decimal variable to a
  29.   6-byte Real or to a 10-byte Extended.
  30.  
  31.   The BCD unit uses conditional compilation constructs to define a
  32.   type Float which is equivalent to either Real or Extended,
  33.   depending on the kind of numeric processing you select (software
  34.   or hardware). To compile a program that uses the BCD unit, first
  35.   select software or hardware floating point, using the Options/
  36.   Compiler/Numeric processing menu, and then do a Compile/Build,
  37.   which automatically recompiles BCD.PAS.
  38.  
  39.   The following program shows how to convert a 3.0 data file that
  40.   contains records with BCD fields. The program defines an equivalent
  41.   of the 3.0 record (OldDataRec) using the Decimal type for fields
  42.   that contain BCD reals. In the corresponding 5.5 record (NewDataRec),
  43.   floating point fields are declared using the Float type, which is
  44.   either Real or Extended depending on the floating point model
  45.   selected. During the conversion, all Decimal fields are converted
  46.   to Float using the DecToFloat function, whereas all non-real fields
  47.   are copied directly.
  48.  
  49.   program ConvertBCD;
  50.   uses BCD;
  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.   The range of a BCD real is larger than that of a 6-byte software
  85.   real. Therefore, when converting to 6-byte reals, BCD values larger
  86.   than 1E+38 are converted to 1E+38, and BCD values less than 2.9E-39
  87.   are converted to zero.
  88. }
  89.  
  90. interface
  91.  
  92. type
  93.   Decimal = array[0..9] of Byte;
  94. {$IFOPT N-}
  95.   Float = Real;
  96. {$ELSE}
  97.   Float = Extended;
  98. {$ENDIF}
  99.  
  100. function DecToFloat(var D: Decimal): Float;
  101.  
  102. implementation
  103.  
  104. function DecToFloat(var D: Decimal): Float;
  105. var
  106.   E,L,P: Integer;
  107.   V: Float;
  108.  
  109. function Power10(E: Integer): Float;
  110. var
  111.   I: Integer;
  112.   P: Float;
  113. begin
  114.   I:=0; P:=1.0;
  115.   repeat
  116.     if Odd(E) then
  117.     case I of
  118.       0: P:=P*1E1;
  119.       1: P:=P*1E2;
  120.       2: P:=P*1E4;
  121.       3: P:=P*1E8;
  122.       4: P:=P*1E16;
  123.       5: P:=P*1E32;
  124.     end;
  125.     E:=E shr 1; Inc(I);
  126.   until E=0;
  127.   Power10:=P;
  128. end;
  129.  
  130. begin
  131. {$IFOPT N-}
  132.   if D[0] and $7F>38+$3F then V:=10E37 else
  133. {$ENDIF}
  134.   begin
  135.     V:=0.0; L:=1;
  136.     while (L<=9) and (D[L]=0) do 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) else
  145.       begin
  146.         if E<-32 then
  147.         begin
  148.           V:=V/1E32; E:=E+32;
  149.         end;
  150.         V:=V/Power10(-E);
  151.       end;
  152.     end;
  153.   end;
  154.   if D[0] and $80=0 then DecToFloat:=V else DecToFloat:=-V;
  155. end;
  156.  
  157. end.
  158.