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

Lines changed: 39 additions & 75 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy