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