On Jul 13, 2008 10:30:27 -0300, Patrick Walker <[EMAIL PROTECTED]> wrote:

     float radians;

     radians = ([entryField floatValue] * M_PI / 180);
     [outField setFloatValue:tan(radians)];


tan() takes a double and returns a double. Your code above truncates doubles three different ways - the input, the intermediate calculation, and the result. Instead, try something like

        double_t input = [inputField doubleValue];
        double_t radians = input * pi / 180;
        double_t output = tan(radians);
        if /* output is "near" infinity */
                [outputField setStringValue:@"INFINITY"];
        else
                [outputField setDoubleValue:output];


My other problems seems to be -2877334 itself.

This is happening because

float radians = 90 * M_PI / 180; // == 1.57079637, truncated from 1.5707963267948966

double result = tan(radians); // == -22877332.428856459 (with <math.>)

but you essentially do

float truncatedResult = tan(pi/2); // == -22877332, truncated from -22877332.428856459


The question is are there any
other than the numerical method "math.h" versions?

Instead of <math.h>, you can use <fp.> along with the '-llibm' compiler flag to get the IEEE trig functions. It won't fix the truncation problem. But it does define "pi" (nice) and gives a slightly different result

double result = tan(pi/2); // == 1.633123935319537e+16

just on the other side of infinity from the -22877332.428856459 obtained with <math.>. Both are "wrong" but surely "close enough"; at any rate about the best you can hope for.

BTW the Mac OS X Numerics manual at
<http://developer.apple.com/documentation/Performance/Conceptual/ Mac_OSX_Numerics/Mac_OSX_Numerics.pdf> (see pages 2-8 and 9-35) indicates this should return a proper IEEE +INFINITY (0x7F800000, binary 01111111 10000000 00000000 00000000). Theoretically you should then be able recognize those values and display text like "INFINITY" to the user.

I say "theoretically" because, while it's supposed to work that way (and I recall it did under OS8/8/7) it doesn't necessarily seem to anymore, given Intel and who knows what else. At least that's what I've seen - I asked a similar question about cos() a while back:

http://lists.apple.com/archives/xcode-users/2006/Jun/msg00453.html


This answer from one of the Apple numerics guys seems relevant:

...how come the results of cos( pi/2 ) don't agree with the behavior documented in PowerPC Numerics, page 148? Am I doing something else wrong? Googling, I see that some other math libs (Java, for instance) document that one should -not- expect cos( pi/ 2 ) to equal exactly zero. This is at variance with what PowerPC Numerics says OS X does, however.

C) If the behavior documented in PowerPC Numerics doesn't actually occur, what's the proper thing to do? The app has some fairly heavy arithmetic going on, with the results displayed to the user both graphically in text form. Should it round before drawing? Round before displaying text? Both? What have others done in this situation?

M_PI_2 (converted to double) is only an approximation to pi/2. It is actually (and approximately) 6.1e-17 smaller than pi/2. The next higher value which a 64 bit IEEE number can represent is approximately 1.6e-16 bigger than pi/2.

It turns out that in the neighborhood of pi/2, cos(x) can be very closely approximated by this simple linear function:

cos(x) =~  pi/2 - x

(derivation available upon request)

Plugging M_PI_2 into this approximation to cos(x) yields the result you report: 6.1e-17. Using nextafter() to find the next representable number above M_PI_2 and calling cos() on that number yields approximately -1.6e-16 (again predicted by the linear approximation to cos(x)).

The answer you're getting is a more accurate answer than 0 would be.

This suggests that what you're seeing is because pi/2, not being exactly expressible on a computer, is a slightly inaccurate argument to tan(). The result is accurate for the binary representation of pi/ 2, but that representation of pi/2 is, unavoidably, not a perfect right angle.

Or, to paraphrase the last sentence in the quote above, the answer you're getting (or will get, once you fix the truncation issues) is a more accurate answer than "infinity" would be.

If the result "close enough" to infinity for your purposes, just display "infinity" as text, or round it off to some reasonable number of digits so the user can see it's "close enough." This is really no different than what a printed trig table does - make the values look nice once a certain threshold is passed.

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to