Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 33a2c5e

Browse files
committed
to_char: revert cc0d90b
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 9d61b99.
1 parent 59b0a98 commit 33a2c5e

File tree

4 files changed

+40
-163
lines changed

4 files changed

+40
-163
lines changed

src/backend/utils/adt/formatting.c

+39-75
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,13 @@
113113
#define DCH_MAX_ITEM_SIZ 12 /* max localized day name */
114114
#define NUM_MAX_ITEM_SIZ 8 /* roman number (RN has 15 chars) */
115115

116+
/* ----------
117+
* More is in float.c
118+
* ----------
119+
*/
120+
#define MAXFLOATWIDTH 60
121+
#define MAXDOUBLEWIDTH 500
122+
116123

117124
/* ----------
118125
* Format parser structs
@@ -5207,7 +5214,8 @@ int4_to_char(PG_FUNCTION_ARGS)
52075214
/* we can do it easily because float8 won't lose any precision */
52085215
float8 val = (float8) value;
52095216

5210-
orgnum = psprintf("%+.*e", Num.post, val);
5217+
orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
5218+
snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, val);
52115219

52125220
/*
52135221
* Swap a leading positive sign for a space.
@@ -5406,6 +5414,7 @@ float4_to_char(PG_FUNCTION_ARGS)
54065414
numstr = orgnum = int_to_roman((int) rint(value));
54075415
else if (IS_EEEE(&Num))
54085416
{
5417+
numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
54095418
if (isnan(value) || is_infinite(value))
54105419
{
54115420
/*
@@ -5419,29 +5428,15 @@ float4_to_char(PG_FUNCTION_ARGS)
54195428
}
54205429
else
54215430
{
5422-
numstr = psprintf("%+.*e", Num.post, value);
5423-
5424-
/* prevent the display of imprecise/junk digits */
5425-
if (Num.pre + Num.post > FLT_DIG)
5426-
{
5427-
int digits = 0;
5428-
char *numstr_p;
5429-
5430-
for (numstr_p = numstr; *numstr_p && *numstr_p != 'e'; numstr_p++)
5431-
{
5432-
if (isdigit(*numstr_p))
5433-
{
5434-
if (++digits > FLT_DIG)
5435-
*numstr_p = '0';
5436-
}
5437-
}
5438-
}
5431+
snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, value);
54395432

54405433
/*
54415434
* Swap a leading positive sign for a space.
54425435
*/
5443-
if (*numstr == '+')
5444-
*numstr = ' ';
5436+
if (*orgnum == '+')
5437+
*orgnum = ' ';
5438+
5439+
numstr = orgnum;
54455440
}
54465441
}
54475442
else
@@ -5457,24 +5452,16 @@ float4_to_char(PG_FUNCTION_ARGS)
54575452
Num.pre += Num.multi;
54585453
}
54595454

5460-
/* let psprintf() do the rounding */
5461-
orgnum = psprintf("%.*f", Num.post, val);
5455+
orgnum = (char *) palloc(MAXFLOATWIDTH + 1);
5456+
snprintf(orgnum, MAXFLOATWIDTH + 1, "%.0f", fabs(val));
5457+
numstr_pre_len = strlen(orgnum);
54625458

5463-
/* prevent the display of imprecise/junk digits */
5464-
if (Num.pre + Num.post > FLT_DIG)
5465-
{
5466-
int digits = 0;
5467-
char *orgnum_p;
5468-
5469-
for (orgnum_p = orgnum; *orgnum_p; orgnum_p++)
5470-
{
5471-
if (isdigit(*orgnum_p))
5472-
{
5473-
if (++digits > FLT_DIG)
5474-
*orgnum_p = '0';
5475-
}
5476-
}
5477-
}
5459+
/* adjust post digits to fit max float digits */
5460+
if (numstr_pre_len >= FLT_DIG)
5461+
Num.post = 0;
5462+
else if (numstr_pre_len + Num.post > FLT_DIG)
5463+
Num.post = FLT_DIG - numstr_pre_len;
5464+
snprintf(orgnum, MAXFLOATWIDTH + 1, "%.*f", Num.post, val);
54785465

54795466
if (*orgnum == '-')
54805467
{ /* < 0 */
@@ -5533,6 +5520,7 @@ float8_to_char(PG_FUNCTION_ARGS)
55335520
numstr = orgnum = int_to_roman((int) rint(value));
55345521
else if (IS_EEEE(&Num))
55355522
{
5523+
numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
55365524
if (isnan(value) || is_infinite(value))
55375525
{
55385526
/*
@@ -5546,29 +5534,15 @@ float8_to_char(PG_FUNCTION_ARGS)
55465534
}
55475535
else
55485536
{
5549-
numstr = psprintf("%+.*e", Num.post, value);
5550-
5551-
/* prevent the display of imprecise/junk digits */
5552-
if (Num.pre + Num.post > DBL_DIG)
5553-
{
5554-
int digits = 0;
5555-
char *numstr_p;
5556-
5557-
for (numstr_p = numstr; *numstr_p && *numstr_p != 'e'; numstr_p++)
5558-
{
5559-
if (isdigit(*numstr_p))
5560-
{
5561-
if (++digits > DBL_DIG)
5562-
*numstr_p = '0';
5563-
}
5564-
}
5565-
}
5537+
snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, value);
55665538

55675539
/*
55685540
* Swap a leading positive sign for a space.
55695541
*/
5570-
if (*numstr == '+')
5571-
*numstr = ' ';
5542+
if (*orgnum == '+')
5543+
*orgnum = ' ';
5544+
5545+
numstr = orgnum;
55725546
}
55735547
}
55745548
else
@@ -5583,25 +5557,15 @@ float8_to_char(PG_FUNCTION_ARGS)
55835557
val = value * multi;
55845558
Num.pre += Num.multi;
55855559
}
5586-
5587-
/* let psprintf() do the rounding */
5588-
orgnum = psprintf("%.*f", Num.post, val);
5589-
5590-
/* prevent the display of imprecise/junk digits */
5591-
if (Num.pre + Num.post > DBL_DIG)
5592-
{
5593-
int digits = 0;
5594-
char *orgnum_p;
5595-
5596-
for (orgnum_p = orgnum; *orgnum_p; orgnum_p++)
5597-
{
5598-
if (isdigit(*orgnum_p))
5599-
{
5600-
if (++digits > DBL_DIG)
5601-
*orgnum_p = '0';
5602-
}
5603-
}
5604-
}
5560+
orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
5561+
numstr_pre_len = snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.0f", fabs(val));
5562+
5563+
/* adjust post digits to fit max double digits */
5564+
if (numstr_pre_len >= DBL_DIG)
5565+
Num.post = 0;
5566+
else if (numstr_pre_len + Num.post > DBL_DIG)
5567+
Num.post = DBL_DIG - numstr_pre_len;
5568+
snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.*f", Num.post, val);
56055569

56065570
if (*orgnum == '-')
56075571
{ /* < 0 */

0 commit comments

Comments
 (0)