Thread: Float output formatting options

Float output formatting options

From
"Pedro M. Ferreira"
Date:
Hi All,

This relates to the recent discussion about floating point output format.

The discussion was at a point where one parameter would be added to
specify the number of extra digits used in fp output formatting.
The parameter would have a 0 default value, a maximum of 2 and the
minimum remained open for discussion.

In a previous message I proposed that for double precision numbers a
minimum value of -13 would be usefful. For single precision numbers this
corresponds to a value of -4.

I downloaded the PG sources and added two parameters (as PGC_USERSET):

int extra_float4_digits, default 0, min -4, max 2
int extra_float8_digits, defualt 0, min -13, max 2

Compiled and tested for these functionalities. It is ok.

The afected files are:

src/backend/utils/adt/float.c
src/backend/utils/misc/guc.c
src/bin/psql/tab-complete.c
src/backend/utils/misc/postgresql.conf.sample

I used sources from Debian source package, postgresql_7.2.1-2woody2.

Diff's produced with diff -u are enclosed as attachments.
Can you comment on this (particularly the min values) ?
Also, if we concluded that there is a need of 2 more digits, should'nt
this be the default ?

Best regards,
Pedro M. Ferreira
--
----------------------------------------------------------------------
Pedro Miguel Frazao Fernandes Ferreira
Universidade do Algarve
Faculdade de Ciencias e Tecnologia
Campus de Gambelas
8000-117 Faro
Portugal
Tel./Fax:  (+351) 289 800950 / 289 819403
http://w3.ualg.pt/~pfrazao
--- old/postgresql-7.2.1/src/backend/utils/adt/float.c  Tue Dec 11 02:02:12 2001
+++ postgresql-7.2.1/src/backend/utils/adt/float.c      Mon Nov  4 10:32:33 2002
@@ -65,6 +65,12 @@
 #include "utils/array.h"
 #include "utils/builtins.h"

+/*
+ *     Configuration options for float4 and float8 extra digits in output format
+ */
+
+int extra_float4_digits;
+int extra_float8_digits;

 #if !(NeXT && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_2)
  /* NS3.3 has conflicting declarations of these in <math.h> */
@@ -237,7 +243,7 @@
        if (infflag < 0)
                PG_RETURN_CSTRING(strcpy(ascii, "-Infinity"));

-       sprintf(ascii, "%.*g", FLT_DIG, num);
+       sprintf(ascii, "%.*g", FLT_DIG+extra_float4_digits, num);
        PG_RETURN_CSTRING(ascii);
 }

@@ -299,7 +305,7 @@
        if (infflag < 0)
                PG_RETURN_CSTRING(strcpy(ascii, "-Infinity"));

-       sprintf(ascii, "%.*g", DBL_DIG, num);
+       sprintf(ascii, "%.*g", DBL_DIG+extra_float8_digits, num);
        PG_RETURN_CSTRING(ascii);
 }

--- old/postgresql-7.2.1/src/backend/utils/misc/guc.c   Tue Oct 30 05:38:56 2001
+++ postgresql-7.2.1/src/backend/utils/misc/guc.c       Mon Nov  4 10:53:15 2002
@@ -49,6 +49,11 @@
 extern int     CommitSiblings;
 extern bool FixBTree;

+/* For float4 and float8 extra digits in output format */
+
+extern int extra_float4_digits;
+extern int extra_float8_digits;
+
 #ifdef ENABLE_SYSLOG
 extern char *Syslog_facility;
 extern char *Syslog_ident;
@@ -502,6 +507,19 @@
                "commit_siblings", PGC_USERSET, &CommitSiblings,
                5, 1, 1000, NULL, NULL
        },
+
+       /*
+        * For float4 and float8 extra digits in output format
+        */
+       {
+               "float4_extra_digits", PGC_USERSET, &extra_float4_digits,
+               0, -4, 2, NULL, NULL
+       },
+
+       {
+               "float8_extra_digits", PGC_USERSET, &extra_float8_digits,
+               0, -13, 2, NULL, NULL
+       },

        {
                NULL, 0, NULL, 0, 0, 0, NULL, NULL
--- old/postgresql-7.2.1/src/bin/psql/tab-complete.c    Mon Nov  5 17:46:31 2001
+++ postgresql-7.2.1/src/bin/psql/tab-complete.c        Mon Nov  4 11:16:01 2002
@@ -266,6 +266,9 @@

                "default_transaction_isolation",

+               "float4_extra_digits",
+               "float8_extra_digits",
+
                NULL
        };

--- old/postgresql-7.2.1/src/backend/utils/misc/postgresql.conf.sample  Fri Jan  4 05:50:25 2002
+++ postgresql-7.2.1/src/backend/utils/misc/postgresql.conf.sample      Mon Nov  4 11:02:04 2002
@@ -182,3 +182,9 @@
 #password_encryption = false
 #sql_inheritance = true
 #transform_null_equals = false
