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-
123116
124117/* ----------
125118 * Format parser structs
@@ -5214,8 +5207,7 @@ int4_to_char(PG_FUNCTION_ARGS)
52145207/* we can do it easily because float8 won't lose any precision */
52155208float8 val = (float8 )value ;
52165209
5217- orgnum = (char * )palloc (MAXDOUBLEWIDTH + 1 );
5218- snprintf (orgnum ,MAXDOUBLEWIDTH + 1 ,"%+.*e" ,Num .post ,val );
5210+ orgnum = psprintf ("%+.*e" ,Num .post ,val );
52195211
52205212/*
52215213 * Swap a leading positive sign for a space.
@@ -5414,7 +5406,6 @@ float4_to_char(PG_FUNCTION_ARGS)
54145406numstr = orgnum = int_to_roman ((int )rint (value ));
54155407else if (IS_EEEE (& Num ))
54165408{
5417- numstr = orgnum = (char * )palloc (MAXDOUBLEWIDTH + 1 );
54185409if (isnan (value )|| is_infinite (value ))
54195410{
54205411/*
@@ -5428,15 +5419,29 @@ float4_to_char(PG_FUNCTION_ARGS)
54285419}
54295420else
54305421{
5431- snprintf (orgnum ,MAXDOUBLEWIDTH + 1 ,"%+.*e" ,Num .post ,value );
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+ }
54325439
54335440/*
54345441 * Swap a leading positive sign for a space.
54355442 */
5436- if (* orgnum == '+' )
5437- * orgnum = ' ' ;
5438-
5439- numstr = orgnum ;
5443+ if (* numstr == '+' )
5444+ * numstr = ' ' ;
54405445}
54415446}
54425447else
@@ -5452,16 +5457,24 @@ float4_to_char(PG_FUNCTION_ARGS)
54525457Num .pre += Num .multi ;
54535458}
54545459
5455- orgnum = (char * )palloc (MAXFLOATWIDTH + 1 );
5456- snprintf (orgnum ,MAXFLOATWIDTH + 1 ,"%.0f" ,fabs (val ));
5457- numstr_pre_len = strlen (orgnum );
5460+ /* let psprintf() do the rounding */
5461+ orgnum = psprintf ("%.*f" ,Num .post ,val );
54585462
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 );
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+ }
54655478
54665479if (* orgnum == '-' )
54675480{/* < 0 */
@@ -5520,7 +5533,6 @@ float8_to_char(PG_FUNCTION_ARGS)
55205533numstr = orgnum = int_to_roman ((int )rint (value ));
55215534else if (IS_EEEE (& Num ))
55225535{
5523- numstr = orgnum = (char * )palloc (MAXDOUBLEWIDTH + 1 );
55245536if (isnan (value )|| is_infinite (value ))
55255537{
55265538/*
@@ -5534,15 +5546,29 @@ float8_to_char(PG_FUNCTION_ARGS)
55345546}
55355547else
55365548{
5537- snprintf (orgnum ,MAXDOUBLEWIDTH + 1 ,"%+.*e" ,Num .post ,value );
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+ }
55385566
55395567/*
55405568 * Swap a leading positive sign for a space.
55415569 */
5542- if (* orgnum == '+' )
5543- * orgnum = ' ' ;
5544-
5545- numstr = orgnum ;
5570+ if (* numstr == '+' )
5571+ * numstr = ' ' ;
55465572}
55475573}
55485574else
@@ -5557,15 +5583,25 @@ float8_to_char(PG_FUNCTION_ARGS)
55575583val = value * multi ;
55585584Num .pre += Num .multi ;
55595585}
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 );
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+ }
55695605
55705606if (* orgnum == '-' )
55715607{/* < 0 */