mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 07:59:34 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			213 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			213 lines
		
	
	
		
			5.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}
 | 
						|
{  bestreal  = extended;  still gives problems }
 | 
						|
  bestreal = double;
 | 
						|
{$else i386}
 | 
						|
  bestreal = single;
 | 
						|
{$endif 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 }
 | 
						|
  if len=-32767 then len:=maxlen;
 | 
						|
  { 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<>0) and ((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.4  1998-06-18 08:15:33  michael
 | 
						|
  + Fixed error when printing zero. len was calculated wron.
 | 
						|
 | 
						|
  Revision 1.3  1998/05/12 10:42:45  peter
 | 
						|
    * moved getopts to inc/, all supported OS's need argc,argv exported
 | 
						|
    + strpas, strlen are now exported in the systemunit
 | 
						|
    * removed logs
 | 
						|
    * removed $ifdef ver_above
 | 
						|
 | 
						|
  Revision 1.2  1998/04/07 22:40:46  florian
 | 
						|
    * final fix of comp writing
 | 
						|
}
 |