+
+#
+# floating point extra digits in output formatting
+#
+#extra_float4_digits = 0       #min -4, max 2
+#extra_float8_digits = 0       #min -13, max 2

Re: Float output formatting options

From
Tom Lane
Date:
"Pedro M. Ferreira" <pfrazao@ualg.pt> writes:
> int extra_float4_digits, default 0, min -4, max 2
> int extra_float8_digits, defualt 0, min -13, max 2

I think a single setting extra_float_digits would be sufficient.

> Also, if we concluded that there is a need of 2 more digits, should'nt 
> this be the default ?

No.  pg_dump would want to bump it up on-the-fly.
        regards, tom lane


Re: Float output formatting options

From
"Pedro M. Ferreira"
Date:
Tom Lane wrote:
> "Pedro M. Ferreira" <pfrazao@ualg.pt> writes:
> 
>>int extra_float4_digits, default 0, min -4, max 2
>>int extra_float8_digits, defualt 0, min -13, max 2
> 
> 
> I think a single setting extra_float_digits would be sufficient.

Ok. Assuming,

int extra_float_digits, default 0, min -13, max 2

If extra_float_digits==-13 and we are outputing a float4 this results in 
a negative value for FLT_DIG+extra_float_digits. I dont know if 
sprintf's behaviour is the same across different libraries for this 
situation.

Should I include the following to handle this case ?

if(extra_float_digits<-4)  sprintf(ascii, "%.*g", FLT_DIG-4, num);
else  sprintf(ascii, "%.*g", FLT_DIG+extra_float_digits, num);

> 
> 
>>Also, if we concluded that there is a need of 2 more digits, should'nt 
>>this be the default ?
> 
> 
> No.  pg_dump would want to bump it up on-the-fly.
> 
>             regards, tom lane
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster
> 
> 


-- 
----------------------------------------------------------------------
Pedro Miguel Frazao Fernandes Ferreira
Universidade do Algarve
Faculdade de Ciencias e Tecnologia
Campus de Gambelas
8000-117 Faro
Portugal
Tel./Fax:  (+351) 289 800950 / 289 819403
http://w3.ualg.pt/~pfrazao



Re: Float output formatting options

From
Tom Lane
Date:
"Pedro M. Ferreira" <pfrazao@ualg.pt> writes:
> Tom Lane wrote:
>> I think a single setting extra_float_digits would be sufficient.

> Ok. Assuming,

> int extra_float_digits, default 0, min -13, max 2

> If extra_float_digits==-13 and we are outputing a float4 this results in 
> a negative value for FLT_DIG+extra_float_digits.

You would want to clamp the values passed to %g to not less than 1.
I'd favor code likeint    ndig = FLT_DIG + extra_float_digits;if (ndig < 1)    ndig = 1;sprintf(ascii, "%.*g", ndig,
num);

Probably best to do it this way with float8 too; otherwise we're
essentially wiring in the assumption that we know what DBL_DIG is.
Which is exactly what we're trying to avoid doing.
        regards, tom lane


Re: Float output formatting options

From
"Pedro M. Ferreira"
Date:
Tom Lane wrote:
> "Pedro M. Ferreira" <pfrazao@ualg.pt> writes:
 >>
>>If extra_float_digits==-13 and we are outputing a float4 this results in
>>a negative value for FLT_DIG+extra_float_digits.
>
> You would want to clamp the values passed to %g to not less than 1.
> I'd favor code like
>     int    ndig = FLT_DIG + extra_float_digits;
>     if (ndig < 1)
>         ndig = 1;
>     sprintf(ascii, "%.*g", ndig, num);
>
> Probably best to do it this way with float8 too; otherwise we're
> essentially wiring in the assumption that we know what DBL_DIG is.
> Which is exactly what we're trying to avoid doing.

Good.
Corrected this, compiled and tested it. Works fine.

I am attaching the diff's made with diff -u. Sources were from Debian
source package Version 7.2.1-2woody2.

Best regards,
Pedro

>
>             regards, tom lane
>
>


--
----------------------------------------------------------------------
Pedro Miguel Frazao Fernandes Ferreira
Universidade do Algarve
Faculdade de Ciencias e Tecnologia
Campus de Gambelas
8000-117 Faro
Portugal
Tel./Fax:  (+351) 289 800950 / 289 819403
http://w3.ualg.pt/~pfrazao
--- old/postgresql-7.2.1/src/backend/utils/adt/float.c  Tue Dec 11 02:02:12 2001
+++ postgresql-7.2.1/src/backend/utils/adt/float.c      Mon Nov  4 15:50:19 2002
@@ -65,6 +65,11 @@
 #include "utils/array.h"
 #include "utils/builtins.h"

