[gforth] / gforth / engine / ecvt.c  

gforth: gforth/engine/ecvt.c


1 : anton 1.3 /* cheap ecvt replacement
2 :    
3 : anton 1.6 Copyright (C) 1998,2000 Free Software Foundation, Inc.
4 : anton 1.3
5 :     This file is part of Gforth.
6 :    
7 :     Gforth is free software; you can redistribute it and/or
8 :     modify it under the terms of the GNU General Public License
9 :     as published by the Free Software Foundation; either version 2
10 :     of the License, or (at your option) any later version.
11 :    
12 :     This program is distributed in the hope that it will be useful,
13 :     but WITHOUT ANY WARRANTY; without even the implied warranty of
14 :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 :     GNU General Public License for more details.
16 :    
17 :     You should have received a copy of the GNU General Public License
18 :     along with this program; if not, write to the Free Software
19 : anton 1.7 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
20 : anton 1.3 */
21 : anton 1.1
22 : pazsan 1.2 #include <stdio.h>
23 : anton 1.1 #include "config.h"
24 :     #include <math.h>
25 :     extern double floor(double);
26 :     extern double pow10(double);
27 :    
28 :     #define MAXCONV 0x40
29 :     char scratch[MAXCONV];
30 :    
31 :     char* ecvt(double x, int len, int* exp, int* sign)
32 :     {
33 :     int i, j;
34 :     double z;
35 :    
36 : anton 1.8 if (isnan(x)) {
37 :     *sign=0;
38 :     *exp=0;
39 :     return "nan";
40 :     }
41 :     if (isinf(x)) {
42 :     *sign=0; /* this mimics the glibc ecvt */
43 :     *exp=0;
44 :     if (x<0)
45 :     return "-inf";
46 :     else
47 :     return "inf";
48 :     }
49 :    
50 : anton 1.1 if(len > (MAXCONV-1)) len = MAXCONV-1;
51 :    
52 :     if(x<0)
53 :     {
54 :     *sign = 1;
55 :     x = -x;
56 :     }
57 :     else
58 :     {
59 :     *sign = 0;
60 :     }
61 :    
62 :     if(x==0)
63 :     *exp=-1;
64 :     else
65 :     *exp=(int)floor(log10(x));
66 :     x = x / pow10((double)*exp);
67 :    
68 :     *exp += 1;
69 :    
70 :     for(i=0; i < len; i++)
71 :     {
72 :     z=floor(x);
73 : pazsan 1.5 if(z<0) z = 0;
74 : anton 1.1 scratch[i]='0'+(char)((int)z);
75 :     x = (x-z)*10;
76 :     }
77 :    
78 :     if((x >= 5) && i)
79 :     {
80 :     for(j=i-1; j>=0; j--)
81 :     {
82 :     if(scratch[j]!='9')
83 :     {
84 :     scratch[j]+=1; break;
85 :     }
86 :     else
87 :     {
88 :     scratch[j]='0';
89 :     }
90 :     }
91 : pazsan 1.2 if(j<0)
92 : anton 1.1 {
93 :     scratch[0]='1';
94 :     *exp += 1;
95 :     }
96 :     }
97 :    
98 :     scratch[i]='\0';
99 :    
100 :     return scratch;
101 :     }
102 :    
103 :     #ifdef TEST
104 :     int main(int argc, char ** argv)
105 :     {
106 :     int a, b;
107 : pazsan 1.2 char * conv=ecvt(9e0,20,&a,&b);
108 : anton 1.1
109 : pazsan 1.2 printf("ecvt Test: %f -> %s, %d, %d\n",9e0,conv,a,b);
110 : anton 1.1 }
111 :     #endif
112 : pazsan 1.5

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help