当前位置: 首页 > 面试题库 >

在Python中,用于浮点数的内置pow()和math.pow()之间的区别?

吴浩皛
2023-03-14
问题内容

在使用两个 float 参数的情况下,Python的内置pow(x, y)函数(没有第三个参数)返回的结果与的返回值是否有所不同?math.pow() __

我问这个问题,因为文件的math.pow()暗示pow(x, y)(例如x**y)在本质上是一样的math.pow(x, y)

math.pow(x,y)

将x提高到y。例外情况应尽可能遵循C99标准的附件“
F”。特别是,即使x为零或NaN,pow(1.0,x)和pow(x,0.0)始终返回1.0。如果x和y都是有限的,x是负数,并且y不是整数,则pow(x,y)是未定义的,并引发ValueError。

在2.6版中进行了更改:1 nan和nan ** 0的结果不确定。

请注意最后一行:该文档暗示,行为math.pow()是指数运算符的行为**(因此是pow(x, y))。这是官方保证吗?

背景:我的目标是提供一个实现 这两个 内置的pow()math.pow()对不确定性的数字 ,在相同的行为方式
与常规的Python花车(相同的数值结果,同样的例外,拐角情况相同的结果,等等)。我已经实现了一些效果很好的方法,但是有些极端情况需要处理。


问题答案:

快速检查

从签名中我们可以看出它们是不同的:

pow(x,y [,z])

math.pow(x,y)

另外,在shell中尝试它也会给您一个快速的想法:

>>> pow is math.pow
False

测试差异

了解这两个功能之间行为差异的另一种方法是测试它们:

import math
import traceback
import sys

inf = float("inf")
NaN = float("nan")

vals = [inf, NaN, 0.0, 1.0, 2.2, -1.0, -0.0, -2.2, -inf, 1, 0, 2]

tests = set([])

for vala in vals:
  for valb in vals:
    tests.add( (vala, valb) )
    tests.add( (valb, vala) )


for a,b in tests:
  print("math.pow(%f,%f)"%(a,b) )
  try:
    print("    %f "%math.pow(a,b))
  except:
    traceback.print_exc()

  print("__builtins__.pow(%f,%f)"%(a,b) )
  try:
    print("    %f "%__builtins__.pow(a,b))
  except:
    traceback.print_exc()

然后,我们可以注意到一些细微的差异。例如:

math.pow(0.000000,-2.200000)
    ValueError: math domain error

__builtins__.pow(0.000000,-2.200000)
    ZeroDivisionError: 0.0 cannot be raised to a negative power

还有其他区别,并且上面的测试列表不完整(没有长数字,没有复数,等等),但这将为我们提供实用的列表,说明这两个函数的行为方式不同。我还建议扩展上述测试,以检查每个函数返回的类型。您可能会写类似的东西来创建两个函数之间差异的报告。

math.pow()

math.pow()处理其参数的方法与内建**或完全不同pow()。这是以灵活性为代价的。在看看源,我们可以看到,参数math.pow()
直接转换为双打