+/*
+ *     Configuration options for float4 and float8 extra digits in output format
+ */
+
+int extra_float_digits;

 #if !(NeXT && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_2)
  /* NS3.3 has conflicting declarations of these in <math.h> */
@@ -228,6 +233,7 @@
        float4          num = PG_GETARG_FLOAT4(0);
        char       *ascii = (char *) palloc(MAXFLOATWIDTH + 1);
        int                     infflag;
+       int     ndig = FLT_DIG + extra_float_digits;

        if (isnan(num))
                PG_RETURN_CSTRING(strcpy(ascii, "NaN"));
@@ -237,7 +243,10 @@
        if (infflag < 0)
                PG_RETURN_CSTRING(strcpy(ascii, "-Infinity"));

-       sprintf(ascii, "%.*g", FLT_DIG, num);
+       if (ndig < 1)
+         ndig = 1;
+
+       sprintf(ascii, "%.*g", ndig, num);
        PG_RETURN_CSTRING(ascii);
 }

@@ -290,6 +299,7 @@
        float8          num = PG_GETARG_FLOAT8(0);
        char       *ascii = (char *) palloc(MAXDOUBLEWIDTH + 1);
        int                     infflag;
+       int     ndig = DBL_DIG + extra_float_digits;

        if (isnan(num))
                PG_RETURN_CSTRING(strcpy(ascii, "NaN"));
@@ -299,7 +309,10 @@
        if (infflag < 0)
                PG_RETURN_CSTRING(strcpy(ascii, "-Infinity"));

-       sprintf(ascii, "%.*g", DBL_DIG, num);
+        if (ndig < 1)
+               ndig = 1;
+
+       sprintf(ascii, "%.*g", ndig, num);
        PG_RETURN_CSTRING(ascii);
 }

--- old/postgresql-7.2.1/src/backend/utils/misc/guc.c   Tue Oct 30 05:38:56 2001
+++ postgresql-7.2.1/src/backend/utils/misc/guc.c       Mon Nov  4 15:41:24 2002
@@ -49,6 +49,10 @@
 extern int     CommitSiblings;
 extern bool FixBTree;

+/* For float4 and float8 extra digits in output format */
+
+extern int extra_float_digits;
+
 #ifdef ENABLE_SYSLOG
 extern char *Syslog_facility;
 extern char *Syslog_ident;
@@ -502,6 +506,14 @@
                "commit_siblings", PGC_USERSET, &CommitSiblings,
                5, 1, 1000, NULL, NULL
        },
+
+       /*
+        * For float4 and float8 extra digits in output format
+        */
+       {
+               "float_extra_digits", PGC_USERSET, &extra_float_digits,
+               0, -13, 2, NULL, NULL
+       },

        {
                NULL, 0, NULL, 0, 0, 0, NULL, NULL
--- old/postgresql-7.2.1/src/bin/psql/tab-complete.c    Mon Nov  5 17:46:31 2001
+++ postgresql-7.2.1/src/bin/psql/tab-complete.c        Mon Nov  4 15:38:52 2002
@@ -266,6 +266,8 @@

                "default_transaction_isolation",

+               "float_extra_digits",
+
                NULL
        };

--- old/postgresql-7.2.1/src/backend/utils/misc/postgresql.conf.sample  Fri Jan  4 05:50:25 2002
+++ postgresql-7.2.1/src/backend/utils/misc/postgresql.conf.sample      Mon Nov  4 15:39:55 2002
@@ -182,3 +182,8 @@
 #password_encryption = false
 #sql_inheritance = true
 #transform_null_equals = false
+
+#
+# floating point extra digits in output formatting
+#
+#extra_float_digits = 0                #min -13, max 2

Re: Float output formatting options

From
Tom Lane
Date:
"Pedro M. Ferreira" <pfrazao@ualg.pt> writes:
> I am attaching the diff's made with diff -u. Sources were from Debian 
> source package Version 7.2.1-2woody2.

Looks good, will keep to apply after we branch for 7.4 development.

BTW, did you check to see if this affects the geometric types or not?
I am not sure that they go through float8out; they may need similar
adjustments in their output routines.
        regards, tom lane


Re: Float output formatting options

From
"Pedro M. Ferreira"
Date:
Tom Lane wrote:

> Looks good, will keep to apply after we branch for 7.4 development.
> 
> BTW, did you check to see if this affects the geometric types or not?
> I am not sure that they go through float8out; they may need similar
> adjustments in their output routines.

Only checked arrays.
I will check this and get you posted about it ASAP.

Best regards,
Pedro

> 
>             regards, tom lane
> 
> 


