实现 pow(x, n)
Posted
技术标签:
【中文标题】实现 pow(x, n)【英文标题】:Implement pow(x, n) 【发布时间】:2015-06-15 05:30:20 【问题描述】:当我尝试这个时,为什么这个函数给出错误答案-1
而不是正确答案1
? myPow(-1.00000, -2147483648)
double QuickPower(double x, int n)
if(n==0)
return 1;
if(n==1)
return x;
if(n>=2)
int res=n%2;
double half=QuickPower(x,n/2);
return res? Half*half*x: half*half;
double myPow(double x, int n)
return n>=0? QuickPower(x,n):(1/QuickPower(x,-n));
我只是尝试运行下面的代码。打印出“Hello World”。
这里我没有指定数据类型,但它仍然通过 if 语句。为什么?if (-1 > 2147483648)
cout << "Hello World";
【问题讨论】:
您是否尝试过添加一些std::cout << ...
跟踪,以便查看它正在进行的计算,以及它们与您的预期不同的地方?还是使用调试器?根据 Mitch 的提示 - 很快就会发现问题。
double myPow(double a, double b) return exp(b * log(a));
更快更容易(但尽管标题具有误导性,但我想问题不在于那个)。
@Amadan:如果 a
【参考方案1】:
错误是整数溢出的结果。
在myPow
中,当 n 为负数时,您将 n 取反。
否定 -2147483648 得到 2147483648,它比最大正符号 32 位整数值(2147483647)多 1。使用更大的整数数据类型来修复错误。
【讨论】:
【参考方案2】:您的问题是由于计算 -n 时整数溢出造成的。
在您的系统(和我的本地系统)上INT_MIN
=-2147483648 和INT_MAX
=2147483647。
所以问题是-(INT_MIN)
不能表示为整数。
但是,您无需使用更高精度的整数类型即可避免此问题:
自从
xn = xn+1 / x = (1/x) / x-(n+1)
我们可以将myPow
改写为
double myPow(double x, int n)
return n>=0? QuickPower(x,n):(1/x)/QuickPower(x,-(n+1));
由于-(INT_MIN+1)=INT_MAX
,此功能正常。
值得注意的是,myPow(0,-k)
将返回 +/- Infinity (n=-1) 或 NaN (nman page for the C pow function 来获取所有边缘情况。
【讨论】:
为什么要加1?这是什么意思? @Martingalemsy 因为 int 的范围是从 -2147483648 到 2147483647。整个二进制字段可以表示 4294967296 个数字。您需要考虑值“0”、0xFFFFFFF = 2147483648、0x0000000 = 0 和 0x7FFFFFF = -2147483647。结帐 2 的补充了解更多信息【参考方案3】:注意Primitive data type ranges 是:
short int and int: −32,768 to 32,767
unsigned short int and unsigned int: 0 to 65,535
long int: −2,147,483,648 to 2,147,483,647
unsigned long int: 0 to 4,294,967,295
long long int: −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
参考: MSDN 和 The GNU C Reference
正如你所看到的,一个整数可以容纳的最小值是−2,147,483,648
,所以当你执行-(−2,147,483,648)
时发生了一个整数溢出。
所以使用long long int
而不是int
来处理大签名数。
以下代码:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
double QuickPower(double x, long long int n)
if(n==0)
return 1;
if(n==1)
return x;
if(n>=2)
long long int res=n%2;
double half=QuickPower(x,n/2);
return res? half*half*x: half*half;
else
return 0;
double myPow(double x, long long int n)
return n>=0? QuickPower(x,n):(1/QuickPower(x,-n));
int main ()
cout << myPow(-1.00000, -2147483648);
给我输出:
1
【讨论】:
你引用的范围不标准,甚至不常见。 从 5.2.4.2.1 开始:“下面给出的值应替换为常数表达式……在幅度(绝对值)上等于 或更大同一个标志。”您将最小范围引用为最大范围。 您在 C++ 问题中引用了 C 标准。 你应该使用 和 std::numeric_limits/*Java Solution */
class Solution
public double myPow(double x, int n)
if(n == 0) return 1;
if(Math.abs(x-0.0)<0.0000001) return 0.0;
if(Math.abs(x-1.0)<0.0000001) return 1.0;
if(n < 0) x = 1.0/x;
return Power(x, Math.abs(n));
double Power(double x, int n)
if(n == 0) return 1;
if(n == 1) return x;
return ((n&0x1) == 1) ? x*Power(x*x, n/2) : Power(x*x, n/2);
【讨论】:
【参考方案5】:C# 简单解决方案:
class Program
private static void Main(string[] args)
var result = MyPow(-1.00000, -2147483648);
public static double MyPow(double x, int n)
return Math.Pow(x, n);
运行此代码后,变量“result”的值将等于 1
【讨论】:
以上是关于实现 pow(x, n)的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode练习(Python):数学类:第50题:Pow(x, n):实现 pow(x, n) ,即计算 x 的 n 次幂函数。
Leetcode练习(Python):数学类:第50题:Pow(x, n):实现 pow(x, n) ,即计算 x 的 n 次幂函数。
2021-09-27:Pow(x, n)。实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,x**n)。力扣50。