P: n/a

In Plauger's THE STANDARD C LIBRARY (1992) there is the source code for
fabs.c (p140).
/* fabs function */
#include "xmath.h"
double (fabs)(double x)
{
switch (_Dtest(&x))
{ /* test for special codes */
case NAN:
errno = EDOM;
return (x);
case INF:
errno = ERANGE;
return (_Inf._D);
case 0:
return (0.0);
default: /* finite */
return (x < 0.0 ? x : x);
}
}
This is not necessarily a question about fabs() in particular, but rather a
question about the *technique* Plauger has employed, and if there is a
subtlety involved.
My question is: why is there a case for 0, which simply returns 0.0? Without
it, the default case will trap it anyway, and return 0, which will be
converted to double  the return type of the function.
Also, I'm puzzled by the superfluous use of parentheses around the return
expressions.
Martin http://martinobrien.co.uk/  
Share this Question
P: n/a

In <CD******************@fe04.usenetserver.com> "Martin" <martin.o_brien@[nospam]which.net> writes: In Plauger's THE STANDARD C LIBRARY (1992) there is the source code for fabs.c (p140).
/* fabs function */ #include "xmath.h" double (fabs)(double x) { switch (_Dtest(&x)) { /* test for special codes */ case NAN: errno = EDOM; return (x); case INF: errno = ERANGE; return (_Inf._D); case 0: return (0.0); default: /* finite */ return (x < 0.0 ? x : x); } }
This is not necessarily a question about fabs() in particular, but rather a question about the *technique* Plauger has employed, and if there is a subtlety involved.
My question is: why is there a case for 0, which simply returns 0.0? Without it, the default case will trap it anyway, and return 0, which will be converted to double  the return type of the function.
No conversion to double is needed or would occur in that case: the
function would return x which is already of type double.
However, I don't know why Plauger handled 0.0 as a special case.
Also, I'm puzzled by the superfluous use of parentheses around the return expressions.
They were mandatory, back when Plauger started to use C. Old habits die
hard...
Dan

Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de  
P: n/a

Martin <martin.o_brien@[nospam]which.net> wrote: My question is: why is there a case for 0, which simply returns 0.0? Without it, the default case will trap it anyway, and return 0, which will be converted to double  the return type of the function.
The subtlety you're missing is signed zeros. On implementations that
have such things, 0.0 is not < 0.0, so the default case would return it
asis (i.e., 0.0) rather than returning the correct +0.0.
Also, I'm puzzled by the superfluous use of parentheses around the return expressions.
Style. Or lack thereof, if we're making value judgments. :)
Larry Jones
I don't think that question was very hypothetical at all.  Calvin  
P: n/a

"Martin" <martin.o_brien@[nospam]which.net> writes: In Plauger's THE STANDARD C LIBRARY (1992) there is the source code for fabs.c (p140).
/* fabs function */ #include "xmath.h" double (fabs)(double x) { switch (_Dtest(&x)) { /* test for special codes */ case NAN: errno = EDOM; return (x); case INF: errno = ERANGE; return (_Inf._D); case 0: return (0.0); default: /* finite */ return (x < 0.0 ? x : x); } }
This is not necessarily a question about fabs() in particular, but rather a question about the *technique* Plauger has employed, and if there is a subtlety involved.
My question is: why is there a case for 0, which simply returns 0.0? Without it, the default case will trap it anyway, and return 0, which will be converted to double  the return type of the function.
I don't know what `_Dtest' does, but presumably it returns 0 if `x' is
0.0. If it is already known that `x' is 0.0, there is no reason to
compare it with 0.0 again, which would only (slightly) degrade the
performance.
Also, I'm puzzled by the superfluous use of parentheses around the return expressions.
So am I.
Martin  
P: n/a

>This is not necessarily a question about fabs() in particular, but rather a question about the *technique* Plauger has employed, and if there is a subtlety involved.
My question is: why is there a case for 0, which simply returns 0.0? Without it, the default case will trap it anyway, and return 0, which will be converted to double  the return type of the function.
Is negative zero an issue here? Are there some implementations
(possibly buggy by current floating point standards) where negative
zero tests as less than 0? Perhaps it was desired that fabs() never
return anything that tests less than zero, not even negative zero,
even for implementations of what later became IEEE floating point
that didn't quite handle all the corner cases involving negative
zero according to the current floating point standard.
Gordon L. Burditt  
P: n/a

In article <CD******************@fe04.usenetserver.com>,
"Martin" <martin.o_brien@[nospam]which.net> wrote: In Plauger's THE STANDARD C LIBRARY (1992) there is the source code for fabs.c (p140).
/* fabs function */ #include "xmath.h" double (fabs)(double x) { switch (_Dtest(&x)) { /* test for special codes */ case NAN: errno = EDOM; return (x); case INF: errno = ERANGE; return (_Inf._D); case 0: return (0.0); default: /* finite */ return (x < 0.0 ? x : x); } }
This is not necessarily a question about fabs() in particular, but rather a question about the *technique* Plauger has employed, and if there is a subtlety involved.
My question is: why is there a case for 0, which simply returns 0.0? Without it, the default case will trap it anyway, and return 0, which will be converted to double  the return type of the function.
One possibility is that he wanted floating point numbers in IEEE 754
format to be handled correctly: In that format, there are two different
representations for +0.0 and 0.0; both produce values that compare
equal to x, but you would want fabs (0.0) to be +0.0.
Also, I'm puzzled by the superfluous use of parentheses around the return expressions.
Martin http://martinobrien.co.uk/  
P: n/a