-- 
----------------------------------------------------------------------
Pedro Miguel Frazao Fernandes Ferreira
Universidade do Algarve
Faculdade de Ciencias e Tecnologia
Campus de Gambelas
8000-117 Faro
Portugal
Tel./Fax:  (+351) 289 800950 / 289 819403
http://w3.ualg.pt/~pfrazao



Re: Float output formatting options

From
"Pedro M. Ferreira"
Date:
Tom Lane wrote:

> BTW, did you check to see if this affects the geometric types or not?
> I am not sure that they go through float8out; they may need similar
> adjustments in their output routines.

In fact they need adjustments.

The *_out routines (in src/backend/utils/adt/geo_ops.c) for the 
geometric types rely on two functions to output data:

static int      pair_encode(float8 x, float8 y, char *str);
static int      single_encode(float8 x, char *str);

These functions produce output with (for pair_encode):

sprintf(str, "%.*g,%.*g", digits8, x, digits8, y);

digits8 is defined as ,

#define P_MAXDIG DBL_DIG
static int      digits8 = P_MAXDIG;

I think it would be done the same way as for float4_out and float8_out:

extern int extra_float_digits;


int 
ndig = digits8 + extra_float_digits;

if (ndig < 1)ndig = 1;

sprintf(str, "%.*g,%.*g", ndig, x, ndig, y);

There a bunch of other places where output is produced. They are all 
within #ifdef GEODEBUG / #enfif blocks. Should these be corrected the 
same way ?

Regards,
Pedro



Re: Float output formatting options

From
Tom Lane
Date:
"Pedro M. Ferreira" <pfrazao@ualg.pt> writes:
> These functions produce output with (for pair_encode):

> sprintf(str, "%.*g,%.*g", digits8, x, digits8, y);

> digits8 is defined as ,

> #define P_MAXDIG DBL_DIG
> static int      digits8 = P_MAXDIG;

> I think it would be done the same way as for float4_out and float8_out:

Yeah.  In fact I'd be inclined to remove the static variable and make
the code match float8out exactly (do "DBL_DIG + extra_float_digits").

> There a bunch of other places where output is produced. They are all 
> within #ifdef GEODEBUG / #enfif blocks. Should these be corrected the 
> same way ?

Up to you.  Personally I'd just leave them alone...
        regards, tom lane


Re: Float output formatting options

From
"Pedro M. Ferreira"
Date:
Tom Lane wrote:
> 
> Yeah.  In fact I'd be inclined to remove the static variable and make
> the code match float8out exactly (do "DBL_DIG + extra_float_digits").

P_MAXDIG is only used in the lines below:

#define P_MAXDIG DBL_DIG
#define P_MAXLEN (2*(P_MAXDIG+7)+1)
static int      digits8 = P_MAXDIG;

Is it ok to remove #define P_MAXDIG DBL_DIG,
change P_MAXLEN to 2*(DBL_DIG+7)+1) and
remove the line 'static int      digits8 = P_MAXDIG;' ?

Would then change the two geo output functions and replace digits8 by 
DBL_DIG in the #ifdef GEODEBUG / #enfif output stuff.

>>There a bunch of other places where output is produced. They are all 
>>within #ifdef GEODEBUG / #enfif blocks. Should these be corrected the 
>>same way ?



Re: Float output formatting options

From
Tom Lane
Date:
"Pedro M. Ferreira" <pfrazao@ualg.pt> writes:
> Is it ok to remove #define P_MAXDIG DBL_DIG,
> change P_MAXLEN to 2*(DBL_DIG+7)+1) and
> remove the line 'static int      digits8 = P_MAXDIG;' ?

Perhaps P_MAXLEN now needs to be (2*(DBL_DIG+2+7)+1), considering
that we'll allow extra_float_digits to be up to 2.  What's it used for?
        regards, tom lane


Re: Float output formatting options

From
"Pedro M. Ferreira"
Date:
Tom Lane wrote:
> "Pedro M. Ferreira" <pfrazao@ualg.pt> writes:
> 
>>Is it ok to remove #define P_MAXDIG DBL_DIG,
>>change P_MAXLEN to 2*(DBL_DIG+7)+1) and
>>remove the line 'static int      digits8 = P_MAXDIG;' ?
> 
> Perhaps P_MAXLEN now needs to be (2*(DBL_DIG+2+7)+1), considering
> that we'll allow extra_float_digits to be up to 2.  What's it used for?

Yes. I guess so, because it is used in what I think is a memory 
allocation function. P_MAXLEN is only used twice:

* 1st use in path_encode() (allmost all the geo *_out functions use 
path_encode):

int        size = npts * (P_MAXLEN + 3) + 2;

/* Check for integer overflow */
if ((size - 2) / npts != (P_MAXLEN + 3))                elog(ERROR, "Too many points requested");


