Windows计算器中的Java/Android pow精度/类似比例

Windows计算器中的Java/Android pow精度/类似比例,java,android,math,precision,pow,Java,Android,Math,Precision,Pow,例如,在Windows计算器中,当我们执行“3^8.73”时,结果是“14630816172800116064202808828951”,但在Java中执行“Math.pow(3,8.73)”时,结果是“14630.8172800123” 如何在Java中使用类似Windows calculator的Presision(逗号后32个数字)执行pow 我不能使用BigDecimal类,因为只有pow(int)-我需要pow(double)方法 关于这个问题,我找不到任何解决办法。 对于Androi

例如,在Windows计算器中,当我们执行“3^8.73”时,结果是“14630816172800116064202808828951”,但在Java中执行“Math.pow(3,8.73)”时,结果是“14630.8172800123

如何在Java中使用类似Windows calculator的Presision(逗号后32个数字)执行pow

我不能使用BigDecimal类,因为只有pow(int)-我需要pow(double)方法

关于这个问题,我找不到任何解决办法。 对于Android,可能有比BigDecimal更好的类,我们可以在其中执行pow(double)

感谢您的回答:。

天哪

我为此花了几天时间。我尝试了很多算法,但没有一个不起作用。。。然后我在函数中写道:

pow(new BigDecimal(3), new BigDecimal("8.73")) // <-- this is String in 2 argument (good)

在某些情况下,例如:

BigDecimal x = pow(new BigDecimal(2), new BigDecimal("0.5")); // sqrt(2)
BigDecimal z = pow(x, new BigDecimal(2)); // x^2;
System.out.println(x);
System.out.println(z);
我们取得了以下成果:

1.41421356237309504800168872420970

2.00000000000000000000000001

所以我们可以这样修改我们的方法:

public static BigDecimal pow(BigDecimal x, BigDecimal y)
{
    BigDecimal val = BigFunctions.ln(x, 33).setScale(32, RoundingMode.HALF_UP).multiply(y);
    BigDecimal result = BigFunctions.exp(val, 33).setScale(32, RoundingMode.HALF_UP);
    
    String regExp = "0{30}", resultString = result.toPlainString();
    int commaIndex = resultString.indexOf(".");
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(resultString.substring(commaIndex));
    boolean hasMatch = matcher.find();
    if(hasMatch == true)
    {
        return new BigDecimal(resultString.substring(0, commaIndex));
    }
    return result;
}

结果是:

1.41421356237309504800168872420970

二,




编辑: 我发现了一个问题——当我们提高大值时,他的精度就不好,所以下面是pow方法的最终版本

完全功率法:

public static BigDecimal pow(BigDecimal x, BigDecimal y)
{
    String yString = y.toPlainString();
    if(y.compareTo(BigDecimal.valueOf(999999999)) == 1) // In smaller ^values (like 1000000) in each algorithm we must waiting infinitely long so this is only 'protection' from exceptions.
    {
        System.out.println("Too big value for exponentiation");
        return new BigDecimal("0");
    }
    else if(x.compareTo(BigDecimal.valueOf(0)) == 0)
    {
        return new BigDecimal("0");
    }
    int yStringCommaIndex = yString.indexOf(".");

    if(yStringCommaIndex == -1)
    {
        String xString = x.toPlainString(), xString2;
        int precision = xString.indexOf(".")+1;
        if(precision == 0)
        {
            if(xString.length() > 53)
            {
                System.out.println("Too long value of integer number. Max is 53.");
                return new BigDecimal("0");
            }
            precision = xString.length()+1;
        }
        else if(precision > 54)
        {
            System.out.println("Too long value of integer number. Max is 53.");
            return new BigDecimal("0");
        }
        
        BigDecimal result = x.pow(Integer.parseInt(yString)).setScale(32, RoundingMode.HALF_UP);
        xString2 = result.toPlainString();
        precision = xString2.indexOf(".");
        if(precision > 32)
        {
            precision = 32;
        }
        else if(precision == -1 || precision == 1 && xString2.charAt(0) == '0')
        {
            precision = 0;
        }
        result = result.setScale(32-precision, RoundingMode.HALF_UP);
        
        
        String regExp = "9{16}", resultString = result.toPlainString();
        int commaIndex = resultString.indexOf(".");
        if(commaIndex == -1)
        {
            return result;
        }
        String result2 = resultString.substring(0, commaIndex);
        resultString = resultString.substring(commaIndex+1);
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(resultString);
        boolean hasMatch = matcher.find();
        if(hasMatch == true)
        {
            result2 += "."+resultString.substring(0, matcher.start());
            if(result2.endsWith("."))
            {
                result2 = result2.substring(0, commaIndex);
                return new BigDecimal(result2).add(BigDecimal.valueOf(1));
            }
            result2 += "9";
            return new BigDecimal(result2).setScale((result2.length()-1)-(commaIndex+1), RoundingMode.HALF_UP);
        }
        
        regExp = "0{16}|0+$";
        resultString = result.toPlainString();
        commaIndex = resultString.indexOf(".");
        if(commaIndex == -1)
        {
            return result;
        }
        result2 = resultString.substring(0, commaIndex+1);
        resultString = resultString.substring(commaIndex+1);
        pattern = Pattern.compile(regExp);
        matcher = pattern.matcher(resultString);
        hasMatch = matcher.find();
        if(hasMatch == true)
        {
            result2 += resultString.substring(0, matcher.start());
            if(result2.endsWith("."))
            {
                result2 = result2.substring(0, commaIndex);
            }
            return new BigDecimal(result2);
        }
        return result;
    }
    else
    {
        if(x.compareTo(BigDecimal.valueOf(0)) == -1)
        {
            System.out.println("Wrong input values");
            return new BigDecimal("0");
        }
        
        BigDecimal x1 = x.pow(Integer.parseInt(yString.substring(0, yStringCommaIndex))); // Integer value
        
        String xString = x.toPlainString(), xString2;
        int precision = xString.indexOf(".")+1;
        if(precision == 0)
        {
            if(xString.length() > 53)
            {
                System.out.println("Too long value of integer number. Max is 53.");
                return new BigDecimal("0");
            }
            precision = xString.length()+1;
        }
        else if(precision > 54)
        {
            System.out.println("Too long value of integer number. Max is 53.");
            return new BigDecimal("0");
        }
        BigDecimal val = BigFunctions.ln(x, 33).setScale(32, RoundingMode.HALF_UP).multiply(new BigDecimal("0"+yString.substring(yStringCommaIndex)));
        BigDecimal x2 = BigFunctions.exp(val, 33).setScale(32, RoundingMode.HALF_UP); // Decimal value

        BigDecimal result = x1.multiply(x2).setScale(32, RoundingMode.HALF_UP);
        
        xString2 = result.toPlainString();
        precision = xString2.indexOf(".");
        if(precision > 32)
        {
            precision = 32;
        }
        else if(precision == -1 || precision == 1 && xString2.charAt(0) == '0')
        {
            precision = 0;
        }
        result = result.setScale(32-precision, RoundingMode.HALF_UP);
        
        String regExp = "9{16}", resultString = result.toPlainString();
        int commaIndex = resultString.indexOf(".");
        if(commaIndex == -1)
        {
            return result;
        }
        String result2 = resultString.substring(0, commaIndex);
        resultString = resultString.substring(commaIndex+1);
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(resultString);
        boolean hasMatch = matcher.find();
        if(hasMatch == true)
        {
            result2 += "."+resultString.substring(0, matcher.start());
            if(result2.endsWith("."))
            {
                result2 = result2.substring(0, commaIndex);
                return new BigDecimal(result2).add(BigDecimal.valueOf(1));
            }
            result2 += "9";
            return new BigDecimal(result2).setScale((result2.length()-1)-(commaIndex+1), RoundingMode.HALF_UP);
        }
        
        regExp = "0{16}|0+$";
        resultString = result.toPlainString();
        commaIndex = resultString.indexOf(".");
        if(commaIndex == -1)
        {
            return result;
        }
        result2 = resultString.substring(0, commaIndex+1);
        resultString = resultString.substring(commaIndex+1);
        pattern = Pattern.compile(regExp);
        matcher = pattern.matcher(resultString);
        hasMatch = matcher.find();
        if(hasMatch == true)
        {
            result2 += resultString.substring(0, matcher.start());
            if(result2.endsWith("."))
            {
                result2 = result2.substring(0, commaIndex);
            }
            return new BigDecimal(result2);
        }
        return result;
    }
}