static PyObject *
math_pow(PyObject *self, PyObject *args)
{
    PyObject *ox, *oy;
    double r, x, y;
    int odd_y;

    if (! PyArg_UnpackTuple(args, "pow", 2, 2, &ox, &oy))
        return NULL;
    x = PyFloat_AsDouble(ox);
    y = PyFloat_AsDouble(oy);
/*...*/

然后针对双精度进行检查以检查有效性,然后将结果传递到基础C数学库。

内建的 pow()

另一方面,内置函数pow()(与**运算符相同)的行为却大不相同,它实际上使用了Objects自己的**运算符实现,如果需要替换数字的或方法__pow__(),最终用户可以重写该实现。__rpow__()``__ipow__()

对于内置类型,研究为两个数字类型实现的幂函数之间的差异是有启发性的,例如floats,long和complex。

覆盖默认行为

在此处描述了模拟数字类型。本质上,如果您要为不确定性的数字创建新的类型,则要做的是为类型提供__pow__()__rpow__()并可能提供__ipow__()方法。这将使您的号码可以与运营商一起使用:

class Uncertain:
  def __init__(self, x, delta=0):
    self.delta = delta
    self.x = x
  def __pow__(self, other):
    return Uncertain(
      self.x**other.x, 
      Uncertain._propagate_power(self, other)
    )
  @staticmethod
  def _propagate_power(A, B):
    return math.sqrt(
      ((B.x*(A.x**(B.x-1)))**2)*A.delta*A.delta +
      (((A.x**B.x)*math.log(B.x))**2)*B.delta*B.delta
    )

为了覆盖,math.pow()您将不得不对其进行修补以支持您的新类型:

def new_pow(a,b):
    _a = Uncertain(a)
    _b = Uncertain(b)
    return _a ** _b

math.pow = new_pow

请注意,要执行此操作,您必须纠缠Uncertain类以应对Uncertain实例作为输入的__init__()



 类似资料:
  • 本文向大家介绍Python中pow()和math.pow()函数用法示例,包括了Python中pow()和math.pow()函数用法示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Python中pow()和math.pow()函数用法。分享给大家供大家参考,具体如下: 1. 内置函数pow() 2. math.pow() PS:这里再为大家推荐几款计算工具供大家参考使用: 在线一元函

  • 问题内容: 当我在MySQL中使用浮点和十进制数据类型时,它有什么区别? 我什么时候应该使用哪个? 问题答案: 这是我对此有疑问时发现的。 十进制完全符合这种情况下的预期,截断了其余部分,从而丢失了1/3的部分。 因此对于总和,小数点更好,但是对于除数,浮点数更好,当然到了某种程度。我的意思是,使用DECIMAL不会以任何方式为您提供“防故障算法”。 希望这可以帮助。

  • 问题内容: 有人可以解释这个代码吗? 输出: 问题答案: 将对象转换为列表时,它仅使用键。 但是,如果用方括号将其包围,则所有内容都将保持不变,只会使其成为s的列表,其中仅包含一项。 这是因为,当您使用循环遍历时,它也只使用了键: 但是,如果要获取键 和 值,请使用: 使用循环: 但是,当您输入时,它会为您提供: 有点误导:)

  • 问题内容: 和数据类型之间的区别是什么,应在哪种情况下使用? 对于任何类型的金融交易(例如,薪水领域),首选哪种交易,为什么? 问题答案: 仅当十进制(最多38位)提供的精度不足时才使用浮点或实数数据类型 近似数字数据类型不能存储为许多数字指定的确切值;他们存储的值非常接近。(Technet) 避免在WHERE子句搜索条件中使用浮点或实数列,尤其是=和<>运算符(Technet) 因此通常来说,因

  • 我不明白为什么这是1.0。它不应该是0.999999999999吗?因此,我提出了一种解决方案,python对其答案进行了自动舍入,但如果大于,则无法解释以下结果。。。 我以为四舍五入错误是因为尾数中使用的位数有限,指数(浮点数),但0.9999~~9也没有超出位数的限制...有人能解释一下为什么这些结果会这样吗?

  • 本文向大家介绍Python中关于浮点数的冷知识,包括了Python中关于浮点数的冷知识的使用技巧和注意事项,需要的朋友参考一下 本周的PyCoder's Weekly 上分享了一篇小文章,它里面提到的冷知识很有意思,我稍作补充,分享给大家。 它提到的部分问题,读者们可以先思考下: 若两个元组相等,即 a==b 且 a is b,那么相同索引的元素(如 a[0] 、b[0])是否必然相等呢? 若两个

  • 本文向大家介绍C和Python之间的区别,包括了C和Python之间的区别的使用技巧和注意事项,需要的朋友参考一下 C和Python都是主要使用的编程语言。各种特性使它们在程序设计领域流行。根据这些特征,我们可以区分C和Python。 以下是C和Python之间的重要区别。 序号 键 C语言 Python语言 定义 Python是一种通用的解释型,交互式,面向对象的高级编程语言。 类型 另一方面,

  • 本文向大家介绍Python和Bash之间的区别,包括了Python和Bash之间的区别的使用技巧和注意事项,需要的朋友参考一下 Python Python是一种编程语言,旨在易于实现和易于理解。它是一种动态类型的语言。它不使用指针。 重击 Bash是命令行解释器,默认情况下在Linux和MacOS操作系统中提供。它也可以安装在其他操作系统中。它是Linux和MacOS的默认用户外壳程序。 以下是P