mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-06 10:27:12 +01:00
246 lines
6.6 KiB
PHP
246 lines
6.6 KiB
PHP
{
|
|
$Id$
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 1997 by Michael Van Canneyt,
|
|
member of the Free Pascal development team
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
|
|
type
|
|
|
|
treal_type = (rt_s64real,rt_s32real,rt_f32bit,rt_s80real,rt_s64bit);
|
|
{ corresponding to real single fixed extended and comp for i386 }
|
|
|
|
{$ifdef i386}
|
|
{$ifdef ver_above0_9_ still not ok }
|
|
bestreal = extended; { still gives problems }
|
|
{$else ver_above0_9_8}
|
|
bestreal = double;
|
|
{$endif ver_above0_9_8}
|
|
{$else not i386}
|
|
bestreal = single;
|
|
{$endif not i386}
|
|
|
|
Procedure str_real (len,f : longint; d : bestreal; real_type :treal_type; var s : string);
|
|
|
|
{ These numbers are for the double type...
|
|
At the moment these are mapped onto a double but this may change
|
|
in the future ! }
|
|
|
|
var maxlen : longint; { Maximal length of string for float }
|
|
minlen : longint; { Minimal length of string for float }
|
|
explen : longint; { Length of exponent, including E and sign.
|
|
Must be strictly larger than 2 }
|
|
const
|
|
maxexp = 1e+35; { Maximum value for decimal expressions }
|
|
minexp = 1e-35; { Minimum value for decimal expressions }
|
|
zero = '0000000000000000000000000000000000000000';
|
|
|
|
var correct : longint; { Power correction }
|
|
currprec : longint;
|
|
roundcorr : bestreal;
|
|
temp : string;
|
|
power : string[10];
|
|
sign : boolean;
|
|
i : integer;
|
|
dot : byte;
|
|
|
|
begin
|
|
case real_type of
|
|
rt_s64real :
|
|
begin
|
|
maxlen:=23;
|
|
minlen:=9;
|
|
explen:=5;
|
|
end;
|
|
rt_s32real :
|
|
begin
|
|
maxlen:=16;
|
|
minlen:=8;
|
|
explen:=4;
|
|
end;
|
|
rt_f32bit :
|
|
begin
|
|
maxlen:=16;
|
|
minlen:=8;
|
|
explen:=4;
|
|
end;
|
|
rt_s80real :
|
|
begin
|
|
maxlen:=26;
|
|
minlen:=10;
|
|
explen:=6;
|
|
end;
|
|
rt_s64bit :
|
|
begin
|
|
maxlen:=22;
|
|
minlen:=9;
|
|
{ according to TP (was 5) (FK) }
|
|
explen:=6;
|
|
end;
|
|
end;
|
|
{ check parameters }
|
|
{ default value for length is -32767 }
|
|
{$ifdef ver_above0_9_7}
|
|
if len=-32767 then len:=maxlen;
|
|
{$else }
|
|
if (len=-1) and (f=-1) then len:=maxlen;
|
|
{$endif }
|
|
{ determine sign. before precision, needs 2 less calls to abs() }
|
|
sign:=d<0;
|
|
{ the creates a cannot determine which overloaded function to call
|
|
if d is extended !!!
|
|
we should prefer real_to_real on real_to_longint !!
|
|
corrected in compiler }
|
|
|
|
{ d:=abs(d); this converts d to double so we loose precision }
|
|
{ for the same reason I converted d:=frac(d) to d:=d-int(d); (PM) }
|
|
if sign then d:=-d;
|
|
{ determine precision : maximal precision is : }
|
|
currprec:=maxlen-explen-3;
|
|
{ this is also the maximal number of decimals !!}
|
|
if f>currprec then f:=currprec;
|
|
{ when doing a fixed-point, we need less characters.}
|
|
if (f<0) or ((d>maxexp) or (d<minexp)) then
|
|
begin
|
|
{ determine maximal number of decimals }
|
|
if (len>=0) and (len<minlen) then len:=minlen;
|
|
if (len>0) and (len<maxlen) then
|
|
currprec:=len-explen-3;
|
|
end;
|
|
{ convert to standard form. }
|
|
correct:=0;
|
|
if d>=10.0 then
|
|
while d>=10.0 do
|
|
begin
|
|
d:=d/10.0;
|
|
inc(correct);
|
|
end
|
|
else if (d<1) and (d<>0) then
|
|
while d<1 do
|
|
begin
|
|
d:=d*10.0;
|
|
dec(correct);
|
|
end;
|
|
{ RoundOff }
|
|
roundcorr:=0.5;
|
|
if f<0 then
|
|
for i:=1 to currprec do roundcorr:=roundcorr/10
|
|
else
|
|
for i:=1 to correct+f do roundcorr:=roundcorr/10;
|
|
d:=d+roundcorr;
|
|
{ 0.99 + 0.05 > 10.0 ! Fix this by dividing the results >=10 first (PV) }
|
|
if d>=10.0 then
|
|
begin
|
|
d:=d/10.0;
|
|
inc(correct);
|
|
end;
|
|
{ Now we have a standard expression : sign d *10^correct
|
|
where 1<d<10 or d=0 ... }
|
|
{ get first character }
|
|
if sign then
|
|
temp:='-'
|
|
else
|
|
temp:=' ';
|
|
temp:=temp+chr(ord('0')+trunc(d));
|
|
d:=d-int(d);
|
|
{ Start making the string }
|
|
for i:=1 to currprec do
|
|
begin
|
|
d:=d*10.0;
|
|
temp:=temp+chr(ord('0')+trunc(d));
|
|
d:=d-int(d);
|
|
end;
|
|
{ Now we need two different schemes for the different
|
|
representations. }
|
|
if (f<0) or (correct>maxexp) then
|
|
begin
|
|
insert ('.',temp,3);
|
|
str(abs(correct),power);
|
|
if length(power)<explen-2 then
|
|
power:=copy(zero,1,explen-2-length(power))+power;
|
|
if correct<0 then power:='-'+power else power:='+'+power;
|
|
temp:=temp+'E'+power;
|
|
end
|
|
else
|
|
begin
|
|
if not sign then
|
|
begin
|
|
delete (temp,1,1);
|
|
dot:=2;
|
|
end
|
|
else
|
|
dot:=3;
|
|
{ set zeroes and dot }
|
|
if correct>=0 then
|
|
begin
|
|
if length(temp)<correct+dot+f then
|
|
temp:=temp+copy(zero,1,correct+dot+f-length(temp));
|
|
insert ('.',temp,correct+dot);
|
|
end
|
|
else
|
|
begin
|
|
correct:=abs(correct);
|
|
insert(copy(zero,1,correct),temp,dot-1);
|
|
insert ('.',temp,dot);
|
|
end;
|
|
{correct length to fit precision.}
|
|
if f>0 then
|
|
temp[0]:=chr(pos('.',temp)+f)
|
|
else
|
|
temp[0]:=chr(pos('.',temp)-1);
|
|
end;
|
|
if length(temp)<len then
|
|
s:=space(len-length(temp))+temp
|
|
else
|
|
s:=temp;
|
|
end;
|
|
|
|
{
|
|
$Log$
|
|
Revision 1.2 1998-04-07 22:40:46 florian
|
|
* final fix of comp writing
|
|
|
|
Revision 1.1.1.1 1998/03/25 11:18:43 root
|
|
* Restored version
|
|
|
|
Revision 1.7 1998/03/16 23:38:17 peter
|
|
* fixed 0.997:0:2 bugs
|
|
|
|
Revision 1.6 1998/01/26 11:59:47 michael
|
|
+ Added log at the end
|
|
|
|
|
|
revision 1.5
|
|
date: 1998/01/05 00:48:24; author: carl; state: Exp; lines: +2 -2
|
|
+ Now compatible with m68k floating point types
|
|
----------------------------
|
|
revision 1.4
|
|
date: 1997/12/02 17:44:45; author: pierre; state: Exp; lines: +2 -2
|
|
* use of extended type in function str_real still buggy
|
|
----------------------------
|
|
revision 1.3
|
|
date: 1997/12/01 12:08:04; author: michael; state: Exp; lines: +12 -6
|
|
+ added copyright reference header.
|
|
----------------------------
|
|
revision 1.2
|
|
date: 1997/11/28 19:45:21; author: pierre; state: Exp; lines: +6 -3
|
|
* one more bug fix with namelength
|
|
+ fixed math in fixed_math define (does not compile yet)
|
|
----------------------------
|
|
revision 1.1
|
|
date: 1997/11/27 08:33:47; author: michael; state: Exp;
|
|
Initial revision
|
|
----------------------------
|
|
revision 1.1.1.1
|
|
date: 1997/11/27 08:33:47; author: michael; state: Exp; lines: +0 -0
|
|
FPC RTL CVS start
|
|
}
|