#define DCH_MAX_ITEM_SIZ 12 /* max localized day name */
#define NUM_MAX_ITEM_SIZ 8 /* roman number (RN has 15 chars) */
+/* ----------
+ * More is in float.c
+ * ----------
+ */
+#define MAXFLOATWIDTH 60
+#define MAXDOUBLEWIDTH 500
+
/* ----------
* Format parser structs
/* we can do it easily because float8 won't lose any precision */
float8 val = (float8) value;
- orgnum = psprintf("%+.*e", Num.post, val);
+ orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
+ snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, val);
/*
* Swap a leading positive sign for a space.
numstr = orgnum = int_to_roman((int) rint(value));
else if (IS_EEEE(&Num))
{
+ numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
if (isnan(value) || is_infinite(value))
{
/*
}
else
{
- numstr = psprintf("%+.*e", Num.post, value);
-
- /* prevent the display of imprecise/junk digits */
- if (Num.pre + Num.post > FLT_DIG)
- {
- int digits = 0;
- char *numstr_p;
-
- for (numstr_p = numstr; *numstr_p && *numstr_p != 'e'; numstr_p++)
- {
- if (isdigit(*numstr_p))
- {
- if (++digits > FLT_DIG)
- *numstr_p = '0';
- }
- }
- }
+ snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, value);
/*
* Swap a leading positive sign for a space.
*/
- if (*numstr == '+')
- *numstr = ' ';
+ if (*orgnum == '+')
+ *orgnum = ' ';
+
+ numstr = orgnum;
}
}
else
Num.pre += Num.multi;
}
- /* let psprintf() do the rounding */
- orgnum = psprintf("%.*f", Num.post, val);
+ orgnum = (char *) palloc(MAXFLOATWIDTH + 1);
+ snprintf(orgnum, MAXFLOATWIDTH + 1, "%.0f", fabs(val));
+ numstr_pre_len = strlen(orgnum);
- /* prevent the display of imprecise/junk digits */
- if (Num.pre + Num.post > FLT_DIG)
- {
- int digits = 0;
- char *orgnum_p;
-
- for (orgnum_p = orgnum; *orgnum_p; orgnum_p++)
- {
- if (isdigit(*orgnum_p))
- {
- if (++digits > FLT_DIG)
- *orgnum_p = '0';
- }
- }
- }
+ /* adjust post digits to fit max float digits */
+ if (numstr_pre_len >= FLT_DIG)
+ Num.post = 0;
+ else if (numstr_pre_len + Num.post > FLT_DIG)
+ Num.post = FLT_DIG - numstr_pre_len;
+ snprintf(orgnum, MAXFLOATWIDTH + 1, "%.*f", Num.post, val);
if (*orgnum == '-')
{ /* < 0 */
numstr = orgnum = int_to_roman((int) rint(value));
else if (IS_EEEE(&Num))
{
+ numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
if (isnan(value) || is_infinite(value))
{
/*
}
else
{
- numstr = psprintf("%+.*e", Num.post, value);
-
- /* prevent the display of imprecise/junk digits */
- if (Num.pre + Num.post > DBL_DIG)
- {
- int digits = 0;
- char *numstr_p;
-
- for (numstr_p = numstr; *numstr_p && *numstr_p != 'e'; numstr_p++)
- {
- if (isdigit(*numstr_p))
- {
- if (++digits > DBL_DIG)
- *numstr_p = '0';
- }
- }
- }
+ snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, value);
/*
* Swap a leading positive sign for a space.
*/
- if (*numstr == '+')
- *numstr = ' ';
+ if (*orgnum == '+')
+ *orgnum = ' ';
+
+ numstr = orgnum;
}
}
else
val = value * multi;
Num.pre += Num.multi;
}
-
- /* let psprintf() do the rounding */
- orgnum = psprintf("%.*f", Num.post, val);
-
- /* prevent the display of imprecise/junk digits */
- if (Num.pre + Num.post > DBL_DIG)
- {
- int digits = 0;
- char *orgnum_p;
-
- for (orgnum_p = orgnum; *orgnum_p; orgnum_p++)
- {
- if (isdigit(*orgnum_p))
- {
- if (++digits > DBL_DIG)
- *orgnum_p = '0';
- }
- }
- }
+ orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
+ numstr_pre_len = snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.0f", fabs(val));
+
+ /* adjust post digits to fit max double digits */
+ if (numstr_pre_len >= DBL_DIG)
+ Num.post = 0;
+ else if (numstr_pre_len + Num.post > DBL_DIG)
+ Num.post = DBL_DIG - numstr_pre_len;
+ snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.*f", Num.post, val);
if (*orgnum == '-')
{ /* < 0 */
3 | 4
(10 rows)
---
--- Test code path for high-precision output
---
-SELECT to_char(float8 '99999999999', '9999999999999999D99999999');
- to_char
-----------------------------
- 99999999999.00000000
-(1 row)
-
-SELECT to_char(float8 '99999999999', '9999999999999999D' || repeat('9', 1000));
- to_char
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- 99999999999.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-(1 row)
-
-SELECT to_char(float8 '1e9','999999999999999999999D9');
- to_char
---------------------------
- 1000000000.0
-(1 row)
-
-SELECT to_char(float8 '1e20','999999999999999999999D9');
- to_char
---------------------------
- 100000000000000000000.0
-(1 row)
-
-SELECT to_char(1e20, '999999999999999999999D9');
- to_char
---------------------------
- 100000000000000000000.0
-(1 row)
-
-SELECT to_char(float8 '1.123456789123456789', '9.' || repeat('9', 55));
- to_char
-------------------------------------------------------------
- 1.1234567891234500000000000000000000000000000000000000000
-(1 row)
-
-SELECT to_char(float8 '1999999999999999999999999999999999999999999999.123456789123456789',
- repeat('9', 50) || '.' || repeat('9', 50));
- to_char
---------------------------------------------------------------------------------------------------------
- 1999999999999990000000000000000000000000000000.00000000000000000000000000000000000000000000000000
-(1 row)
-
-SELECT to_char(float8 '0.1', '9D' || repeat('9', 1000));
- to_char
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- .1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-(1 row)
-
-SELECT to_char(int4 '1', '9D' || repeat('9', 1000) || 'EEEE');
- to_char
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- 1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00
-(1 row)
-
-SELECT to_char(float4 '1', '9D' || repeat('9', 1000) || 'EEEE');
- to_char
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- 1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00
-(1 row)
-
-SELECT to_char(float8 '1', '9D' || repeat('9', 1000) || 'EEEE');
- to_char
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- 1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00
-(1 row)
-
FROM (VALUES(1,1e20),(2,1)) n(i,n);
to_char
--------------------------
- 100000000000000000000.0
+ 100000000000000000000
1.0
(2 rows)
select * from generate_series(1::numeric, 3::numeric) i, generate_series(i,3) j;
select * from generate_series(1::numeric, 3::numeric) i, generate_series(1,i) j;
select * from generate_series(1::numeric, 3::numeric) i, generate_series(1,5,i) j;
-
---
--- Test code path for high-precision output
---
-
-SELECT to_char(float8 '99999999999', '9999999999999999D99999999');
-SELECT to_char(float8 '99999999999', '9999999999999999D' || repeat('9', 1000));
-SELECT to_char(float8 '1e9','999999999999999999999D9');
-SELECT to_char(float8 '1e20','999999999999999999999D9');
-SELECT to_char(1e20, '999999999999999999999D9');
-SELECT to_char(float8 '1.123456789123456789', '9.' || repeat('9', 55));
-SELECT to_char(float8 '1999999999999999999999999999999999999999999999.123456789123456789',
- repeat('9', 50) || '.' || repeat('9', 50));
-SELECT to_char(float8 '0.1', '9D' || repeat('9', 1000));
-SELECT to_char(int4 '1', '9D' || repeat('9', 1000) || 'EEEE');
-SELECT to_char(float4 '1', '9D' || repeat('9', 1000) || 'EEEE');
-SELECT to_char(float8 '1', '9D' || repeat('9', 1000) || 'EEEE');