* 2nd use in circle_out(PG_FUNCTION_ARGS):

result = palloc(3 * (P_MAXLEN + 1) + 3);

I will do the changes tomorrow and send in the appropriate diff's.

Regards,
Pedro



Re: Float output formatting options

From
"Christopher Kings-Lynne"
Date:
> > Perhaps P_MAXLEN now needs to be (2*(DBL_DIG+2+7)+1), considering
> > that we'll allow extra_float_digits to be up to 2.  What's it used for?
> 
> Yes. I guess so, because it is used in what I think is a memory 
> allocation function. P_MAXLEN is only used twice:

Curse my slowness, but what's the actual problem being fixed here?

Chris



Re: Float output formatting options

From
Tom Lane
Date:
"Christopher Kings-Lynne" <chriskl@familyhealth.com.au> writes:
> Curse my slowness, but what's the actual problem being fixed here?

Two things:

* allow pg_dump to accurately dump and restore float quantities (setting
float_extra_digits to 2 during the dump will accomplish this, at least
on systems with reasonable float I/O routines).

* allow us to get out from under the geometry regression test's platform
dependency problems (setting float_extra_digits to -2 or so during the
test should make most or all of the variations go away).

This proposal is the first one I've seen that solves both these problems
without introducing any compatibility issues of its own.
        regards, tom lane


Re: Float output formatting options

From
"Pedro M. Ferreira"
Date:
Pedro M. Ferreira wrote:
> Tom Lane wrote:
>> Perhaps P_MAXLEN now needs to be (2*(DBL_DIG+2+7)+1), considering
>> that we'll allow extra_float_digits to be up to 2.  What's it used for?
>
> Yes. I guess so, because it is used in what I think is a memory
> allocation function. P_MAXLEN is only used twice:
<...>
>
> I will do the changes tomorrow and send in the appropriate diff's.

Ok. Its done now.
Only one file changed: src/backend/utils/adt/geo_ops.c

All the geometric types should now account for float_extra_digits on output.

A diff -u is attached.

Best reagards,
Pedro

> Regards,
> Pedro
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>    (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
>
>


--
----------------------------------------------------------------------
Pedro Miguel Frazao Fernandes Ferreira
Universidade do Algarve
Faculdade de Ciencias e Tecnologia
Campus de Gambelas
8000-117 Faro
Portugal
Tel./Fax:  (+351) 289 800950 / 289 819403
http://w3.ualg.pt/~pfrazao
--- old/postgresql-7.2.1/src/backend/utils/adt/geo_ops.c    Mon Nov  4 12:01:39 2002
+++ postgresql-7.2.1/src/backend/utils/adt/geo_ops.c    Tue Nov  5 10:47:56 2002
@@ -80,11 +80,11 @@
 #define RDELIM_C        '>'

 /* Maximum number of output digits printed */
-#define P_MAXDIG DBL_DIG
-#define P_MAXLEN (2*(P_MAXDIG+7)+1)
-
-static int    digits8 = P_MAXDIG;
+/* ...+2+7 : 2 accounts for extra_float_digits max value */
+#define P_MAXLEN (2*(DBL_DIG+2+7)+1)

+/* Extra digits in float output formatting (in float.c) */
+extern int extra_float_digits;

 /*
  * Geometric data types are composed of points.
@@ -139,7 +139,12 @@
 static int
 single_encode(float8 x, char *str)
 {
-    sprintf(str, "%.*g", digits8, x);
+    int    ndig = DBL_DIG + extra_float_digits;
+
+    if (ndig < 1)
+        ndig=1;
+
+    sprintf(str, "%.*g", ndig, x);
     return TRUE;
 }    /* single_encode() */

@@ -190,7 +195,12 @@
 static int
 pair_encode(float8 x, float8 y, char *str)
 {
-    sprintf(str, "%.*g,%.*g", digits8, x, digits8, y);
+    int    ndig = DBL_DIG + extra_float_digits;
+
+    if (ndig < 1)
+        ndig=1;
+
+    sprintf(str, "%.*g,%.*g", ndig, x, ndig, y);
     return TRUE;
 }

@@ -974,7 +984,7 @@
 #endif
 #ifdef GEODEBUG
         printf("line_construct_pts- line is neither vertical nor horizontal (diffs x=%.*g, y=%.*g\n",
-               digits8, (pt2->x - pt1->x), digits8, (pt2->y - pt1->y));
+               DBL_DIG, (pt2->x - pt1->x), DBL_DIG, (pt2->y - pt1->y));
 #endif
     }
 }
