home *** CD-ROM | disk | FTP | other *** search
-
- { Copyright (c) 1985, 87 by Borland International, Inc. }
-
- unit BCD;
-
- { The BCD version of Turbo Pascal 3.0 (TURBOBCD.COM) supports
- 10-byte binary coded decimal reals with 18 significant digits
- and a range of 1E-63 to 1E+63. The BCD real data type is not
- supported by Turbo Pascal 4.0, and this unit provides a routine
- for converting 3.0 BCD reals to 6-byte reals (software reals)
- or 10-byte 8087 extended reals.
-
- Before you convert a Turbo Pascal 3.0 BCD program to run under
- 4.0, you need to select a 4.0 real data type for your floating
- point values. If you do not have an 8087, or if your program is
- to run on machines without an 8087, your only option is to use
- the familiar 6-byte Real, which provides 11-12 significant digits
- with a range of 2.9E-39 to 1.7E+38. This type is also supported by
- the standard version of Turbo Pascal 3.0. If you are planning to
- use the 8087, we suggest you select the 10-byte Extended type,
- which provides 19-20 significant digits with a range of 1.9E-4951
- to 1.1E+4932. Once you have selected a data type, you need to write
- a conversion program that translates your old data files using the
- conversion routine provided here.
-
- The Decimal type defined by this unit corresponds to the 3.0 BCD
- Real, and the DecToFloat routine converts a Decimal variable to a
- 6-byte Real or to a 10-byte Extended.
-
- The BCD unit uses conditional compilation constructs to define a
- type Float which is equivalent to either Real or Extended,
- depending on the kind of numeric processing you select (software
- or hardware). To compile a program that uses the BCD unit, first
- select software or hardware floating point, using the Options/
- Compiler/Numeric processing menu, and then do a Compile/Build,
- which automatically recompiles BCD.PAS.
-
- The following program shows how to convert a 3.0 data file that
- contains records with BCD fields. The program defines an equivalent
- of the 3.0 record (OldDataRec) using the Decimal type for fields
- that contain BCD reals. In the corresponding 4.0 record (NewDataRec),
- floating point fields are declared using the Float type, which is
- either Real or Extended depending on the floating point model
- selected. During the conversion, all Decimal fields are converted
- to Float using the DecToFloat function, whereas all non-real fields
- are copied directly.
-
- program ConvertBCD;
- uses BCD;
- type
- OldDataRec = record
- Name: string[15];
- InPrice,OutPrice: Decimal;
- InStock,MinStock: Integer;
- end;
- NewDataRec = record
- Name: string[15];
- InPrice,OutPrice: Float;
- InStock,MinStock: Integer;
- end;
- var
- OldFile: file of OldDataRec;
- NewFile: file of NewDataRec;
- Old: OldDataRec;
- New: NewDataRec;
- begin
- Assign(OldFile,'OLDFILE.DTA'); Reset(F);
- Assign(NewFile,'NEWFILE.DTA'); Rewrite(F);
- while not Eof(OldFile) do
- begin
- Read(OldFile,Old);
- New.Name := Old.Name;
- New.InPrice := DecToFloat(Old.InPrice);
- New.OutPrice := DecToFloat(Old.OutPrice);
- New.InStock := Old.InStock;
- New.MinStock := Old.MinStock;
- Write(NewFile,New);
- end;
- Close(OldFile);
- Close(NewFile);
- end.
-
- The range of a BCD real is larger than that of a 6-byte software
- real. Therefore, when converting to 6-byte reals, BCD values larger
- than 1E+38 are converted to 1E+38, and BCD values less than 2.9E-39
- are converted to zero.
- }
-
- interface
-
- type
- Decimal = array[0..9] of Byte;
- {$IFOPT N-}
- Float = Real;
- {$ELSE}
- Float = Extended;
- {$ENDIF}
-
- function DecToFloat(var D: Decimal): Float;
-
- implementation
-
- function DecToFloat(var D: Decimal): Float;
- var
- E,L,P: Integer;
- V: Float;
-
- function Power10(E: Integer): Float;
- var
- I: Integer;
- P: Float;
- begin
- I:=0; P:=1.0;
- repeat
- if Odd(E) then
- case I of
- 0: P:=P*1E1;
- 1: P:=P*1E2;
- 2: P:=P*1E4;
- 3: P:=P*1E8;
- 4: P:=P*1E16;
- 5: P:=P*1E32;
- end;
- E:=E shr 1; Inc(I);
- until E=0;
- Power10:=P;
- end;
-
- begin
- {$IFOPT N-}
- if D[0] and $7F>38+$3F then V:=10E37 else
- {$ENDIF}
- begin
- V:=0.0; L:=1;
- while (L<=9) and (D[L]=0) do Inc(L);
- if L<=9 then
- begin
- for P:=9 downto L do
- begin
- V:=V*100.0+((D[P] shr 4)*10+D[P] and $0F);
- end;
- E:=D[0] and $7F-($3F+(10-L)*2);
- if E>=0 then V:=V*Power10(E) else
- begin
- if E<-32 then
- begin
- V:=V/1E32; E:=E+32;
- end;
- V:=V/Power10(-E);
- end;
- end;
- end;
- if D[0] and $80=0 then DecToFloat:=V else DecToFloat:=-V;
- end;
-
- end.