- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 Windows 计算器中,当我们执行“3^8.73”时,结果是“14630,816172800116064202808828951”,但当我们在 Java 中执行时,结果是“Math.pow (3, 8.73)”结果为“14630.816172800123”。
我如何在 Java 中像在 Windows 计算器中一样使用 presicion 执行 pow(逗号后的 32 个数字)?
我不能使用 BigDecimal 类,因为只有 pow(int) - 我需要 pow(double) 方法。
我找不到关于这个问题的任何解决方案。对于 Android,可能有比 BigDecimal 更好的类,我们可以在哪里做 pow(double)?
感谢您的回答:*。
最佳答案
我的天啊...
我在这上面花了几天时间。我尝试了很多算法,但没有一个不起作用......然后我在我的函数中写道:
pow(new BigDecimal(3), new BigDecimal("8.73")) // <-- this is String in 2 argument (good)
不是:
pow(new BigDecimal(3), new BigDecimal(8.73)) // <-- this is double in 2 argument (bad)
现在一切正常...
所以如果你也想拥有好的函数/方法pow(BigDecimal x, BigDecimal y)你必须下载这个类:BigFunctions.java (我从这本书中得到这段代码:Java Number Cruncher: The Java ...)ln 和 exp 有很好的方法 - 我们需要它们到我们的pow。接下来将这个类放入你的项目中,最后你必须在你的一些类中编写这个方法(这个方法的完整版本在这篇文章的结尾):
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);
return result;
}
在某些情况下,比如这里:
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.41421356237309504880168872420970
2.00000000000000000000000000000001
所以我们可以这样修改我们的方法:
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.41421356237309504880168872420970
2
我发现了一个问题——当我们提高 big 值时,他的精度不好,所以下面是 pow 方法的最终版本。
完整的 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;
}
}
关于Java/Android pow precision/scale like in Windows calculator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30336628/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 9 年前。 Improv
我发现了 pow(x, n) 的迭代实现,它需要 o(log n) 时间和常量空间,如下所示: double pow(double x, int n) { double left = x;
我想创建一个特征,说它实现了num_traits::pow::Pow - Rust。 我的特征当前定义为: pub trait PrimeSieveTrait: AddAssign + MulAs
对于我的项目,我应该在 java 中创建一个图形计算器(绘制图形),并以函数作为输入。我已经找到了一种正确绘制函数图的方法。但是我想不出一种方法可以让解释器理解该功能。如果我能够做到这一点,以便我可以
我发现对于大整数,math.pow() 没有成功给出它的整数版本。 (我在使用 math.pow 实现时遇到了一个错误 Karatsuba multiplication)。 例如: >>> a_Siz
问题或多或少说明了一切。 calling a host function("std::pow ") from a __device__/__global__ function("_calc_psd")
我想知道,因为当我在检查模式下运行我的代码时,似乎出现了一些差异。例如: List getFactors(int n) { List factors = [[1, n]]; doubl
pow(a/b,x) 和 pow(b/a,-x) 在精度上有区别吗?如果存在,将小于 1 的数字提升为正幂或将大于 1 的数字提升为负幂会产生更准确的结果吗? 编辑:让我们假设 x86_64 处理器和
此代码在 Windows 上的 Visual Studio 2010 上正确编译,但我在 Linux、g++ 上遇到此错误。谁能解释一下如何解决这个问题? int bits; T scale; std
Python内置的pow(x, y)(没有第三个参数)返回的结果和math.pow()返回的值有区别吗>,在两个 float 参数的情况下。 我问这个问题是因为 documentation对于 mat
这个问题在这里已经有了答案: Why was std::pow(double, int) removed from C++11? (1 个回答) 关闭 9 年前。 在 C++ 03 中,使用例如st
我可以将pow()与#include 一起使用,而无需使用using关键字或::运算符。为什么? 最佳答案 来自标准的[headers]/4。 Except as noted in Clause 20
我觉得这很有趣: System.out.println( (long)(Math.pow(2,63) - 1) == Long.MAX_VALUE); // true System.out.prin
这个打印 100: int j=2; int i= pow(10,2); printf("%d\n", i); 这个打印出 99: int j=2; int i= pow(10,j); print
这也是一个与数学相关的问题,但我想用 C++ 实现它...所以,我有一个 2^n 形式的数字,我必须计算它的数字总和(以 10 为基数;P)。我的想法是用下面的公式来计算: sum = (2^n mo
我看到这个关于 std::pow 的老问题:What is more efficient? Using pow to square or just multiply it with itself? 旧
我正在尝试比较 pow(x,2.0) 和 pow(x,2.0000001) 的性能,但我认为 2.0 会快得多,但它们的速度相同。我什至通过使用 -Xint 参数运行 jar 来删除 JIT 优化。
我的 linux 版本是 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u1 (2019-09-20) x86_64 GNU/Linux我的 gcc 版本是
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 6 年前。 Improve t
python3 中的 pow() 函数提供指数的值。 >>>pow(2,3) 8 Python3 支持负指数,即 可以使用 pow(10,-1) 表示。当我计算 pow(4,-1,5) 时,它给出了输
我是一名优秀的程序员,十分优秀!