113
113
#define DCH_MAX_ITEM_SIZ 12 /* max localized day name */
114
114
#define NUM_MAX_ITEM_SIZ 8 /* roman number (RN has 15 chars) */
115
115
116
- /* ----------
117
- * More is in float.c
118
- * ----------
119
- */
120
- #define MAXFLOATWIDTH 60
121
- #define MAXDOUBLEWIDTH 500
122
-
123
116
124
117
/* ----------
125
118
* Format parser structs
@@ -5214,8 +5207,7 @@ int4_to_char(PG_FUNCTION_ARGS)
5214
5207
/* we can do it easily because float8 won't lose any precision */
5215
5208
float8 val = (float8 ) value ;
5216
5209
5217
- orgnum = (char * ) palloc (MAXDOUBLEWIDTH + 1 );
5218
- snprintf (orgnum , MAXDOUBLEWIDTH + 1 , "%+.*e" , Num .post , val );
5210
+ orgnum = psprintf ("%+.*e" , Num .post , val );
5219
5211
5220
5212
/*
5221
5213
* Swap a leading positive sign for a space.
@@ -5414,7 +5406,6 @@ float4_to_char(PG_FUNCTION_ARGS)
5414
5406
numstr = orgnum = int_to_roman ((int ) rint (value ));
5415
5407
else if (IS_EEEE (& Num ))
5416
5408
{
5417
- numstr = orgnum = (char * ) palloc (MAXDOUBLEWIDTH + 1 );
5418
5409
if (isnan (value ) || is_infinite (value ))
5419
5410
{
5420
5411
/*
@@ -5428,15 +5419,29 @@ float4_to_char(PG_FUNCTION_ARGS)
5428
5419
}
5429
5420
else
5430
5421
{
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
+ }
5432
5439
5433
5440
/*
5434
5441
* Swap a leading positive sign for a space.
5435
5442
*/
5436
- if (* orgnum == '+' )
5437
- * orgnum = ' ' ;
5438
-
5439
- numstr = orgnum ;
5443
+ if (* numstr == '+' )
5444
+ * numstr = ' ' ;
5440
5445
}
5441
5446
}
5442
5447
else
@@ -5452,16 +5457,24 @@ float4_to_char(PG_FUNCTION_ARGS)
5452
5457
Num .pre += Num .multi ;
5453
5458
}
5454
5459
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 );
5458
5462
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
+ }
5465
5478
5466
5479
if (* orgnum == '-' )
5467
5480
{ /* < 0 */
@@ -5520,7 +5533,6 @@ float8_to_char(PG_FUNCTION_ARGS)
5520
5533
numstr = orgnum = int_to_roman ((int ) rint (value ));
5521
5534
else if (IS_EEEE (& Num ))
5522
5535
{
5523
- numstr = orgnum = (char * ) palloc (MAXDOUBLEWIDTH + 1 );
5524
5536
if (isnan (value ) || is_infinite (value ))
5525
5537
{
5526
5538
/*
@@ -5534,15 +5546,29 @@ float8_to_char(PG_FUNCTION_ARGS)
5534
5546
}
5535
5547
else
5536
5548
{
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
+ }
5538
5566
5539
5567
/*
5540
5568
* Swap a leading positive sign for a space.
5541
5569
*/
5542
- if (* orgnum == '+' )
5543
- * orgnum = ' ' ;
5544
-
5545
- numstr = orgnum ;
5570
+ if (* numstr == '+' )
5571
+ * numstr = ' ' ;
5546
5572
}
5547
5573
}
5548
5574
else
@@ -5557,15 +5583,25 @@ float8_to_char(PG_FUNCTION_ARGS)
5557
5583
val = value * multi ;
5558
5584
Num .pre += Num .multi ;
5559
5585
}
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
+ }
5569
5605
5570
5606
if (* orgnum == '-' )
5571
5607
{ /* < 0 */
0 commit comments