Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python abs()函数在负数上失败_Python_Python 3.x_Numpy_Python 3.6_Absolute Value - Fatal编程技术网

Python abs()函数在负数上失败

Python abs()函数在负数上失败,python,python-3.x,numpy,python-3.6,absolute-value,Python,Python 3.x,Numpy,Python 3.6,Absolute Value,我在linux上使用python3.6,遇到了一个非常明显的abs功能故障。我的变量x最终可能是一个非常大的负数-inf,但是绝对值abs函数仍然返回一个负数,这是不可能的。我对我的代码进行了快速修复,只在abs的输入中添加了0.1,但是。。。。我是否误解了abs应该如何使用 $> x -9223372036854775808 $> abs(x) -9223372036854775808 $> np.abs(x) -9223372036854775808 $> ab

我在linux上使用python3.6,遇到了一个非常明显的abs功能故障。我的变量x最终可能是一个非常大的负数-inf,但是绝对值abs函数仍然返回一个负数,这是不可能的。我对我的代码进行了快速修复,只在abs的输入中添加了0.1,但是。。。。我是否误解了abs应该如何使用

$> x
-9223372036854775808

$> abs(x)
-9223372036854775808

$> np.abs(x)
-9223372036854775808

$> abs(x+.1)
9.223372036854776e+18

$> np.abs(x+.1)
9.223372036854776e+18

编辑:在下面解决,但它归结为x是一个numpy.int64,而不仅仅是int,我不知道。

你没想到提到它,我从你的np.abs测试中推断出来,但重要的是x是一个numpy.int64或等效的有符号64位类型。这个特定的值,in,没有正的等价物,所以abs只是再次产生相同的值,它可以引发一个异常,但是numpy坚持低级别的C行为,在这种情况下它返回原始值

首先将它转换为一个真正的Python int,例如absintx,它就会工作

解释其为何以这种方式工作:


-9223372036854775808的位模式为0x8000_0000_0000_0000仅设置最高位,为可读性加下划线。二的补码求反是通过翻转所有位,然后加上一个进位的算法来处理的,因此转换将0x8000_0000_0000_0000_0000_0000更改为0x7fff_fff_fff_fff_fff_fff_fff所有翻转的位,然后加上1,它携带字段的整个长度,因为除高位外的每一位都已设置,再次生成0x8000_0000_0000_0000。同一位模式实际上对应于无符号64位数量等于9223372036854775808的位模式,但如果将其解释为有符号,则继续将其解释为最负的值,没有一个大于不能表示为int64的最大正值int64的值。

您不想提及它,我是从您使用np.abs的测试中推断出来的,但重要的是x是numpy.int64或等效的有符号64位类型。这个特定的值,in,没有正的等价物,所以abs只是再次产生相同的值,它可以引发一个异常,但是numpy坚持低级别的C行为,在这种情况下它返回原始值

首先将它转换为一个真正的Python int,例如absintx,它就会工作

解释其为何以这种方式工作:


-9223372036854775808的位模式为0x8000_0000_0000_0000仅设置最高位,为可读性加下划线。二的补码求反是通过翻转所有位,然后加上一个进位的算法来处理的,因此转换将0x8000_0000_0000_0000_0000_0000更改为0x7fff_fff_fff_fff_fff_fff_fff所有翻转的位,然后加上1,它携带字段的整个长度,因为除高位外的每一位都已设置,再次生成0x8000_0000_0000_0000。同一位模式实际上对应于无符号64位数量等于9223372036854775808的位模式,但如果将其解释为有符号,则继续将其解释为最负的值,没有一个大于不能表示为int64的最大正值int64值。

我无法在MacOS High Sierra上的Python 3.6.3中复制此值。我还尝试使用x=-9223372036854775808然后使用absx来复制它,结果为正值。请指定您正在使用的shell和Python版本。这不会在Python 3.8或2.7中重现,无论是命令行执行程序还是空闲shell。在Ubuntu 20.04.printx中使用Python 3.8.5和ipython都很好,typex显示了什么?我无法在MacOS High Sierra上的Python 3.6.3中复制它。我还尝试使用x=-9223372036854775808然后使用absx来复制它,它产生了积极的结果请指定您正在使用的shell和Python版本。这不会在Python 3.8或2.7中重现,无论是命令行执行程序还是空闲shell。在Ubuntu 20.04.printx中,Python 3.8.5和ipython对我来说都很好,typex显示了什么?对我来说,这确实像是一个Python bug,不是很常见Zen@Chris_Rands:它不是Python,而是numpy;Python abs信任类型的_abs___)方法返回正确的值,因为它不知道它实际上是一个整数,并且返回值在逻辑上是错误的。numpy更像是裸机,不惜一切代价提高性能,而不是核心Python,根本不是这样;在这样的情况下,检查每一个数学运算是否存在溢出,其中2**64-1值不需要溢出,而一个可能会执行繁重的数字运算的代码有时需要无声溢出,这会减慢速度以获得最小的好处(如果有的话)。当然,谢谢你说服了我@悖论:不是一个下层选民,但我明白了;OP忽略了告诉我们x是一个裸体类型。虽然我的心理调试能力非常棒,在这种情况下,我几乎100%确信它们达到了目标,但如果我没有达到目标,我会限制自己发表评论,这些问题忽略了关键细节,比如所使用的库和变量的定义
“暗影游侠”是的,他们并没有提供一个很好的答案,可以说是很糟糕的。我同意你的看法,OP应该做得更好,为我们提供正确的上下文Zen@Chris_Rands:它不是Python,而是numpy;Python abs信任类型的_abs___)方法返回正确的值,因为它不知道它实际上是一个整数,并且返回值在逻辑上是错误的。numpy更像是裸机,不惜一切代价提高性能,而不是核心Python,根本不是这样;在这样的情况下,检查每一个数学运算是否存在溢出,其中2**64-1值不需要溢出,而一个可能会执行繁重的数字运算的代码有时需要无声溢出,这会减慢速度以获得最小的好处(如果有的话)。当然,谢谢你说服了我@悖论:不是一个下层选民,但我明白了;OP忽略了告诉我们x是一个裸体类型。虽然我的心理调试能力非常棒,在这种情况下,我几乎100%确信它们达到了目标,但如果我没有达到目标,我会限制自己发表评论,忽略关键细节的问题,如所使用的库和变量定义,不会提供一个很好的答案,而且可以说是不好的。@ShadowRanger是的。我同意你的看法,OP应该做得更好,为我们提供正确的背景。