程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Cold knowledge of Python floating point numbers

編輯:Python

This week's PyCoder's Weekly I shared a little article on , The cold knowledge mentioned in it is very interesting , I'll add a little , Share with you .

Some of the questions it mentions , Readers can think about :

  • If two tuples are equal , namely a==b And a is b, So the elements of the same index ( Such as a[0] 、b[0]) Must be equal ?
  • If two objects hash The result is equal , namely hash(a) == hash(b), So are they necessarily equal ?
    The answer, of course, is No ( Otherwise, it's not cold knowledge ), You can try to answer it first , Then look down .

Okay , Let's take a look at the first question . Two identical tuples a、b, They have the following relationships :

>>> a = (float('nan'),)
>>> b = a
>>> a # (nan,)
>>> b # (nan,)
>>> type(a), type(b)
(<type 'tuple'>, <type 'tuple'>)
>>> a == b
True
>>> a is b # namely id(a) == id(b)
True
>>> a[0] == b[0]
False

The above code indicates :a be equal to b( type 、 Value and id All equal ), But their opposite elements are not equal .

Both tuples have only one element ( There is no other element after the comma , This is the representation of a tuple of a single element , namely len(a)==1 ).float() It's a built-in function , You can construct an input parameter into a floating-point number .

Why is this so ? Check out the documentation first , The parsing rule for this built-in function is :

sign ::= "+" | "-"
infinity ::= "Infinity" | "inf"
nan ::= "nan"
numeric_value ::= floatnumber | infinity | nan
numeric_string ::= [sign] numeric_value

It's parsing , You can parse the spaces before and after 、 Plus minus sign of prefix (+/-)、 Floating point numbers , besides , You can also parse two types of strings ( Case insensitive ):"Infinity" or "inf", For infinity ;“nan”, It means not counting (not-a-number), To be precise , It means everything but numbers .

The first cold knowledge shared above follows “nan” of , As a whole , Two tuples are equal , But their only elements are not equal . The reason for this , because “nan” Means something other than numbers , It's a range , So it's not comparable .

As a contrast , Let's take a look at two “ Infinite floating point numbers ” What is the result :

>>> a = (float('inf'),)
>>> b = a
>>> a # (inf,)
>>> b # (inf,)
>>> a == b # True
>>> a is b # True
>>> a[0] == b[0] # True

Pay attention to the last comparison , It's the opposite of the first two tuples , thus , We can come to a conclusion : Two infinite floating-point numbers , The values are equal , And two “ It's not counting ”, The values are not equal .

Simplify , You can look at it this way :

>>> a = float('inf')
>>> b = float('inf')
>>> c = float('nan')
>>> d = float('nan')
>>> a == b # True
>>> c == d # False

The above is the first secret of cold knowledge . Let's take a look at the second one :

>>> hash(float('nan')) == hash(float('nan'))
True

I just said two “ It's not counting ” It's not equal , Here it shows that their hash results are equal , It's against common sense .

We can deduce a simple conclusion : Two objects that are not equal , Its hash result may be equal .

The reason lies in ,hash(float('nan')) The result is equal to 0, It's a fixed value , In comparison, of course, they are equal .

Actually , About hash() function , And buried an egg :

>>> hash(float('inf')) # 314159
>>> hash(float('-inf')) # -314159

Do you think this value is very familiar ? It's the top five pi 3.14159, The result of removing the decimal point . Early Python In the version , The hash result of a negative infinite number is actually -271828, It's from the natural logarithm e. Both numbers are hard coded in Python In the interpreter , It's a kind of homage .

because float('nan') The hash of , This usually means that they cannot be used as different key values in a dictionary , But the truth is unexpected :

>>> a = {float('nan'): 1, float('nan'): 2}
>>> a
{nan: 1, nan: 2}
# As a contrast :
>>> b = {float('inf'): 1, float('inf'): 2}
>>> b
{inf: 2}

As shown above , Two nan The key value is as like as two peas ( Be careful , They are not enclosed in quotation marks ), They can coexist , and inf But it can only be merged into one , Once again, it shows nan The magic of .

Okay , Two very cold little knowledge sharing finished , The reason behind it all lies in float() When floating point number is taken ,Python Yes nan( Not a number ) The existence of , It means the existence of uncertainty , So it led to these strange results .

Last , Let's summarize :

  • contain float('nan') Two tuples of , When comparing as a whole , The result is equal ; Two equal tuples , The opposite elements may not be equal
  • float('nan') It means a “ Not a number ” Things that are , It's not a definite value in itself , When two objects are compared, they are not equal , But the hash result is a fixed value , Equal in comparison ; Can be used as key value of Dictionary , And it's a non conflicting key value
  • float('inf') Floating point number representing infinity , Can be seen as a definite value , When two objects are compared, they are equal , The hash result is the same ; Can be used as key value of Dictionary , But there will be conflicts
  • float('nan') The hash result of is 0,float('inf') The hash result of is 314159

The above is all the content shared this time , Want to know more python Welcome to official account :Python Programming learning circle , send out “J” Free access to , Daily dry goods sharing


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved