Received: from localhost (maia-3.hub.org [200.46.204.184]) by postgresql.org (Postfix) with ESMTP id EA9659FA4D1; Fri, 29 Dec 2006 13:11:40 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.184]) (amavisd-new, port 10024) with ESMTP id 07045-07; Fri, 29 Dec 2006 13:11:33 -0400 (AST) X-Greylist: from auto-whitelisted by SQLgrey-1.7.4 X-Greylist: from auto-whitelisted by SQLgrey-1.7.4 Received: from out4.smtp.messagingengine.com (out4.smtp.messagingengine.com [66.111.4.28]) by postgresql.org (Postfix) with ESMTP id 91B8D9FA4D6; Fri, 29 Dec 2006 13:11:33 -0400 (AST) Received: from out1.internal (unknown [10.202.2.149]) by out1.messagingengine.com (Postfix) with ESMTP id 8632B58FA9; Fri, 29 Dec 2006 12:10:06 -0500 (EST) Received: from heartbeat2.messagingengine.com ([10.202.2.161]) by out1.internal (MEProxy); Fri, 29 Dec 2006 12:10:06 -0500 X-Sasl-enc: VT6q8aMercoaHDHFIgwpQPeMUC+ifaFX6j9Z6SFgOIFU 1167412206 Received: from [10.10.0.130] (adsl-68-75-163-199.dsl.emhril.ameritech.net [68.75.163.199]) by mail.messagingengine.com (Postfix) with ESMTP id E129C110EC; Fri, 29 Dec 2006 12:10:03 -0500 (EST) Message-ID: <45954C41.8020304@yahoo.com> Date: Fri, 29 Dec 2006 11:11:29 -0600 From: Roman Kononov User-Agent: Thunderbird 1.5.0.8 (X11/20061117) MIME-Version: 1.0 To: Bruce Momjian CC: Tom Lane , pgsql-hackers@postgresql.org, PostgreSQL-patches , Roman Kononov Subject: Re: [HACKERS] [BUGS] BUG #2846: inconsistent and confusing References: <200612290623.kBT6Nnh18012@momjian.us> In-Reply-To: <200612290623.kBT6Nnh18012@momjian.us> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=3.654 tagged_above=0 required=5 tests=AWL, BAYES_50, DNS_FROM_RFC_ABUSE, DNS_FROM_RFC_POST, DNS_FROM_RFC_WHOIS, FORGED_YAHOO_RCVD X-Spam-Level: *** X-Archive-Number: 200612/192 X-Sequence-Number: 21868 On 12/29/2006 12:23 AM, Bruce Momjian wrote: > Well, then show me what direction you think is better. Think about this idea please. This has no INF, NaN or range checks and detects all "bad" cases with any floating point math. The only issue is that a bad case is detected only once. You need to restart the postmaster. It can be fixed by re-enabling FP exceptions in the FP exception handler. Roman ----------------------------- ~/postgresql-8.2.0/src/backend/utils/adt>diff -U3 -p float.orig.c float.c --- float.orig.c 2006-12-29 10:49:51.000000000 -0600 +++ float.c 2006-12-29 10:58:19.000000000 -0600 @@ -60,12 +60,21 @@ #ifdef HAVE_IEEEFP_H #include #endif +#include #include "catalog/pg_type.h" #include "libpq/pqformat.h" #include "utils/array.h" #include "utils/builtins.h" +static void __attribute__((__constructor__)) +enable_fp_exceptions() +{ + feclearexcept(FE_ALL_EXCEPT); + feenableexcept(FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID); + printf("FP exceptions enabled\n"); +} + #ifndef M_PI /* from my RH5.2 gcc math.h file - thomas 2000-04-03 */ @@ -783,11 +792,10 @@ float4pl(PG_FUNCTION_ARGS) { float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - double result; + float4 result; result = arg1 + arg2; - CheckFloat4Val(result); - PG_RETURN_FLOAT4((float4) result); + PG_RETURN_FLOAT4(result); } Datum @@ -795,11 +803,10 @@ float4mi(PG_FUNCTION_ARGS) { float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - double result; + float4 result; result = arg1 - arg2; - CheckFloat4Val(result); - PG_RETURN_FLOAT4((float4) result); + PG_RETURN_FLOAT4(result); } Datum @@ -807,11 +814,10 @@ float4mul(PG_FUNCTION_ARGS) { float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - double result; + float4 result; result = arg1 * arg2; - CheckFloat4Val(result); - PG_RETURN_FLOAT4((float4) result); + PG_RETURN_FLOAT4(result); } Datum @@ -819,18 +825,10 @@ float4div(PG_FUNCTION_ARGS) { float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - double result; - - if (arg2 == 0.0) - ereport(ERROR, - (errcode(ERRCODE_DIVISION_BY_ZERO), - errmsg("division by zero"))); - - /* Do division in float8, then check for overflow */ - result = (float8) arg1 / (float8) arg2; + float4 result; - CheckFloat4Val(result); - PG_RETURN_FLOAT4((float4) result); + result = arg1 / arg2; + PG_RETURN_FLOAT4(result); } /*