121 lines
2.6 KiB
C
121 lines
2.6 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2001, 2011 Fidelity Information Services, Inc *
|
|
* *
|
|
* This source code contains the intellectual property *
|
|
* of its copyright holder(s), and is made available *
|
|
* under a license. If you do not know the terms of *
|
|
* the license, please stop and do not read further. *
|
|
* *
|
|
****************************************************************/
|
|
|
|
#include "mdef.h"
|
|
|
|
#include "gtm_string.h"
|
|
|
|
#include "arit.h"
|
|
#include "stringpool.h"
|
|
|
|
#define PACKED_DIGITS (MAX_DIGITS_IN_INT - 1) /* maximum packed decimal representation is 999999999 (nine nines) */
|
|
|
|
GBLREF spdesc stringpool;
|
|
|
|
unsigned char *n2s(mval *mv_ptr)
|
|
{
|
|
unsigned char *start, *cp, *cp1;
|
|
int4 exp, n0, m1, m0, tmp;
|
|
unsigned char lcl_buf[MAX_DIGITS_IN_INT];
|
|
|
|
if (!MV_DEFINED(mv_ptr))
|
|
GTMASSERT;
|
|
ENSURE_STP_FREE_SPACE(MAX_NUM_SIZE);
|
|
start = stringpool.free;
|
|
cp = start;
|
|
m1 = mv_ptr->m[1];
|
|
if (m1 == 0) /* SHOULD THIS BE UNDER THE MV_INT TEST? */
|
|
*cp++ = '0';
|
|
else if (mv_ptr->mvtype & MV_INT)
|
|
{
|
|
if (m1 < 0)
|
|
{
|
|
*cp++ = '-';
|
|
m1 = -m1;
|
|
}
|
|
cp1 = ARRAYTOP(lcl_buf);
|
|
/* m0 is the integer part */
|
|
m0 = m1 / MV_BIAS;
|
|
/* m1 will become the fractional part */
|
|
m1 = m1 - (m0 * MV_BIAS);
|
|
if (m1 > 0)
|
|
{
|
|
for (n0 = 0; n0 < MV_BIAS_PWR; n0++)
|
|
{
|
|
tmp = m1;
|
|
m1 /= 10;
|
|
tmp -= (m1 * 10);
|
|
if (tmp)
|
|
break;
|
|
}
|
|
*--cp1 = tmp + '0';
|
|
for (n0++; n0 < MV_BIAS_PWR; n0++)
|
|
{
|
|
tmp = m1;
|
|
m1 /= 10;
|
|
*--cp1 = tmp - (m1 * 10) + '0';
|
|
}
|
|
*--cp1 = '.';
|
|
}
|
|
while (m0 > 0)
|
|
{
|
|
tmp = m0;
|
|
m0 /= 10;
|
|
*--cp1 = tmp - (m0 * 10) + '0';
|
|
}
|
|
n0 = (int4)(ARRAYTOP(lcl_buf) - cp1);
|
|
memcpy(cp, cp1, n0);
|
|
cp += n0;
|
|
} else
|
|
{
|
|
exp = (int4)mv_ptr->e - MV_XBIAS;
|
|
if (mv_ptr->sgn)
|
|
*cp++ = '-';
|
|
m0 = mv_ptr->m[0];
|
|
if (exp < 0)
|
|
{
|
|
*cp++ = '.';
|
|
for (n0 = exp; n0 < 0; n0++)
|
|
*cp++ = '0';
|
|
}
|
|
for (; m1; m1 = m0, m0 = 0)
|
|
{
|
|
for (n0 = 0; n0 < PACKED_DIGITS; n0++)
|
|
{
|
|
if (exp-- == 0)
|
|
{
|
|
if (m0 == 0 && m1 == 0)
|
|
break;
|
|
*cp++ = '.';
|
|
} else if (exp < 0 && m0 == 0 && m1 == 0)
|
|
break;
|
|
tmp = m1 / MANT_LO;
|
|
m1 = (m1 - tmp * MANT_LO) * 10;
|
|
*cp++ = tmp + '0';
|
|
}
|
|
}
|
|
while (exp-- > 0)
|
|
*cp++ = '0';
|
|
}
|
|
mv_ptr->mvtype |= MV_STR;
|
|
mv_ptr->mvtype &= ~MV_NUM_APPROX;
|
|
mv_ptr->str.addr = (char *)start;
|
|
NON_UNICODE_ONLY(mv_ptr->str.len = cp - start);
|
|
#ifdef UNICODE_SUPPORTED
|
|
/* Numerics are not unicode so cheaply set "unicode" length same as ascii length */
|
|
mv_ptr->str.len = mv_ptr->str.char_len = INTCAST(cp - start);
|
|
mv_ptr->mvtype |= MV_UTF_LEN;
|
|
#endif
|
|
stringpool.free = cp;
|
|
assert(mv_ptr->str.len);
|
|
return cp;
|
|
}
|