@@ -1180,8 +1190,8 @@

 #ifdef GEODEBUG
     printf("line_interpt- lines are A=%.*g, B=%.*g, C=%.*g, A=%.*g, B=%.*g, C=%.*g\n",
-           digits8, l1->A, digits8, l1->B, digits8, l1->C, digits8, l2->A, digits8, l2->B, digits8, l2->C);
-    printf("line_interpt- lines intersect at (%.*g,%.*g)\n", digits8, x, digits8, y);
+           DBL_DIG, l1->A, DBL_DIG, l1->B, DBL_DIG, l1->C, DBL_DIG, l2->A, DBL_DIG, l2->B, DBL_DIG, l2->C);
+    printf("line_interpt- lines intersect at (%.*g,%.*g)\n", DBL_DIG, x, DBL_DIG, y);
 #endif

     return result;
@@ -2390,14 +2400,14 @@
     p = line_interpt_internal(&tmp, line);
 #ifdef GEODEBUG
     printf("interpt_sl- segment is (%.*g %.*g) (%.*g %.*g)\n",
-           digits8, lseg->p[0].x, digits8, lseg->p[0].y, digits8, lseg->p[1].x, digits8, lseg->p[1].y);
+           DBL_DIG, lseg->p[0].x, DBL_DIG, lseg->p[0].y, DBL_DIG, lseg->p[1].x, DBL_DIG, lseg->p[1].y);
     printf("interpt_sl- segment becomes line A=%.*g B=%.*g C=%.*g\n",
-           digits8, tmp.A, digits8, tmp.B, digits8, tmp.C);
+           DBL_DIG, tmp.A, DBL_DIG, tmp.B, DBL_DIG, tmp.C);
 #endif
     if (PointerIsValid(p))
     {
 #ifdef GEODEBUG
-        printf("interpt_sl- intersection point is (%.*g %.*g)\n", digits8, p->x, digits8, p->y);
+        printf("interpt_sl- intersection point is (%.*g %.*g)\n", DBL_DIG, p->x, DBL_DIG, p->y);
 #endif
         if (on_ps_internal(p, lseg))
         {

Re: Float output formatting options

From
Bruce Momjian
Date:
I am confused about this patch.  I don't see extra_float_digits defined
anywhere.  Am I missing a patch?

---------------------------------------------------------------------------

Pedro M. Ferreira wrote:
> Pedro M. Ferreira wrote:
> > Tom Lane wrote:
> >> Perhaps P_MAXLEN now needs to be (2*(DBL_DIG+2+7)+1), considering
> >> that we'll allow extra_float_digits to be up to 2.  What's it used for?
> > 
> > Yes. I guess so, because it is used in what I think is a memory 
> > allocation function. P_MAXLEN is only used twice:
> <...>
> > 
> > I will do the changes tomorrow and send in the appropriate diff's.
> 
> Ok. Its done now.
> Only one file changed: src/backend/utils/adt/geo_ops.c
> 
> All the geometric types should now account for float_extra_digits on output.
> 
> A diff -u is attached.
> 
> Best reagards,
> Pedro
> 
> > Regards,
> > Pedro
> > 
> > 
> > ---------------------------(end of broadcast)---------------------------
> > TIP 2: you can get off all lists at once with the unregister command
> >    (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
> > 
> > 
> 
> 
> -- 
> ----------------------------------------------------------------------
> Pedro Miguel Frazao Fernandes Ferreira
> Universidade do Algarve
> Faculdade de Ciencias e Tecnologia
> Campus de Gambelas
> 8000-117 Faro
> Portugal
> Tel./Fax:  (+351) 289 800950 / 289 819403
> http://w3.ualg.pt/~pfrazao

> --- old/postgresql-7.2.1/src/backend/utils/adt/geo_ops.c    Mon Nov  4 12:01:39 2002
> +++ postgresql-7.2.1/src/backend/utils/adt/geo_ops.c    Tue Nov  5 10:47:56 2002
> @@ -80,11 +80,11 @@
>  #define RDELIM_C        '>'
>  
>  /* Maximum number of output digits printed */
> -#define P_MAXDIG DBL_DIG
> -#define P_MAXLEN (2*(P_MAXDIG+7)+1)
> -
> -static int    digits8 = P_MAXDIG;
> +/* ...+2+7 : 2 accounts for extra_float_digits max value */
> +#define P_MAXLEN (2*(DBL_DIG+2+7)+1)
>  
> +/* Extra digits in float output formatting (in float.c) */
> +extern int extra_float_digits;
>  
>  /*
>   * Geometric data types are composed of points.
> @@ -139,7 +139,12 @@
>  static int
>  single_encode(float8 x, char *str)
>  {
> -    sprintf(str, "%.*g", digits8, x);
> +    int    ndig = DBL_DIG + extra_float_digits;
> +
> +    if (ndig < 1)
> +        ndig=1;
> +
> +    sprintf(str, "%.*g", ndig, x);
>      return TRUE;
>  }    /* single_encode() */
>  
> @@ -190,7 +195,12 @@
>  static int
>  pair_encode(float8 x, float8 y, char *str)
>  {
> -    sprintf(str, "%.*g,%.*g", digits8, x, digits8, y);
> +    int    ndig = DBL_DIG + extra_float_digits;
> +
> +    if (ndig < 1)
> +        ndig=1;
> +
> +    sprintf(str, "%.*g,%.*g", ndig, x, ndig, y);
>      return TRUE;
>  }
>  
> @@ -974,7 +984,7 @@
>  #endif
>  #ifdef GEODEBUG
>          printf("line_construct_pts- line is neither vertical nor horizontal (diffs x=%.*g, y=%.*g\n",
> -               digits8, (pt2->x - pt1->x), digits8, (pt2->y - pt1->y));
> +               DBL_DIG, (pt2->x - pt1->x), DBL_DIG, (pt2->y - pt1->y));
>  #endif
>      }
>  }
> @@ -1180,8 +1190,8 @@
>  
>  #ifdef GEODEBUG
>      printf("line_interpt- lines are A=%.*g, B=%.*g, C=%.*g, A=%.*g, B=%.*g, C=%.*g\n",
> -           digits8, l1->A, digits8, l1->B, digits8, l1->C, digits8, l2->A, digits8, l2->B, digits8, l2->C);
> -    printf("line_interpt- lines intersect at (%.*g,%.*g)\n", digits8, x, digits8, y);
> +           DBL_DIG, l1->A, DBL_DIG, l1->B, DBL_DIG, l1->C, DBL_DIG, l2->A, DBL_DIG, l2->B, DBL_DIG, l2->C);
> +    printf("line_interpt- lines intersect at (%.*g,%.*g)\n", DBL_DIG, x, DBL_DIG, y);
>  #endif
>  
>      return result;
> @@ -2390,14 +2400,14 @@
>      p = line_interpt_internal(&tmp, line);
>  #ifdef GEODEBUG
>      printf("interpt_sl- segment is (%.*g %.*g) (%.*g %.*g)\n",
> -           digits8, lseg->p[0].x, digits8, lseg->p[0].y, digits8, lseg->p[1].x, digits8, lseg->p[1].y);
> +           DBL_DIG, lseg->p[0].x, DBL_DIG, lseg->p[0].y, DBL_DIG, lseg->p[1].x, DBL_DIG, lseg->p[1].y);
>      printf("interpt_sl- segment becomes line A=%.*g B=%.*g C=%.*g\n",
> -           digits8, tmp.A, digits8, tmp.B, digits8, tmp.C);
> +           DBL_DIG, tmp.A, DBL_DIG, tmp.B, DBL_DIG, tmp.C);
>  #endif
>      if (PointerIsValid(p))
>      {
>  #ifdef GEODEBUG
> -        printf("interpt_sl- intersection point is (%.*g %.*g)\n", digits8, p->x, digits8, p->y);
> +        printf("interpt_sl- intersection point is (%.*g %.*g)\n", DBL_DIG, p->x, DBL_DIG, p->y);
>  #endif
>          if (on_ps_internal(p, lseg))
>          {

> 
> ---------------------------(end of broadcast)---------------------------
> TIP 6: Have you searched our list archives?
> 
> http://archives.postgresql.org

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
359-1001+  If your life is a hard drive,     |  13 Roberts Road +  Christ can be your backup.        |  Newtown Square,
Pennsylvania19073
 


Re: Float output formatting options

From
Tom Lane
Date:
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> I am confused about this patch.  I don't see extra_float_digits defined
> anywhere.  Am I missing a patch?

Evidently.  I have the patch and was planning to apply it myself as soon
as Pedro does something with the geometry types...
        regards, tom lane


Re: Float output formatting options

From
"Pedro M. Frazao F. Ferreira"
Date:
HI All,

Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> 
>>I am confused about this patch.  I don't see extra_float_digits defined
>>anywhere.  Am I missing a patch  ?

Probably!  :)

The definition of extra_float_digits was made in float.c and the diff was sent 
to the list and Tom before. I think its the one Tom refers below.
There were diff's to four files:

src/backend/utils/adt/float.c
src/backend/utils/misc/guc.c
src/bin/psql/tab-complete.c
src/backend/utils/misc/postgresql.conf.sample

> 
> 
> Evidently.  I have the patch and was planning to apply it myself as soon
> as Pedro does something with the geometry types...

Lots of mail in the list!   ;)
Its done. The diff file to src/backend/utils/adt/geo_ops.c (to handle the 
gemetry types) was sent some days ago. Its the one in the message where Bruce 
says that extra_float_digits is not defined anywhere.

