当前位置: 首页 > 后端技术 > Python

Python浮点数冷知识_0

时间:2023-03-26 15:18:07 Python

本周在PyCoder'sWeekly分享了一篇小文章。里面提到的冷知识很有意思。我会添加它并与您分享。其中提到的一些问题,读者可以先思考一下:如果两个元组相等,即a==b且a是b,那么索引相同的元素(如a[0]、b[0])必须相等?如果两个对象的hash结果相等,即hash(a)==hash(b),是否一定相等?答案当然是否定的(不然就不叫冷知识了),大家可以先试着回答一下,再往下看。-----想想分界线-----好吧,我们先来看第一题。两个相同的元组a和b有如下关系:>>>a=(float('nan'),)>>>b=a>>>a#(nan,)>>>b#(nan,)>>>type(a),type(b)(,)>>>a==bTrue>>>aisb#即id(a)==id(b)True>>>a[0]==b[0]False上面的代码表明:a等于b(type、value、id都相等),但它们的相反元素不相等。两个元组都只有一个元素(逗号后没有其他元素,这是单元素元组的表示,即len(a)==1)。float()是一个内置函数,可以将输入参数构造成浮点数。为什么会这样?首先检查文档。这个内置函数的解析规则是:sign::="+"|“-”无穷大::=“无穷大”|"inf"nan::="nan"numeric_value::=floatnumber|无限|nannumeric_string::=[sign]numeric_value解析时,可以解析前后空格,前缀的加减号(+/-),浮点数。此外,它还可以解析两种类型的字符串(不区分大小写):“Infinity”或“inf”,表示无限数;“nan”,意思是not-a-number,准确的说是指除了数字以外的一切。早先分享的第一个冷知识与“南”有关。作为一个整体,两个元组是相等的,但它们唯一的元素是不相等的。发生这种情况是因为“nan”的意思不是数字,而是一个范围,因此无法比较。为了对比,我们看一下两个“无限浮点数”的结果:>>>a=(float('inf'),)>>>b=a>>>a#(inf,)>>>b#(inf,)>>>a==b#True>>>aisb#True>>>a[0]==b[0]#True注意最后比较的,是与前面两个元组正好相反。由此,我们可以得出结论,两个无穷大的浮点数是相等的,而两个“不是数字的东西”是不相等的。简化一下,你可以这样看:>>>a=float('inf')>>>b=float('inf')>>>c=float('nan')>>>d=float('nan')>>>a==b#True>>>c==d#False以上就是冷知识的第一个秘密。再看第二个:>>>hash(float('nan'))==hash(float('nan'))没错刚才说了两个“不是数字的东西”不相等,但是这里它表明它们的哈希结果是相等的,这是相当违反直觉的。我们可以推断出一个简单的结论:两个不相等的对象可能具有相同的哈希结果。原因是hash(float('nan'))的结果等于0,是一个固定值,当然比较起来是相等的。其实关于hash()函数,还埋了一个彩蛋:>>>hash(float('inf'))#314159>>>hash(float('-inf'))#-314159你觉得这个值很熟悉吗?去掉小数点后,正好是圆周率的前五位,3.14159。在早期版本的Python中,负无穷大的哈??希值实际上是-271828,取自自然对数e。这两个数字都硬编码在Python解释器中,有点像致敬。由于float('nan')的哈希值相等,这通常意味着它们不能作为字典的不同键,但事实却出乎意料:>>>a={float('nan'):1,float('nan'):2}>>>a{nan:1,nan:2}#比较:>>>b={float('inf'):1,float('inf'):2}>>>b{inf:2}如上图,两个nan键值表达式完全一样(注意没有用引号括起来),可以共存,但inf只能合并合二为一,再次展现馕的神奇。好了,两个冰冷的小知识分享给大家。其背后的原因是,当float()取浮点数时,Python允许nan(不是数字)的存在,这意味着不准确的存在,从而导致这些奇怪的结果。最后总结一下:两个包含float('nan')的元组,作为一个整体比较,结果是相等的;两个相等的元组,它们的相反元素可能不相等float('nan')表示一个“不是数字”的东西,它本身不是一个确定的值,两个对象比较时不相等,但是哈希结果是一个固定值,比较时相等;可以作为字典的键值,不冲突键值float('inf')表示一个无穷大的浮点数,可以看做是一个定值。当比较两个对象时,它们是相等的,它们的散列结果也相等;可以作为字典的键值,但会发生冲突float('nan')的哈希结果为0,float('inf')的哈希结果为314159参考:https://docs.python.org/3/library/functions.html#floathttps://www.pythondoeswhat.com/2019/09/welcome-to-float-zone.html公众号【蟒猫】,本号连载一系列高-优质文章,包括喵星哲学猫系列、Python进阶系列、好书推荐系列、技术文案、优质英文推荐及翻译等,欢迎关注。