[Cfp-interest 1851] Re: Negative zero
Mike Cowlishaw
mfc at speleotrove.com
Sat Nov 21 12:23:16 PST 2020
The signbit macro returns a nonzero value if and only if the sign of its
argument value is negative.
That indeed does not sound 'right'. I just did a quick check of where I
use signbit(); code attached below -- it assumes it is the sign bit in the
encoding that is being tested, I think, not 'negativity'.
(Caveat: this code is some years old and might well have errors, and might
not reflect recent 754 changes. It is/was my best attempt at creating an
atan2 (degrees, approximated) that was fast enough to be usable as the
'obvious' atan2d (also below) was too slow.)
Mike
------------------------------------
/* --------------------------------------------------------------- */
/* atan2d -- arc tangent of y/x in degrees */
/* */
/* y -- Y-coordinate [-inf -> +inf] */
/* x -- X-coordinate [-inf -> +inf] */
/* */
/* returns the principal value of the arc tangent of y/x, in */
/* degrees from -180 through +180 */
/* */
/* The signs of the arguments are used to determine the quadrant, */
/* and hence the sign and value, of the result. If x and y are */
/* both 0 then 0 is returned. */
/* */
/* No argument error is possible. */
/* */
/* For example: */
/* */
/* atan2d( 10, 10) => 45 */
/* atan2d(-10, 10) => -45 */
/* atan2d( 10, -10) => 135 */
/* atan2d(-10, -10) => -135 */
/* atan2d( 0, 0) => 0 */
/* atan2d( 0, -0) => 180 */
/* atan2d( -0, 0) => -0 */
/* atan2d( -0, -0) => -180 */
/* */
/* (see the IEEE 754 standard for other special cases). */
/* --------------------------------------------------------------- */
degree atan2d(double y, double x) {
return Rad2Deg(atan2(y, x)); // use library function
} // atan2d
/* --------------------------------------------------------------- */
/* atan2da -- arc tangent of y/x in degrees approximation */
/* */
/* y -- Y-coordinate [-inf -> +inf] */
/* x -- X-coordinate [-inf -> +inf] */
/* */
/* returns the principal value of the arc tangent of y/x, in */
/* degrees from -180 through +180 */
/* */
/* See atan2d for description of the function. */
/* */
/* This approximation is from Rajan et al, 2006, wrapped in atan2 */
/* wrapper due to 'imuli' 2017. */
/* */
/* Special cases for infinite x or y not included. */
/* */
/* 4.1x faster than base; max error 0.086° */
/* --------------------------------------------------------------- */
degree atan2da(double y, double x) {
if (y==0.0) { // y is a 0 (sign matters)
if (signbit(y)) {
if (signbit(x)) return -180;
return NEG0;
}
// y is +0
if (signbit(x)) return 180;
return +0;
}
if (x==0) { // x is 0
if (y<0) return -90;
return 90;
}
// here both x and y are non-zero
double absy=fabs(y);
double absx=fabs(x);
Flag invert=absy>absx;
double z=invert ? absx/absy : absy/absx; // [0..1]
// z is >=0
// atan_approx [-1<=z<=1] ...
double th=(MAT_PI/4)*z - z*(z-1)*(0.2447 + 0.0663*z); // Eq 9
// Eq. 7 is slower(!) and less accurate (0.21°) than Eq. 9:
// double th=(MAT_PI/4)*z + 0.273*z*(1.0-z); // Eq 7
if (invert) th=(MAT_PI/2)-th;
if (signbit(x)) th=MAT_PI-th;
if (signbit(y)) return Rad2Deg(-th);
return Rad2Deg(th);
} // atan2da
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.oakapple.net/pipermail/cfp-interest/attachments/20201121/0cf7ae41/attachment-0001.htm>
More information about the Cfp-interest
mailing list