Re: [PATCHES] [BUGS] BUG #2846: inconsistent and confusing handling of underflows,

2006-12-29 Thread Roman Kononov

On 12/27/2006 12:44 PM, Bruce Momjian wrote:

The only unsolved issue is the one with underflow checks.  I have added
comments explaining the problem in case someone ever figures out how to
address it.


This will behave better for float4:

   Datum float4pl(PG_FUNCTION_ARGS)
   {
---float4  arg1 = PG_GETARG_FLOAT4(0);
---float4  arg2 = PG_GETARG_FLOAT4(1);
+++double  arg1 = PG_GETARG_FLOAT4(0);
+++double  arg2 = PG_GETARG_FLOAT4(1);
   double  result;

   result = arg1 + arg2;
   CheckFloat4Val(result,isinf(arg1) || isinf(arg2));
   PG_RETURN_FLOAT4((float4) result);
}

Roman

---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


Re: [PATCHES] [BUGS] BUG #2846: inconsistent and confusing handling of underflows,

2006-12-27 Thread Roman Kononov

On 12/27/2006 03:23 PM, Bruce Momjian wrote:

Are you sure?  As I remember, computation automatically upgrades to
'double'.  See this program and output:


This is platform- and compiler- dependent:

~uname -a
Linux rklinux 2.6.15-27-amd64-generic #1 SMP PREEMPT Fri Dec 8 17:50:54 UTC 
2006 x86_64 GNU/Linux
~gcc --version
gcc (GCC) 4.3.0 20061213 (experimental)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

~cat test.c
#include stdio.h
#include stdlib.h

int
main(int argc, char *argv[])
{
   float a = 1e30, b = 1e30;
   double c;

   c = a * b;

   printf(%e\n, c);
   return 0;
}
~gcc test.c
~./a.out
inf
~gcc -march=i386 -m32 test.c
~./a.out
1.00e+60

Roman

---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

  http://www.postgresql.org/docs/faq


Re: [PATCHES] [BUGS] BUG #2846: inconsistent and confusing handling of underflows,

2006-12-27 Thread Roman Kononov

On 12/27/2006 04:04 PM, Bruce Momjian wrote:

Interesting.  I didn't know that, but in the float4pl() function,
because the overflow tests and result is float4, what value is there to
doing things as double --- as soon as the float4 maximum is exceeded, we
throw an error?



This is useful for underflows.

float a=1e-30;
float b=1e-30;
double r1=a*b;
double r2=(double)a*b;

r1 is zero and underflow is lost.
r2 is not zero and underflow is detected.

In float4mul() and float4div(), the computation should be double precision.

In float4pl() and float4mi(), it depends on the ability of the hardware
to generate denormalized numbers. If denormalized numbers are generated,
float vs double makes no difference. If denormalized numbers are not
generated (zero is generated), then double computation is safer.

Another way to detect underflows, overflows and other junk is to use FPU
status flags after each computation. Performance will likely suffer.

#include fenv.h

Datum
float4mul(PG_FUNCTION_ARGS)
{
float4   arg1 = PG_GETARG_FLOAT4(0);
float4   arg2 = PG_GETARG_FLOAT4(1);
float4   result;
int fe_exceptions;
feclearexcept(FE_ALL_EXCEPT);
result = arg1 * arg2;

fe_exceptions=fetestexcept(FE_DIVBYZERO,FE_INVALID,FE_OVERFLOW,FE_UNDERFLOW);
if (fe_exceptions) handle_exceptions(fe_exceptions); //??
PG_RETURN_FLOAT4(result);
}

Yet another way to detect exceptions is to remove all CheckFloat4Val(),
CheckFloat8Val(), isnan(), unmask FPU exceptions and install an exception 
handler.
Might have portability difficulties. Comparisons of NaNs must be done in
non-IEEE way (FPU does not compare NaNs, it generates exceptions).

Roman


---(end of broadcast)---
TIP 6: explain analyze is your friend


Re: [PATCHES] [BUGS] BUG #2846: inconsistent and confusing handling of underflows,

2006-12-27 Thread Tom Lane
Roman Kononov [EMAIL PROTECTED] writes:
 On 12/27/2006 03:23 PM, Bruce Momjian wrote:
 Are you sure?  As I remember, computation automatically upgrades to
 'double'.  See this program and output:

 This is platform- and compiler- dependent:

... and probably irrelevant, too.  We should store the result into a
float4 variable and then test for isinf() on that; that eliminates the
question of whether the compiler did the multiply in a wider format or
not.

regards, tom lane

---(end of broadcast)---
TIP 6: explain analyze is your friend


Re: [PATCHES] [BUGS] BUG #2846: inconsistent and confusing handling of underflows,

2006-12-27 Thread Tom Lane
Roman Kononov [EMAIL PROTECTED] writes:
 In float4mul() and float4div(), the computation should be double precision.

Why?  It's going to have to fit in a float4 eventually anyway.

regards, tom lane

---(end of broadcast)---
TIP 6: explain analyze is your friend