If you want I can send in the diff's again.

Best regards,
Pedro
> 
>             regards, tom lane


-- 
----------------------------------------------------------------------
Pedro Miguel Frazao Fernandes Ferreira
Universidade do Algarve
Faculdade de Ciencias e Tecnologia
Campus de Gambelas
8000-117 Faro
Portugal
Tel./Fax:  (+351) 289 800950 / 289 819403
http://w3.ualg.pt/~pfrazao



Re: Float output formatting options

From
Tom Lane
Date:
"Pedro M. Frazao F. Ferreira" <pfrazao@ualg.pt> writes:
> Tom Lane wrote:
>> Evidently.  I have the patch and was planning to apply it myself as soon
>> as Pedro does something with the geometry types...

> Its done.

So it is, dunno what I was thinking.  Will work on getting it applied.
        regards, tom lane


Geometry regression tests (was Re: Float output formatting options)

From
Tom Lane
Date:
"Pedro M. Ferreira" <pfrazao@ualg.pt> writes:
> [ patch for extra_float_digits ]

I've applied this patch along with followup changes to pg_dump (it sets
extra_float_digits to 2 to allow accurate dump/reload) and the geometry
regression test (it sets extra_float_digits to -3).

I find that two geometry 'expected' files are now sufficient to cover
all the platforms I have available to test.  (We'd only need one, if
everyone displayed minus zero as '-0', but some platforms print '0'.)
I tested on HPUX 10.20 (HPPA), Red Hat Linux 8.0 (Intel), Mac OS X 10.2.1
and LinuxPPC (PPC).

