Cold knowledge of Python float

This week PyCoder's Weeklyis sharing a small article, which referred to the cold knowledge it is very interesting, I add a few words to share for everyone.

Part of the problem mentioned it, readers may think at first:

  • If both tuples are equal, i.e. a == b and a is b, then the index of the same elements (e.g., a [0], b [0]) is equal Necessarily it?
  • If the hash result of the two objects are equal, that hash (a) == hash (b), then they are equal whether it inevitable?

The answer of course is no (or not called a cold knowledge), we can first try to answer it, and then look down.

----- ----- think the dividing line

Well, take a look at the first question. Two identical tuples a, b, they have the following relationship:

>>> a = (float('nan'),)
>>> b = a
>>> a   # (nan,)
>>> b   # (nan,)

>>> type(a), type(b)
(<type 'tuple'>, <type 'tuple'>)

>>> a == b
True

>>> a is b  # 即 id(a) == id(b)
True

>>> a[0] == b[0]
False

The above code shows that: a is equal to B (type, value and id are equal), but their on-site element is not equal.

Two yuan only one element of the group (no other elements comma, which is a method for single-element tuple, i.e. len (a) == 1). float () is a built-in function, the parameters may be configured as a floating point number.

Why is this so? First check what documents, the parsing rules built-in functions are:

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

When parsing it, the space can be resolved, before and after the prefix minus sign (+/-), floating-point, in addition, can also resolve the two strings (case-insensitive): "Infinity" or "inf "indicating infinite number;" nan ", represents not the number of (not-a-number), specifically, it refers to all things except numbers.

The first cold front to share knowledge just "nan" related, as a whole, the two tuples are equal, but they are not the only elements of the same. The reason why this is so, because "nan" said that apart from something other than a number, it's a range, so we can not compare.

As a comparison, let's look at two "infinite float" 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

Note that the last time comparing it with the previous two tuples is just the opposite, so that we can conclude: two infinity floating point values are equal, and the two "not the number of things," values are not equal.

Simplifying a bit, it must read:

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

>>> a == b  # True
>>> c == d  # False

These are the first cold Secret Knowledge. Then second look:

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

Two front just said, "not the number of things" are not equal, but here they show equal hash result, which quite contrary to common sense.

We can infer a simple conclusion: the two objects are not equal, the hash result may be equal.

The reason is that the results of hash (float ( 'nan')) is equal to 0, it is a fixed value, for comparing the time course of the equal.

In fact, on hash () function, but also a buried egg:

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

Do you feel this number is very familiar ah? It is the ratio of the circumference of the top five 3.14159 removal results after the decimal point. In earlier versions of Python, minus an infinite number of hash result it is actually -271 828, it is taken from the natural logarithm e. These two numbers are hard-coded in the Python interpreter, a sort of salute it.

Since equal float ( 'nan') hash value, which usually means they are not as different keys of the dictionary, but the fact was a surprise:

>>> a = {float('nan'): 1, float('nan'): 2}
>>> a
{nan: 1, nan: 2}

# 作为对比:
>>> b = {float('inf'): 1, float('inf'): 2}
>>> b
{inf: 2}

As described above, two identical keys nan (note, they are not enclosed in quotation marks) on the indicator, they can coexist, can only be merged into a inf, nan magic again demonstrated.

Well, two cold little knowledge sharing is completed, the reason behind all that float () when taking floating point number, Python allows nan (not a number) exists, which indicates the presence of inaccurate, resulting in these strange result.

Finally, we make the next Summary:

  • Tuple contains two float ( 'nan') of, when compared as a whole, the results are equal; two equal tuples, it may not be equal to the bit elements
  • float ( 'nan') indicates a "not the number of" things, not itself determination value, the two objects are not equal for comparison, but the hash result is a fixed value, equal for comparison; used as a dictionary key value, but the key is not in conflict
  • float ( 'inf') represents a floating point infinity, it can be considered as determined values, compared two equal objects, which are equal to the hash result; used as a key dictionary, but will conflict
  • The hash result float ( 'nan') a hash result is 0, float ( 'inf') is 314159

References:

https://docs.python.org/3/library/functions.html#float

https://www.pythondoeswhat.com/2019/09/welcome-to-float-zone.html

Public number [ Python cat ], the serial number of high-quality series of articles, there are philosophical cat meow Star series, Python Advanced Series, recommended books series, technical writing, and recommend high-quality English translation and so on, welcome attention Oh.

Guess you like

Origin www.cnblogs.com/pythonista/p/11565135.html