"Christian Bau" <ch***********@cbau.freeserve.co.uk> wrote in message
news:ch*********************************@slbnewsm1.svr.pol.co.uk... In article <CD******************@fe04.usenetserver.com>, "Martin" <martin.o_brien@[nospam]which.net> wrote:
In Plauger's THE STANDARD C LIBRARY (1992) there is the source code for fabs.c (p140).
/* fabs function */ #include "xmath.h" double (fabs)(double x) { switch (_Dtest(&x)) { /* test for special codes */ case NAN: errno = EDOM; return (x); case INF: errno = ERANGE; return (_Inf._D); case 0: return (0.0); default: /* finite */ return (x < 0.0 ? x : x); } }
This is not necessarily a question about fabs() in particular, but
rather a question about the *technique* Plauger has employed, and if there is a subtlety involved.
My question is: why is there a case for 0, which simply returns 0.0?
Without it, the default case will trap it anyway, and return 0, which will be converted to double  the return type of the function.
One possibility is that he wanted floating point numbers in IEEE 754 format to be handled correctly: In that format, there are two different representations for +0.0 and 0.0; both produce values that compare equal to x, but you would want fabs (0.0) to be +0.0.
Correct. Also, I'm puzzled by the superfluous use of parentheses around the
return expressions.
It's a style I settled on many years ago. (FWIW and IIRC, there was a
brief period when the parentheses were required by an early Ritchie
compiler.) We made it part of the shop standard at Whitesmiths and
I've stuck with it over the years.
P.J. Plauger
Dinkumware, Ltd. http://www.dinkumware.com  
P: n/a

Christian Bau wrote: One possibility is that he wanted floating point numbers in IEEE 754 format to be handled correctly: In that format, there are two different representations for +0.0 and 0.0; both produce values that compare equal to x, but you would want fabs (0.0) to be +0.0.
"P.J. Plauger" commented: Correct.
I wrote: Also, I'm puzzled by the superfluous use of parentheses around the return expressions.
"P.J. Plauger" replied It's a style I settled on many years ago. (FWIW and IIRC, there was a brief period when the parentheses were required by an early Ritchie compiler.) We made it part of the shop standard at Whitesmiths and I've stuck with it over the years.
My thanks to P.J. Plauger, Christian, Gordon, Martin Dicksopp, Lawrence, and
Dan for your reponses.
THE STANDARD C LIBRARY is packed with much information I know, and is a
large enough book, but perhaps that subtlety with the IEEE 754 should have
been pointed out (brief comment in the code?).

Martin http://martinobrien.co.uk/  
P: n/a

Martin wrote: In Plauger's THE STANDARD C LIBRARY (1992) there is the source code for fabs.c (p140).
/* fabs function */ #include "xmath.h" double (fabs)(double x) { switch (_Dtest(&x)) { /* test for special codes */ case NAN: errno = EDOM; return (x); case INF: errno = ERANGE; return (_Inf._D); case 0: return (0.0); default: /* finite */ return (x < 0.0 ? x : x); } }
This is not necessarily a question about fabs() in particular, but rather a question about the *technique* Plauger has employed, and if there is a subtlety involved.
My question is: why is there a case for 0, which simply returns 0.0? Without it, the default case will trap it anyway, and return 0, which will be converted to double  the return type of the function.
The switch is not testing x, but whatever the return value of
_Dtest(&x) happens to be. That obviously involves some magic
incantations, and is outside the users name space. It might well
have something to do with the existance of ve 0 in that
particular arithmetic system. Also, I'm puzzled by the superfluous use of parentheses around the return expressions.
Superfluous is in the eye of the beholder. Plauger, and others,
feel that there is no further need to ration parentheses and that
they can be neatly used to delimit expressions.

Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!  
P: n/a

In <nr************@jones.homeip.net> la************@ugsplm.com writes: Martin <martin.o_brien@[nospam]which.net> wrote: My question is: why is there a case for 0, which simply returns 0.0? Without it, the default case will trap it anyway, and return 0, which will be converted to double  the return type of the function.
The subtlety you're missing is signed zeros. On implementations that have such things, 0.0 is not < 0.0, so the default case would return it asis (i.e., 0.0) rather than returning the correct +0.0.
If 0.0 is not < 0.0, why is it an error to return it as such?
Dan

Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de  
P: n/a

Dan Pop <Da*****@cern.ch> wrote: If 0.0 is not < 0.0, why is it an error to return it as such?
I won't defend the vagaries of signed zeros, but although 0.0 and +0.0
compare equal (obviously), 0.0 is nonetheless negative whereas the
result of fabs() should (obviously) be nonnegative. Despite comparing
equal, 0.0 and +0.0 can still be distingished (e.g., by the signbit()
or copysign() functions).
Larry Jones
I don't need to improve! Everyone ELSE does!  Calvin  
P: n/a

In article <c0***********@sunnews.cern.ch>, Da*****@cern.ch (Dan Pop)
wrote: In <nr************@jones.homeip.net> la************@ugsplm.com writes:
Martin <martin.o_brien@[nospam]which.net> wrote: My question is: why is there a case for 0, which simply returns 0.0? Without it, the default case will trap it anyway, and return 0, which will be converted to double  the return type of the function.
The subtlety you're missing is signed zeros. On implementations that have such things, 0.0 is not < 0.0, so the default case would return it asis (i.e., 0.0) rather than returning the correct +0.0.
If 0.0 is not < 0.0, why is it an error to return it as such?
If the implementor guarantees that the compiler implements not only the
C Standard, but also for example the IEEE 754 Standard then returning
0.0 as the result of fabs (0.0) is an error. It would violate the IEEE
754 Standard.   This discussion thread is closed Replies have been disabled for this discussion.   Question stats  viewed: 3219
 replies: 11
 date asked: Nov 14 '05
