在 Java 中使用 BigDecimal 手动 Math.pow

Posted

技术标签:

【中文标题】在 Java 中使用 BigDecimal 手动 Math.pow【英文标题】:Manual Math.pow using BigDecimal in Java 【发布时间】:2017-03-07 13:07:38 【问题描述】:

我正在尝试使用 BigDecimal 数据类型为 Math.pow 编写手动代码,因为稍后我将使用非常小的值。

我得到了 math.pow 的代码,然后我尝试将其转换为 BigDecimal。

public static double power(double base, int exponent) 
double ans = 1;
if (exponent != 0) 
    int absExponent = exponent > 0 ? exponent : (-1) * exponent;
    for (int i = 1; i <= absExponent; i++) 
        ans *= base;
    

    if (exponent < 0) 
        // For negative exponent, must invert
        ans = 1.0 / ans;
    
 else 
    // exponent is 0
    ans = 1;


return ans;


我将 double 和 int 数据类型转换为 BigDecimal 并尝试相应地更改代码,但不知何故我没有得到正确的结果。

 public static BigDecimal powerBig(BigDecimal base, BigDecimal exponent) 

    BigDecimal ans=  new BigDecimal(1.0);
    BigDecimal k=  new BigDecimal(1.0);
    BigDecimal t=  new BigDecimal(-1.0);
    BigDecimal no=  new BigDecimal(0.0);

    if (exponent != no) 
         BigDecimal absExponent =  exponent.signum() > 0 ? exponent : t.multiply(exponent);
        for (int i =  1 ; i <= absExponent.signum(); i++) 
            ans =ans.multiply(base);
        

        if (exponent.signum() < 0) 
            // For negative exponent, must invert
            ans = k.divide(ans);
        
     else 
        // exponent is 0
        ans = k;
    

    return ans;

我正在尝试运行它

 BigDecimal check =  new BigDecimal (4.0);
 BigDecimal Euler = new BigDecimal (2.7182818);

  powerBig(Euler,check);

但我得到的只是欧拉值。有人可以帮我解决我的代码中的错误吗?

将指数类型更改为 int 后代码现在运行

public static BigDecimal powerBig(BigDecimal base, int exponent) 

    BigDecimal ans=  new BigDecimal(1.0);
    BigDecimal k=  new BigDecimal(1.0);
    //BigDecimal t=  new BigDecimal(-1.0);
    //BigDecimal no=  new BigDecimal(0.0);

    if (exponent != 0) 
         int absExponent =  exponent > 0 ? exponent :  (-1)*exponent;
        for (int i =  1 ; i <= absExponent; i++) 
            ans =ans.multiply(base);
        

        if (exponent < 0) 
            // For negative exponent, must invert
            ans = k.divide(ans);
        
     else 
        // exponent is 0
        ans = k;
    

    return ans;

【问题讨论】:

exponent != no - 你认为这是做什么的?甚至 equals 都不能与 BigDecimal 一起使用,你为什么认为 == 会呢? 我把它改成了 exponent.signum() > 0 但还是不行 鉴于BigDecimal.sigNum() returns -1,0,1 for (int i = 1 ; i &lt;= absExponent.signum(); i++) 到底做了什么?简而言之,调试你的代码 - 问题都是由于缺乏关注...... 我正在尝试将基数(查找指数)的乘法循环运行与指数一样多的次数。 此外,这显然不适用于派系价值,所以为什么不直接使用BigDecimal.pow?? 【参考方案1】:

您的问题是 BigDecimal.sigNum() 如果数字是正数、零或负数,则返回 1、0 或 -1,因此 absExponent.sigNum() 将始终返回 1,您的循环将在第一次执行时结束

此版本适用于欧拉示例

public static BigDecimal powerBig(BigDecimal base, BigDecimal exponent) 

    BigDecimal ans=  new BigDecimal(1.0);
    BigDecimal k=  new BigDecimal(1.0);
    BigDecimal t=  new BigDecimal(-1.0);
    BigDecimal no=  new BigDecimal(0.0);

    if (exponent != no) 
        BigDecimal absExponent =  exponent.signum() > 0 ? exponent : t.multiply(exponent);
        while (absExponent.signum() > 0)
            ans =ans.multiply(base);
            absExponent = absExponent.subtract(BigDecimal.ONE);
        

        if (exponent.signum() < 0) 
            // For negative exponent, must invert
            ans = k.divide(ans);
        
     else 
        // exponent is 0
        ans = k;
    

    return ans;

BigDecimal 类也有一个 pow 函数,所以如果你想保持简单,你可以放

 BigDecimal Euler = new BigDecimal (2.7182818);
 Euler.pow(4);

【讨论】:

如果 exponent 不是整数,这将非常糟糕。那么.. 为什么不使用 BigDecimal.pow? 您确定else-clause 有可能被执行吗?只要no 是用一个新对象创建的,no != exponent 就永远成立。

以上是关于在 Java 中使用 BigDecimal 手动 Math.pow的主要内容,如果未能解决你的问题,请参考以下文章

BigDecimal使用整理

java中BigDecimal在金融行业中的使用

java.math.BigDecimal类multiply的使用

如何在java代码中使用elasticsearch painless BigDecimal?

Java 中如何比较两个BigDecimal 以及BigDecimal的坑

Java之BigDecimal 使用总结