vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| Roman Kononov wrote: > 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); > } Are you sure? As I remember, computation automatically upgrades to 'double'. See this program and output: $ cat tst1.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; } $ tst1 1.000000e+60 -- Bruce Momjian bruce@momjian.us EnterpriseDB http://www.enterprisedb.com + If your life is a hard drive, Christ can be your backup. + ---------------------------(end of broadcast)--------------------------- TIP 9: In versions below 8.0, the planner will ignore your desire to choose an index scan if your joining column's datatypes do not match |
| |||
| 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.000000e+60 Roman ---------------------------(end of broadcast)--------------------------- TIP 3: Have you checked our extensive FAQ? http://www.postgresql.org/docs/faq |
| |||
| Roman Kononov wrote: > 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.000000e+60 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? -- Bruce Momjian bruce@momjian.us EnterpriseDB http://www.enterprisedb.com + If your life is a hard drive, Christ can be your backup. + ---------------------------(end of broadcast)--------------------------- TIP 7: You can help support the PostgreSQL project by donating at http://www.postgresql.org/about/donate |
| |||
| 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 |
| |||
| Roman Kononov <kononov195-pgsql@yahoo.com> 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 |
| |||
| On 12/27/2006 05:19 PM, Tom Lane wrote: > Roman Kononov <kononov195-pgsql@yahoo.com> 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. You are right provided that you want to ignore underflows and silently produce zeros instead. If you go this way, I recommend to ignore overflows as well, and silently produce infinities and NaNs. Roman ---------------------------(end of broadcast)--------------------------- TIP 7: You can help support the PostgreSQL project by donating at http://www.postgresql.org/about/donate |
| |||
| Tom Lane wrote: > Roman Kononov <kononov195-pgsql@yahoo.com> 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. True for overflow to Infinity, but underflow checking is better for float4 using float8. See previous email for details. -- Bruce Momjian bruce@momjian.us EnterpriseDB http://www.enterprisedb.com + If your life is a hard drive, Christ can be your backup. + ---------------------------(end of broadcast)--------------------------- TIP 7: You can help support the PostgreSQL project by donating at http://www.postgresql.org/about/donate |
| ||||
| Roman Kononov wrote: > On 12/27/2006 05:19 PM, Tom Lane wrote: > > Roman Kononov <kononov195-pgsql@yahoo.com> 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. > > You are right provided that you want to ignore underflows and silently > produce zeros instead. > > If you go this way, I recommend to ignore overflows as well, and silently > produce infinities and NaNs. While IEEE seems fine with that, I don't think this is good for SQL. It is best to produce a meaningful error. The major issue is that our current code is buggy because it doesn't have consistent behavior, as Roman outlined. -- Bruce Momjian bruce@momjian.us EnterpriseDB http://www.enterprisedb.com + If your life is a hard drive, Christ can be your backup. + ---------------------------(end of broadcast)--------------------------- TIP 1: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to majordomo@postgresql.org so that your message can get through to the mailing list cleanly |