I'd be interested to hear results of testing CVS tip (now 7.4devel)
on other platforms.  Does geometry pass cleanly for you?
        regards, tom lane


Re: Geometry regression tests (was Re: Float output formatting options)

From
Giles Lean
Date:
> I'd be interested to hear results of testing CVS tip (now 7.4devel)
> on other platforms.  Does geometry pass cleanly for you?

Yes for NetBSD-1.5.1/i386, where it previously didn't due to processor
specific math libraries on this platform.

Giles




Re: Geometry regression tests (was Re: Float output formatting

From
"Pedro M. Frazao F. Ferreira"
Date:
Tom Lane wrote:
> "Pedro M. Ferreira" <pfrazao@ualg.pt> writes:
> 
>>[ patch for extra_float_digits ]
> 
> 
> I've applied this patch along with followup changes to pg_dump (it sets
> extra_float_digits to 2 to allow accurate dump/reload) and the geometry
> regression test (it sets extra_float_digits to -3).
> 
> I find that two geometry 'expected' files are now sufficient to cover
> all the platforms I have available to test.  (We'd only need one, if
> everyone displayed minus zero as '-0', but some platforms print '0'.)
> I tested on HPUX 10.20 (HPPA), Red Hat Linux 8.0 (Intel), Mac OS X 10.2.1
> and LinuxPPC (PPC).
> 
> I'd be interested to hear results of testing CVS tip (now 7.4devel)
> on other platforms.  Does geometry pass cleanly for you?

Yes!   :)
All tests passed on a dual AMD Athlon MP with Debian GNU/Linux 3.0 (Woody), 
kernel 2.4.18-5.

Tested with a snapshot downloaded yesterday.

Best regards,
Pedro M. Ferreira


> 
>             regards, tom lane
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster



Re: Geometry regression tests (was Re: Float output

From
Peter Eisentraut
Date:
Tom Lane writes:

> I find that two geometry 'expected' files are now sufficient to cover
> all the platforms I have available to test.  (We'd only need one, if
> everyone displayed minus zero as '-0', but some platforms print '0'.)

Judging from the platforms affected by this, I would suspect that this is
a (mis-)feature of the snprintf() implementation rather than compiler or
processor.  Would it make sense to provide a fixed version of snprintf()
and get rid of these differences?

-- 
Peter Eisentraut   peter_e@gmx.net



Re: Geometry regression tests (was Re: Float output formatting options)

From
Tom Lane
Date:
Peter Eisentraut <peter_e@gmx.net> writes:
> Tom Lane writes:
>> I find that two geometry 'expected' files are now sufficient to cover
>> all the platforms I have available to test.  (We'd only need one, if
>> everyone displayed minus zero as '-0', but some platforms print '0'.)

> Judging from the platforms affected by this, I would suspect that this is
> a (mis-)feature of the snprintf() implementation rather than compiler or
> processor.  Would it make sense to provide a fixed version of snprintf()
> and get rid of these differences?

Certainly it's a library issue on most of these platforms --- AFAIK,
all these machines have IEEE-compliant float hardware, so it must be
sprintf's fault and not a matter of not getting the minus zero in the
first place.

I wouldn't want to write a float converter from scratch, but maybe we
could add a few lines in src/port/snprintf.c to patch up a wrong result?
        regards, tom lane