NaN解釋
There are three kinds of operation which return NaN:[4]
- Operations with a NaN as at least one operand
- Indeterminate forms
- The divisions 0/0, ∞/∞, ∞/?∞, ?∞/∞, and ?∞/?∞
- The multiplications 0×∞ and 0×?∞
- The additions ∞ + (?∞), (?∞) + ∞ and equivalent subtractions
- The standard has alternative functions for powers:
- The standard pow function and the integer exponent pown function define 00, 1∞, and ∞0 as 1.
- The powr function define all three indeterminate forms as invalid operations and so returns NaN.
- Real operations with complex results, for example:
- The square root of a negative number
- The logarithm of a negative number
- The inverse sine or cosine of a number which is less than ?1 or greater than +1.
NaNs may also be explicitly assigned to variables, typically as a representation for missing values. Prior to the IEEE standard, programmers often used a special value (such as ?99999999) to represent undefined or missing values, but there was no guarantee that they would be handled consistently or correctly.[1]
NaNs are not necessarily generated by the processor. In the case of quiet NaNs, the first item is always valid for each processor; the others may not necessarily be. For example, on the Intel Architecture processors, the FPU never creates a NaN except in the first case, unless the corresponding floating point exception mask bits have been set.[5] The other items would cause exceptions, not NaNs. However, the software exception handler may examine the operands and decide to return a NaN (e.g. in the case of 0/0).
[edit]Quiet NaN
Quiet NaNs, or qNaNs, do not raise any additional exceptions as they propagate through most operations. The exceptions are where the NaN cannot simply be passed through unchanged to the output, such as in format conversions or certain comparison operations (which do not "expect" a NaN input).
[edit]Signaling NaN
Signaling NaNs, or sNaNs, are special forms of a NaN which when consumed by most operations should raise an invalid exception and then, if appropriate, be "quieted" into a qNaN which may then propagate. They were introduced in IEEE 754. There have been several ideas for how these might be used:
- Filling uninitialized memory with signaling NaNs would produce an invalid exception if the data is used before it is initialized
- Using an sNaN as a placeholder for a more complicated object, such as:
- A representation of a number that has underflowed
- A representation of a number that has overflowed
- Number in a higher precision format
- A complex number
When encountered a trap handler could decode the sNaN and return an index to the computed result. In practice this approach is faced with many complications. The treatment of the sign bit of NaNs for some simple operations (such as absolute value) is different from that for arithmetic operations. Traps are not required by the standard. There are other approaches to this sort of problem which would be more portable.
NaN是Not a Number的縮寫,就是說它不是一個(gè)數(shù)。NaN是定義在IEEE 754標(biāo)準(zhǔn)中的特殊值,類似的特殊值還有INF(無窮大,INFinite)。IEEE 754是定義浮點(diǎn)數(shù)的標(biāo)準(zhǔn),有1985和2008兩個(gè)版本。其中,2008版本還定義了十進(jìn)制浮點(diǎn)數(shù)的標(biāo)準(zhǔn)。
NaN的產(chǎn)生(可以)是這樣的(此段文字摘譯自WIKI):
1)NaN參與數(shù)學(xué)運(yùn)算的結(jié)果仍是NaN
2)0/0,正無窮大/正無窮大,正無窮大/負(fù)無窮大,負(fù)無窮大/正無窮大,負(fù)無窮大/負(fù)無窮大
3)0和正/負(fù)無窮大相乘
4)正無窮大+負(fù)無窮大,負(fù)無窮大加正無窮大
5)數(shù)學(xué)上無解的一些函數(shù)值,比如:負(fù)數(shù)的平方根,對2.0的求反正弦,等等
第一條說明了NaN在運(yùn)算中的“傳染性”。如果不慎在某處引入了NaN,那么之后的算式值很可能就一直是NaN了。所以在涉及浮點(diǎn)數(shù)值運(yùn)算時(shí)一定要注意NaN的存在。
回過頭來解釋前面的題目:NaN永遠(yuǎn)不等于自己,所以說NaN == NaN永遠(yuǎn)為false,而NaN != NaN永遠(yuǎn)為true。這是一個(gè)相當(dāng)特殊的情況:即使參與比較的兩個(gè)NaN的內(nèi)存表示是一模一樣的,但它們?nèi)匀皇遣坏鹊摹?/p>
更深一步地說,NaN有兩種,一種是Quiet NaN,另一種是Signalling NaN。在使用時(shí),Signalling NaN會(huì)立即引發(fā)異常,然后將自身變?yōu)镼uiet NaN;Quiet NaN的行為比較安靜,在算術(shù)運(yùn)算中它不會(huì)引發(fā)異常,只是將運(yùn)算結(jié)果“傳染”為NaN(但是在某些不接受NaN的地方仍會(huì)引發(fā)異常)。
INF,它溢出到無窮大
INF就是無窮大,在浮點(diǎn)數(shù)中,有+INF和-INF兩種。INF在數(shù)學(xué)上有對應(yīng)的概念,所以它比NaN更好理解一些。比如用1/0,得到的結(jié)果就是INF
0,它竟然還有正負(fù)
在IEEE浮點(diǎn)數(shù)中,0也是特殊的,因?yàn)樗?0和-0兩種(“正零”和“負(fù)零”)。其中,1除以“負(fù)0”等于“負(fù)無窮大”,1除以“正0”等于“正無窮大”。
舍入,它可不是“四舍五入”
舍入算法對我們多數(shù)人來說意味著“四舍五入”。這個(gè)在上學(xué)時(shí)就學(xué)過了,但它卻會(huì)給舍入之后的數(shù)帶來擴(kuò)大的趨勢。在買賣方之間,民俗傳統(tǒng)中一直有“五 刨六撩”一說,“五刨”是說將5及5以下的舍去,“六撩”是說將6及6以上的進(jìn)位,這種舍入算法有整體減小的趨勢,體現(xiàn)了小生意人讓利的“誠意”。那么, 更好的舍入算法是什么樣的呢?
IEEE754中定義了最基本的舍入算法:Rounds to nearest, ties to even(even在這里是“偶數(shù)”的意思)。這種算法將4及4以下的數(shù)拋棄,6及6以上的數(shù)進(jìn)位,如果要舍入的最高位是5的話,則將要保留的最低位圓整 到最接近的偶數(shù)(這里說的“偶數(shù)”包括0)。比如:
89.64 --> 90
98.46 --> 98
1919.54 --> 1920
1918.55 --> 1918
對于大量均勻分布的數(shù)來說,這種50%概率算法保證了舍入后的數(shù)沒有放大或者縮小的趨勢。在銀行里都是用的這種算法,做過金融類程序的對此應(yīng)該印象深刻的。
除了上面提到的“Ties To Even算法”之外,還有幾種舍入算法,因?yàn)槎x得非常清晰和明確,這里不再多說,詳情請見參考資料。
參考資料/延伸閱讀
1、http://en.wikipedia.org/wiki/IEEE_754-2008
2、http://en.wikipedia.org/wiki/IEEE_754-1985
3、http://en.wikipedia.org/wiki/Signed_zero
4、http://en.wikipedia.org/wiki/Not_a_Number
5、IEEE標(biāo)準(zhǔn)
以上這篇文章zz自 http://blog.csdn.net/yuankaining/archive/2009/08/19/4461238.aspx
這個(gè)問題是在看Fundamentals of Computer Graphics的時(shí)候看到的!總結(jié)一下:
當(dāng)深入理解了IEEE標(biāo)準(zhǔn)和NAN之后,我們完全可以改善程序的設(shè)計(jì)來避免復(fù)雜的判斷!這一點(diǎn)是完全可以做到的!注意Signalling NaN 和Quiet NaN
posted on 2010-10-16 21:35 Sosi 閱讀(1218) 評(píng)論(0) 編輯 收藏 引用