使用long和BigInteger,就像它是十进制一样,然后转换。相关问题:是的,我看到了这个主题,但它对我没有帮助。Apfloat库只在Java上工作,在Android上不工作。大小数不是一个好的库。例如,“BigDecimalMath.pow(新的BigDecimal(“3”)、新的BigDecimal(“8.73”))和是“6000”。
public static BigDecimal pow(BigDecimal x, BigDecimal y)
{
    BigDecimal val = BigFunctions.ln(x, 33).setScale(32, RoundingMode.HALF_UP).multiply(y);
    BigDecimal result = BigFunctions.exp(val, 33).setScale(32, RoundingMode.HALF_UP);
    
    String regExp = "0{30}", resultString = result.toPlainString();
    int commaIndex = resultString.indexOf(".");
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(resultString.substring(commaIndex));
    boolean hasMatch = matcher.find();
    if(hasMatch == true)
    {
        return new BigDecimal(resultString.substring(0, commaIndex));
    }
    return result;
}
public static BigDecimal pow(BigDecimal x, BigDecimal y)
{
    String yString = y.toPlainString();
    if(y.compareTo(BigDecimal.valueOf(999999999)) == 1) // In smaller ^values (like 1000000) in each algorithm we must waiting infinitely long so this is only 'protection' from exceptions.
    {
        System.out.println("Too big value for exponentiation");
        return new BigDecimal("0");
    }
    else if(x.compareTo(BigDecimal.valueOf(0)) == 0)
    {
        return new BigDecimal("0");
    }
    int yStringCommaIndex = yString.indexOf(".");

    if(yStringCommaIndex == -1)
    {
        String xString = x.toPlainString(), xString2;
        int precision = xString.indexOf(".")+1;
        if(precision == 0)
        {
            if(xString.length() > 53)
            {
                System.out.println("Too long value of integer number. Max is 53.");
                return new BigDecimal("0");
            }
            precision = xString.length()+1;
        }
        else if(precision > 54)
        {
            System.out.println("Too long value of integer number. Max is 53.");
            return new BigDecimal("0");
        }
        
        BigDecimal result = x.pow(Integer.parseInt(yString)).setScale(32, RoundingMode.HALF_UP);
        xString2 = result.toPlainString();
        precision = xString2.indexOf(".");
        if(precision > 32)
        {
            precision = 32;
        }
        else if(precision == -1 || precision == 1 && xString2.charAt(0) == '0')
        {
            precision = 0;
        }
        result = result.setScale(32-precision, RoundingMode.HALF_UP);
        
        
        String regExp = "9{16}", resultString = result.toPlainString();
        int commaIndex = resultString.indexOf(".");
        if(commaIndex == -1)
        {
            return result;
        }
        String result2 = resultString.substring(0, commaIndex);
        resultString = resultString.substring(commaIndex+1);
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(resultString);
        boolean hasMatch = matcher.find();
        if(hasMatch == true)
        {
            result2 += "."+resultString.substring(0, matcher.start());
            if(result2.endsWith("."))
            {
                result2 = result2.substring(0, commaIndex);
                return new BigDecimal(result2).add(BigDecimal.valueOf(1));
            }
            result2 += "9";
            return new BigDecimal(result2).setScale((result2.length()-1)-(commaIndex+1), RoundingMode.HALF_UP);
        }
        
        regExp = "0{16}|0+$";
        resultString = result.toPlainString();
        commaIndex = resultString.indexOf(".");
        if(commaIndex == -1)
        {
            return result;
        }
        result2 = resultString.substring(0, commaIndex+1);
        resultString = resultString.substring(commaIndex+1);
        pattern = Pattern.compile(regExp);
        matcher = pattern.matcher(resultString);
        hasMatch = matcher.find();
        if(hasMatch == true)
        {
            result2 += resultString.substring(0, matcher.start());
            if(result2.endsWith("."))
            {
                result2 = result2.substring(0, commaIndex);
            }
            return new BigDecimal(result2);
        }
        return result;
    }
    else
    {
        if(x.compareTo(BigDecimal.valueOf(0)) == -1)
        {
            System.out.println("Wrong input values");
            return new BigDecimal("0");
        }
        
        BigDecimal x1 = x.pow(Integer.parseInt(yString.substring(0, yStringCommaIndex))); // Integer value
        
        String xString = x.toPlainString(), xString2;
        int precision = xString.indexOf(".")+1;
        if(precision == 0)
        {
            if(xString.length() > 53)
            {
                System.out.println("Too long value of integer number. Max is 53.");
                return new BigDecimal("0");
            }
            precision = xString.length()+1;
        }
        else if(precision > 54)
        {
            System.out.println("Too long value of integer number. Max is 53.");
            return new BigDecimal("0");
        }
        BigDecimal val = BigFunctions.ln(x, 33).setScale(32, RoundingMode.HALF_UP).multiply(new BigDecimal("0"+yString.substring(yStringCommaIndex)));
        BigDecimal x2 = BigFunctions.exp(val, 33).setScale(32, RoundingMode.HALF_UP); // Decimal value

        BigDecimal result = x1.multiply(x2).setScale(32, RoundingMode.HALF_UP);
        
        xString2 = result.toPlainString();
        precision = xString2.indexOf(".");
        if(precision > 32)
        {
            precision = 32;
        }
        else if(precision == -1 || precision == 1 && xString2.charAt(0) == '0')
        {
            precision = 0;
        }
        result = result.setScale(32-precision, RoundingMode.HALF_UP);
        
        String regExp = "9{16}", resultString = result.toPlainString();
        int commaIndex = resultString.indexOf(".");
        if(commaIndex == -1)
        {
            return result;
        }
        String result2 = resultString.substring(0, commaIndex);
        resultString = resultString.substring(commaIndex+1);
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(resultString);
        boolean hasMatch = matcher.find();
        if(hasMatch == true)
        {
            result2 += "."+resultString.substring(0, matcher.start());
            if(result2.endsWith("."))
            {
                result2 = result2.substring(0, commaIndex);
                return new BigDecimal(result2).add(BigDecimal.valueOf(1));
            }
            result2 += "9";
            return new BigDecimal(result2).setScale((result2.length()-1)-(commaIndex+1), RoundingMode.HALF_UP);
        }
        
        regExp = "0{16}|0+$";
        resultString = result.toPlainString();
        commaIndex = resultString.indexOf(".");
        if(commaIndex == -1)
        {
            return result;
        }
        result2 = resultString.substring(0, commaIndex+1);
        resultString = resultString.substring(commaIndex+1);
        pattern = Pattern.compile(regExp);
        matcher = pattern.matcher(resultString);
        hasMatch = matcher.find();
        if(hasMatch == true)
        {
            result2 += resultString.substring(0, matcher.start());
            if(result2.endsWith("."))
            {
                result2 = result2.substring(0, commaIndex);
            }
            return new BigDecimal(result2);
        }
        return result;
    }
}