从 Java 中的两个多头计算百分比的溢出安全方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10415531/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Overflow-safe way to calculate percentage from two longs in Java
提问by Steve McLeod
I have two non-negative longs. They may be large, close to Long.MAX_VALUE. I want to calculate a percentage from the two numbers.
我有两个非负多头。它们可能很大,接近 Long.MAX_VALUE。我想从这两个数字中计算一个百分比。
Usually I'd do this:
通常我会这样做:
long numerator = Long.MAX_VALUE / 3 * 2;
long denominator = Long.MAX_VALUE;
int percentage = (int) (numerator * 100 / denominator);
System.out.println("percentage = " + percentage);
This is not correct if numerator is within two order of magnitudes to Long.MAX_VALUE.
如果分子在 Long.MAX_VALUE 的两个数量级内,则这是不正确的。
What's a correct, simple, and fast way to do this?
什么是正确、简单和快速的方法来做到这一点?
回答by NPE
I'd use:
我会用:
int percentage = (int)(numerator * 100.0 / denominator + 0.5);
The 100.0
forces floating-point math from that point on, and the + 0.5
rounds to the nearest integer instead of truncating.
该100.0
部队从该点浮点数学运算,并+ 0.5
四舍五入为最接近的整数,而不是截断。
回答by esej
int percentage = (int) (0.5d + ((double)numerator/(double)denominator) * 100);
If you divide a long
with a long
you will get a long
, that is not good for percentages.
如果您将 along
与 a相除,long
您将得到 a long
,这对百分比不利。
回答by Oliver Charlesworth
The trivial way is to convert both to float
or double
before doing the calculation, at the expense of a slight loss in precision. It's also slow, in comparison to alternatives.
简单的方法是在计算之前float
或double
之前进行转换,代价是精度略有下降。与替代品相比,它也很慢。
One alternative is to split each value into two 32-bit components, and do long-multiplication and long-division.
一种替代方法是将每个值拆分为两个 32 位分量,并进行长乘法和长除法。
回答by Flexo
Unless I'm missing something obvious can't you just write:
除非我遗漏了一些明显的东西,否则你不能只写:
public class round {
public static void main(String[] argv) {
long numerator = Long.MAX_VALUE / 3 * 2;
long denominator = Long.MAX_VALUE;
int percentage = (int) (numerator / (denominator / 100));
System.out.println("percentage = " + percentage);
}
}
instead? I.e. Instead of making the numerator bigger before division make the denominator smaller. Since you know the denominator is large there's no risk that the division will give 0, which is the reason for usually writing (n * 100) / d
when you're not using floating point numbers.
反而?即不是在除法之前使分子变大,而是使分母变小。由于您知道分母很大,因此除法不会产生 0 的风险,这就是通常(n * 100) / d
在您不使用浮点数时编写的原因。
回答by Leninkumar Koppoju
Guys implement in following way because it is suggested to do calculations with BigDecimal and BigInteger. Here is implementation:
伙计们按照以下方式实现,因为建议使用 BigDecimal 和 BigInteger 进行计算。这是实现:
BigDecimal n = new BigDecimal(Long.MAX_VALUE);
BigDecimal d = new BigDecimal(Long.MAX_VALUE);
BigDecimal i = new BigDecimal(100);
int percentage = n.multiply(i).divide(d).intValue();
System.out.println(percentage);