john@newave.UUCP (John A. Weeks III) (02/16/90)
My understanding of the NaN (not a number) value in IEEE math is that once you get NaN, the operators +, -, /, *, and = are supposed to propagate the NaN value. Is my understanding correct? Well, while using MetaWare's HIGH-C compiler for the 80386 chip, I have discovered that: NaN / NaN = 1.0 and 0.0 * NaN = 0.0. Is this correct behavior? I think HIGH-C is broken... -john- -- =============================================================================== John A. Weeks III (612) 942-6969 john@newave.mn.org NeWave Communications ...uunet!rosevax!bungia!wd0gol!newave!john ===============================================================================
sarathy@gpu.utcs.utoronto.ca (Rajiv Sarathy) (02/20/90)
In article <44@newave.UUCP> john@newave.UUCP (John A. Weeks III) writes: > >My understanding of the NaN (not a number) value in IEEE math is >that once you get NaN, the operators +, -, /, *, and = are supposed >to propagate the NaN value. Is my understanding correct? > >Well, while using MetaWare's HIGH-C compiler for the 80386 chip, I >have discovered that: > > NaN / NaN = 1.0 > > and > > 0.0 * NaN = 0.0. > >Is this correct behavior? I think HIGH-C is broken... As long as only very, VERY, large numbers (positive or negative) are defined to be NaNs (ie. not results of division by zero, and other silly things), then the above behaviour makes sense. Mathematically: lim __n__ = 1.0 and lim 0.0 * n = 0.0 n->inf n n->inf where inf is +/- infinity. Unfortunately, NaNs encompass other floating-point exceptions as well, on some machines. -- Rajiv Partha Sarathy _ _ /^\ INTERNET sarathy@gpu.utcs.utoronto.ca ................ooooooooOOOO(_)(_)\_/ BITNET sarathy@utorgpu.bitnet University Of Toronto Computing Services UUCP sarathy@utgpu.uucp
mac@ardent.com (02/20/90)
In article <44@newave.UUCP> john@newave.UUCP (John A. Weeks III) writes: > Xref: ardent comp.lang.c:24861 comp.sys.ibm.pc.programmer:25 ^ why ardent? > My understanding of the NaN (not a number) value in IEEE math is > that once you get NaN, the operators +, -, /, *, and = are supposed > to propagate the NaN value. Is my understanding correct? > > Well, while using MetaWare's HIGH-C compiler for the 80386 chip, I > have discovered that: > > NaN / NaN = 1.0 > > and > > 0.0 * NaN = 0.0. > > Is this correct behavior? I think HIGH-C is broken... > > -john- This behaviour is not correct. Possibly the compiler has folied you by presubstituting 1.0 for A/A and 0.0 for 0.0 * A at compile time. Or, perhaps your hardware traps into the OS for IEEE exceptions and the OS's handling of source exceptions is broken. Or, perhaps your hardware is not IEEE compliant.... -- Michael McNamara (St)ardent, Inc. mac@ardent.com
ok@goanna.oz.au (Richard O'keefe) (02/20/90)
In article <1990Feb19.172558.29696@gpu.utcs.utoronto.ca>, sarathy@gpu.utcs.utoronto.ca (Rajiv Sarathy) writes: > In article <44@newave.UUCP> john@newave.UUCP (John A. Weeks III) writes: > >Well, while using MetaWare's HIGH-C compiler for the 80386 chip, I > >have discovered that: > > NaN / NaN = 1.0 > > 0.0 * NaN = 0.0. > >Is this correct behavior? I think HIGH-C is broken... > > As long as only very, VERY, large numbers (positive or negative) are defined > to be NaNs (ie. not results of division by zero, and other silly things), > then the above behaviour makes sense. > Unfortunately, NaNs encompass other floating-point exceptions as well, > on some machines. Rajiv Sarathy is confused. The IEEE 754 and IEEE 854 specify the following kinds of values: NUMBERS FINITE NUMBERS - minus zero (-0.0) - plus zero (+0.0) - denormalised numbers (numbers which are so small that the exponent field would underflow; the presence of these numbers means that an add or subtract of finite numbers cannot overflow - ordinary normalised numbers INFINITIES - minus infinity (1/(-0) = -infinity) - plus infinity (1/(+0) = +infinity) NOT-A-NUMBERS SIGNALLING NaNs - strange-fella-number-you-touch-im-e-cry QUIET NaNs - propagate quietly "very VERY large numbers" are mapped to plus or minus infinity. The infinities are NOT NaNs. Any machine which maps large numbers to NaNs is _not_ IEEE conforming. It is, however, the case that Infinity / Infinity = NaN Infinity * 0.0 = NaN Note that (contra Rajiv Sarathy) it does *NOT* make sense for Infinity/Infinity to yield 1.0, for then one would expect (3*Infinity)/Infinity to be the same as 3*(Infinity/Infinity). But the first would be 1.0 and the second 3.0. A NaN or an exception is all that makes sense here. One requirement of the IEEE standards which is _very_ commonly ignored is the requirement that the default behaviour for strange computations is to return the appropriate Infinity (instead of signalling Overflow), denormalised number (instead of signalling Underflow), or NaN (instead of signalling Divide by zero or Invalid operand). The IEEE standards are really quite short and not that hard to understand. (What they are like to _implement_ is someone else's problem, thankfully.)
amull@Morgan.COM (Andrew P. Mullhaupt) (02/21/90)
In article <1990Feb19.172558.29696@gpu.utcs.utoronto.ca>, sarathy@gpu.utcs.utoronto.ca (Rajiv Sarathy) writes: > As long as only very, VERY, large numbers (positive or negative) are defined > to be NaNs (ie. not results of division by zero, and other silly things), then > the above behaviour makes sense. > > Mathematically: > > lim __n__ = 1.0 and lim 0.0 * n = 0.0 > n->inf n n->inf > > where inf is +/- infinity. I would not be very convinced by this argument that (infinity/infinity) should be taken to be 1.0, (similarly for the other). There are lots of limits which are of the form (infinity / infinity) and they can have any value you like. To wit: n lim ------- = C n->inf csc C/n covers all complex numbers C other than C=0, and a limit of that kind is easy to find: n lim ----- = 0. n->inf 2 n Needless to say, there are limits of the form (infinity/infinity) which grow without bound, (these are sometimes said to have the value +infinity) and just as well such limits can oscillate finitely or infinitely. Perhaps the most reasonable thing to say about (infinity/infinity) without knowledge of the limit it represents is that it is 'Not Necessarily a Number'. Later, Andrew Mullhaupt
amull@Morgan.COM (Andrew P. Mullhaupt) (02/21/90)
I forgot to mention that the limits in question in my previous posting are required by IEEE to be NaN - that is 'Not a Number'. Later, Andrew Mullhaupt
simon@ms.uky.edu (G. Simon Gales) (02/21/90)
I think that that behavior is correct. 0.0 * (anything) = 0.0 and NaN / NaN = 1.0 Also a NaN/NaN situation is usually treated as 1, but this is definitely not intended to be a -correct- result. If you end up with NaNs in your computation's results, you can't trust the answers you get. -- Simon Gales@The University of Kentucky simon@ms.uky.edu | 'Fate... protects fools, little children, simon@UKMA.BITNET | and ships named Enterprise.' {rutgers, uunet}!ukma!simon | - Riker, ST:TNG
ark@alice.UUCP (Andrew Koenig) (02/22/90)
In article <14266@s.ms.uky.edu>, simon@ms.uky.edu (G. Simon Gales) writes: > I think that that behavior is correct. > 0.0 * (anything) = 0.0 > and > NaN / NaN = 1.0 Sorry, but that's not what IEEE says. NaN is infinitely infectious. That is: any operation that gives a floating point result is supposed to return NaN if any of its operands is NaN. Relational operators all return `false' if either operand is NaN. Thus (x == x) is false if and only if x is NaN (unless, of course, your implementation is broken). Incidentally, 0.0 * infinity = NaN (+ or - infinity -- I think it's implementation defined whether or not NaN has a sign) 0.0 * NaN = NaN (as mentioned before) 0.0 * anything else = 0.0 NaN / NaN = NaN (as mentioned before) infinity / infinity = NaN infinity / NaN = Nan (as mentioned before) infinity / anything else = infinity -- --Andrew Koenig ark@europa.att.com
foessmei@lan.informatik.tu-muenchen.dbp.de (Reinhard Foessmeier) (02/22/90)
In article <14266@s.ms.uky.edu> simon@ms.uky.edu (G. Simon Gales) writes: >I think that that behavior is correct. > > 0.0 * (anything) = 0.0 >and > NaN / NaN = 1.0 Mi tradukis la libron I translated the book The 8087 primer (J. Palmer, S. Morse) en la germanan, kaj ^gi diras en into German, and it says in chapter 2: ^cap. 2: Kiam la 8087 plenumas instrukcion Whenever the 8087 executes an uzantan NaN-on, la normala reago instruction that accesses a NaN estas redoni la NaN-on kiel as an operand the normal reaction rezulton; se ambaw operaciatoj is to return that NaN as a result. estas NaN-oj, la rezulto estas la if both operands are NaNs, the NaN-o kun la pli granda signifikanto. result is the NaN with the greater significand. (Sorry, no verbatim quotation; I have only my translation at hand.) ^Car Palmer kaj Morse kvazaw Since Palmer and Morse sort of inventis la normon IEEE P754, invented the IEEE P754 standard tio ^sajnas fidinda priskribo this seems a fairly reliable de la normo. description of the standard behavior. > >Also a NaN/NaN situation is usually treated as 1, but this is definitely >not intended to be a -correct- result. If you end up with NaNs in your >computation's results, you can't trust the answers you get. > Devus esti inverse: Sen NaN-oj en It should be the other way round: la rezulto oni povas (iom) fidi... With no NaNs in your result you >-- should have (some) faith in it... >Simon Gales@The University of Kentucky > simon@ms.uky.edu | 'Fate... protects fools, little children, > simon@UKMA.BITNET | and ships named Enterprise.' > {rutgers, uunet}!ukma!simon | - Riker, ST:TNG Reinhard Foessmeier, TU Muenchen _____________________________ -- Reinhard F\"ossmeier, Technische Univ. M\"unchen | "Sendmail can safely be made foessmeier@infovax.informatik.tu-muenchen.dbp.de | setuid to root" (E. Allman: [ { relay.cs.net | unido.uucp } ] | SM Install&Operation Guide)
harish@ecebucolix.ncsu.edu (Harish P. Hiriyannaiah) (02/22/90)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXX # > As long as only very, VERY, large numbers (positive or negative) are defined # > to be NaNs (ie. not results of division by zero, and other silly things), then # > the above behaviour makes sense. # > # > # > lim __n__ = 1.0 and lim 0.0 * n = 0.0 # > n->inf n n->inf # > # > where inf is +/- infinity. Sigh ..... I suppose you haven't had a basic course in limits of functions. I thought any elementary course in Calculus will cover this topic. The point is inf/inf, 0/0, 0*inf, inf^0, 0^inf, inf-inf are all indeterminate. You have to explicitly evaluate the limits in such cases. There are many ways of doing this, and one of them is L' Hospital's rule. harish pu. hi. harish@ecebucolix.ncsu.edu
dougp@voodoo.ucsb.edu (02/22/90)
-Message-Text-Follows- In article <10515@alice.UUCP>, ark@alice.UUCP (Andrew Koenig) writes... > 0.0 * infinity = NaN (+ or - infinity -- I think it's implementation > defined whether or not NaN has a sign) > 0.0 * NaN = NaN (as mentioned before) > 0.0 * anything else = 0.0 > > NaN / NaN = NaN (as mentioned before) > > infinity / infinity = NaN > infinity / NaN = Nan (as mentioned before) > infinity / anything else = infinity Does this mean that compilers arn't alowed to optimize code? Suppose someone writes: double a,b; a=NaN; /* who cares how*/ b=NaN; a/a==1 /*can the compiler optomize this to TRUE ?*/ a/b!=1 /*this should work out to TRUE*/ 0*a /*can the compiler optomize this to 0? */ In most cases you never run into NaNs, I think I would prefer to have the compiler optomize a/a to 1 and 0*a to zero.
harish@ecebucolix.ncsu.edu (Harish P. Hiriyannaiah) (02/23/90)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX In article <4030@hub.UUCP>, dougp@voodoo.ucsb.edu writes: > > In most cases you never run into NaNs, I think I would prefer to > have the compiler optomize a/a to 1 and 0*a to zero. Such a compiler is "broken", since it is mathematically incorrect. harish pu. hi. harish@ecebucolix.ncsu.edu
jsalter@slo.uucp (James Salter) (02/28/90)
In article <MAC.90Feb19133844@ben.ardent.com> mac@ardent.com (Michael McNamara) writes: > > In article <44@newave.UUCP> john@newave.UUCP (John A. Weeks III) writes: > >> My understanding of the NaN (not a number) value in IEEE math is >> that once you get NaN, the operators +, -, /, *, and = are supposed >> to propagate the NaN value. Is my understanding correct? >> >> Well, while using MetaWare's HIGH-C compiler for the 80386 chip, I >> have discovered that: >> NaN / NaN = 1.0 >> and >> 0.0 * NaN = 0.0. >> Is this correct behavior? I think HIGH-C is broken... >> -john- > This behaviour is not correct. Possibly the compiler has >folied you by presubstituting 1.0 for A/A and 0.0 for 0.0 * A at >compile time. Metaware hasn't been very good about identifying and correctly dealing with NaNs. They generate code which does not have the jp (jump if parity) instruction around the compare of doubles. Because of the flag bits which get set in the 386, if the jp instruction is placed after the normal conditional jump, even if one of the args is a NaN, it may *still* not reach the jump if parity instruction. If you check the assembler code, this should reveal itself. To be fair, Metaware isn't alone in this, lots of compilers don't do this right. > Or, perhaps your hardware traps into the OS for IEEE exceptions >and the OS's handling of source exceptions is broken. Probably not. > Or, perhaps your hardware is not IEEE compliant.... Well, sorta. Depending on what 80386 level of hardware you have, you may have some microcode problems. But those should be getting fixed soon. Contact your local Intel dealer about errata sheets. Especially if you have an 80387 chip in there, too. >Michael McNamara (St)ardent, Inc. mac@ardent.com jim/jsalter IBM AWD T465/(415)855-4427 VNET: JSALTER at PALOALTO UUCP: ..!uunet!ibmsupt!jsalter Disc: Any opinions are mine. IP: ibmsupt!jsalter@uunet.uu.net "PS/2 it, or DIE!"
jsalter@slo.uucp (James Salter) (03/01/90)
In article <14266@s.ms.uky.edu> simon@ms.uky.edu (G. Simon Gales) writes: >I think that that behavior is correct. > [... 0.0 ...] > NaN / NaN = 1.0 > >Also a NaN/NaN situation is usually treated as 1, but this is definitely >not intended to be a -correct- result. If you end up with NaNs in your >computation's results, you can't trust the answers you get. No. It is *explicitly* stated in IEEE 854, Sec. 6.2, Paragraph 4 (or so) "Every operation involving one or two input NaNs, ..., if a floating-point result is to be delivered, shall deliver as its result a quiet NaN, which should be one of the input NaNs." where "operation" above is defined (5.1): "An implementation shall provide the add, subtract, multiply, divide and remainder operations for any two operands ..." Thus, NaN/NaN != 1.0; in fact, it *can* not be a representable floating point number. It is NaNQ (maybe with an exception thrown in if one of the NaNs is signalling). If you want a controversy, ask about pow(0.0,0.0), but NaN behavior is specified quite completely. >Simon Gales@The University of Kentucky jim/jsalter IBM AWD T465/(415)855-4427 VNET: JSALTER at PALOALTO UUCP: ..!uunet!ibmsupt!jsalter Disc: Any opinions are mine. IP: ibmsupt!jsalter@uunet.uu.net "PS/2 it, or DIE!"