1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-16 06:01:02 +03:00

to_char: revert cc0d90b73b

Revert "to_char(float4/8):  zero pad to specified length".  There are
too many platform-specific problems, and the proper rounding is missing.
Also revert companion patch 9d61b9953c.
This commit is contained in:
Bruce Momjian
2015-03-22 22:56:52 -04:00
parent 59b0a98af0
commit 33a2c5ecd6
4 changed files with 39 additions and 162 deletions

View File

@ -113,6 +113,13 @@
#define DCH_MAX_ITEM_SIZ 12 /* max localized day name */
#define NUM_MAX_ITEM_SIZ 8 /* roman number (RN has 15 chars) */
/* ----------
* More is in float.c
* ----------
*/
#define MAXFLOATWIDTH 60
#define MAXDOUBLEWIDTH 500
/* ----------
* Format parser structs
@ -5207,7 +5214,8 @@ int4_to_char(PG_FUNCTION_ARGS)
/* we can do it easily because float8 won't lose any precision */
float8 val = (float8) value;
orgnum = psprintf("%+.*e", Num.post, val);
orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, val);
/*
* Swap a leading positive sign for a space.
@ -5406,6 +5414,7 @@ float4_to_char(PG_FUNCTION_ARGS)
numstr = orgnum = int_to_roman((int) rint(value));
else if (IS_EEEE(&Num))
{
numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
if (isnan(value) || is_infinite(value))
{
/*
@ -5419,29 +5428,15 @@ float4_to_char(PG_FUNCTION_ARGS)
}
else
{
numstr = psprintf("%+.*e", Num.post, value);
/* prevent the display of imprecise/junk digits */
if (Num.pre + Num.post > FLT_DIG)
{
int digits = 0;
char *numstr_p;
for (numstr_p = numstr; *numstr_p && *numstr_p != 'e'; numstr_p++)
{
if (isdigit(*numstr_p))
{
if (++digits > FLT_DIG)
*numstr_p = '0';
}
}
}
snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, value);
/*
* Swap a leading positive sign for a space.
*/
if (*numstr == '+')
*numstr = ' ';
if (*orgnum == '+')
*orgnum = ' ';
numstr = orgnum;
}
}
else
@ -5457,24 +5452,16 @@ float4_to_char(PG_FUNCTION_ARGS)
Num.pre += Num.multi;
}
/* let psprintf() do the rounding */
orgnum = psprintf("%.*f", Num.post, val);
orgnum = (char *) palloc(MAXFLOATWIDTH + 1);
snprintf(orgnum, MAXFLOATWIDTH + 1, "%.0f", fabs(val));
numstr_pre_len = strlen(orgnum);
/* prevent the display of imprecise/junk digits */
if (Num.pre + Num.post > FLT_DIG)
{
int digits = 0;
char *orgnum_p;
for (orgnum_p = orgnum; *orgnum_p; orgnum_p++)
{
if (isdigit(*orgnum_p))
{
if (++digits > FLT_DIG)
*orgnum_p = '0';
}
}
}
/* adjust post digits to fit max float digits */
if (numstr_pre_len >= FLT_DIG)
Num.post = 0;
else if (numstr_pre_len + Num.post > FLT_DIG)
Num.post = FLT_DIG - numstr_pre_len;
snprintf(orgnum, MAXFLOATWIDTH + 1, "%.*f", Num.post, val);
if (*orgnum == '-')
{ /* < 0 */
@ -5533,6 +5520,7 @@ float8_to_char(PG_FUNCTION_ARGS)
numstr = orgnum = int_to_roman((int) rint(value));
else if (IS_EEEE(&Num))
{
numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
if (isnan(value) || is_infinite(value))
{
/*
@ -5546,29 +5534,15 @@ float8_to_char(PG_FUNCTION_ARGS)
}
else
{
numstr = psprintf("%+.*e", Num.post, value);
/* prevent the display of imprecise/junk digits */
if (Num.pre + Num.post > DBL_DIG)
{
int digits = 0;
char *numstr_p;
for (numstr_p = numstr; *numstr_p && *numstr_p != 'e'; numstr_p++)
{
if (isdigit(*numstr_p))
{
if (++digits > DBL_DIG)
*numstr_p = '0';
}
}
}
snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, value);
/*
* Swap a leading positive sign for a space.
*/
if (*numstr == '+')
*numstr = ' ';
if (*orgnum == '+')
*orgnum = ' ';
numstr = orgnum;
}
}
else
@ -5583,25 +5557,15 @@ float8_to_char(PG_FUNCTION_ARGS)
val = value * multi;
Num.pre += Num.multi;
}
orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
numstr_pre_len = snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.0f", fabs(val));
/* let psprintf() do the rounding */
orgnum = psprintf("%.*f", Num.post, val);
/* prevent the display of imprecise/junk digits */
if (Num.pre + Num.post > DBL_DIG)
{
int digits = 0;
char *orgnum_p;
for (orgnum_p = orgnum; *orgnum_p; orgnum_p++)
{
if (isdigit(*orgnum_p))
{
if (++digits > DBL_DIG)
*orgnum_p = '0';
}
}
}
/* adjust post digits to fit max double digits */
if (numstr_pre_len >= DBL_DIG)
Num.post = 0;
else if (numstr_pre_len + Num.post > DBL_DIG)
Num.post = DBL_DIG - numstr_pre_len;
snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.*f", Num.post, val);
if (*orgnum == '-')
{ /* < 0 */