mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-25 11:37:56 +00:00
196 lines
4.1 KiB
C
196 lines
4.1 KiB
C
/****************************************************************
|
|
Copyright 1990, 1993, 1994 by AT&T, Lucent Technologies and Bellcore.
|
|
|
|
Permission to use, copy, modify, and distribute this software
|
|
and its documentation for any purpose and without fee is hereby
|
|
granted, provided that the above copyright notice appear in all
|
|
copies and that both that the copyright notice and this
|
|
permission notice and warranty disclaimer appear in supporting
|
|
documentation, and that the names of AT&T, Bell Laboratories,
|
|
Lucent or Bellcore or any of their entities not be used in
|
|
advertising or publicity pertaining to distribution of the
|
|
software without specific, written prior permission.
|
|
|
|
AT&T, Lucent and Bellcore disclaim all warranties with regard to
|
|
this software, including all implied warranties of
|
|
merchantability and fitness. In no event shall AT&T, Lucent or
|
|
Bellcore be liable for any special, indirect or consequential
|
|
damages or any damages whatsoever resulting from loss of use,
|
|
data or profits, whether in an action of contract, negligence or
|
|
other tortious action, arising out of or in connection with the
|
|
use or performance of this software.
|
|
****************************************************************/
|
|
|
|
/* Put strings representing decimal floating-point numbers
|
|
* into canonical form: always have a decimal point or
|
|
* exponent field; if using an exponent field, have the
|
|
* number before it start with a digit and decimal point
|
|
* (if the number has more than one digit); only have an
|
|
* exponent field if it saves space.
|
|
*
|
|
* Arrange that the return value, rv, satisfies rv[0] == '-' || rv[-1] == '-' .
|
|
*/
|
|
|
|
#include "defs.h"
|
|
|
|
char *
|
|
#ifdef KR_headers
|
|
cds(s, z0)
|
|
char *s;
|
|
char *z0;
|
|
#else
|
|
cds(char *s, char *z0)
|
|
#endif
|
|
{
|
|
int ea, esign, et, i, k, nd = 0, sign = 0, tz;
|
|
char c, *z;
|
|
char ebuf[24];
|
|
long ex = 0;
|
|
static char etype[Table_size], *db;
|
|
static int dblen = 64;
|
|
|
|
if (!db) {
|
|
etype['E'] = 1;
|
|
etype['e'] = 1;
|
|
etype['D'] = 1;
|
|
etype['d'] = 1;
|
|
etype['+'] = 2;
|
|
etype['-'] = 3;
|
|
db = Alloc(dblen);
|
|
}
|
|
|
|
while((c = *s++) == '0');
|
|
if (c == '-')
|
|
{ sign = 1; c = *s++; }
|
|
else if (c == '+')
|
|
c = *s++;
|
|
k = strlen(s) + 2;
|
|
if (k >= dblen) {
|
|
do dblen <<= 1;
|
|
while(k >= dblen);
|
|
free(db);
|
|
db = Alloc(dblen);
|
|
}
|
|
if (etype[(unsigned char)c] >= 2)
|
|
while(c == '0') c = *s++;
|
|
tz = 0;
|
|
while(c >= '0' && c <= '9') {
|
|
if (c == '0')
|
|
tz++;
|
|
else {
|
|
if (nd)
|
|
for(; tz; --tz)
|
|
db[nd++] = '0';
|
|
else
|
|
tz = 0;
|
|
db[nd++] = c;
|
|
}
|
|
c = *s++;
|
|
}
|
|
ea = -tz;
|
|
if (c == '.') {
|
|
while((c = *s++) >= '0' && c <= '9') {
|
|
if (c == '0')
|
|
tz++;
|
|
else {
|
|
if (tz) {
|
|
ea += tz;
|
|
if (nd)
|
|
for(; tz; --tz)
|
|
db[nd++] = '0';
|
|
else
|
|
tz = 0;
|
|
}
|
|
db[nd++] = c;
|
|
ea++;
|
|
}
|
|
}
|
|
}
|
|
if (et = etype[(unsigned char)c]) {
|
|
esign = et == 3;
|
|
c = *s++;
|
|
if (et == 1) {
|
|
if(etype[(unsigned char)c] > 1) {
|
|
if (c == '-')
|
|
esign = 1;
|
|
c = *s++;
|
|
}
|
|
}
|
|
while(c >= '0' && c <= '9') {
|
|
ex = 10*ex + (c - '0');
|
|
c = *s++;
|
|
}
|
|
if (esign)
|
|
ex = -ex;
|
|
}
|
|
switch(c) {
|
|
case 0:
|
|
break;
|
|
#ifndef VAX
|
|
case 'i':
|
|
case 'I':
|
|
Fatal("Overflow evaluating constant expression.");
|
|
case 'n':
|
|
case 'N':
|
|
Fatal("Constant expression yields NaN.");
|
|
#endif
|
|
default:
|
|
Fatal("unexpected character in cds.");
|
|
}
|
|
ex -= ea;
|
|
if (!nd) {
|
|
if (!z0)
|
|
z0 = mem(4,0);
|
|
strcpy(z0, "-0.");
|
|
sign = 0;
|
|
}
|
|
else if (ex > 2 || ex + nd < -2) {
|
|
sprintf(ebuf, "%ld", ex + nd - 1);
|
|
k = strlen(ebuf) + nd + 3;
|
|
if (nd > 1)
|
|
k++;
|
|
if (!z0)
|
|
z0 = mem(k,0);
|
|
z = z0;
|
|
*z++ = '-';
|
|
*z++ = *db;
|
|
if (nd > 1) {
|
|
*z++ = '.';
|
|
for(k = 1; k < nd; k++)
|
|
*z++ = db[k];
|
|
}
|
|
*z++ = 'e';
|
|
strcpy(z, ebuf);
|
|
}
|
|
else {
|
|
k = (int)(ex + nd);
|
|
i = nd + 3;
|
|
if (k < 0)
|
|
i -= k;
|
|
else if (ex > 0)
|
|
i += ex;
|
|
if (!z0)
|
|
z0 = mem(i,0);
|
|
z = z0;
|
|
*z++ = '-';
|
|
if (ex >= 0) {
|
|
for(k = 0; k < nd; k++)
|
|
*z++ = db[k];
|
|
while(--ex >= 0)
|
|
*z++ = '0';
|
|
*z++ = '.';
|
|
}
|
|
else {
|
|
for(i = 0; i < k;)
|
|
*z++ = db[i++];
|
|
*z++ = '.';
|
|
while(++k <= 0)
|
|
*z++ = '0';
|
|
while(i < nd)
|
|
*z++ = db[i++];
|
|
}
|
|
*z = 0;
|
|
}
|
|
return sign ? z0 : z0+1;
|
|
}
|