在 Java 中确定百万、十亿、万亿、千万亿
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24434555/
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
Determine million, billion, trillion, quadrillion in Java
提问by user3707836
From this Standard dictionary numbers, I need a fastest way to convert some number below :
从这个标准字典数字中,我需要一种最快的方法来转换下面的一些数字:
1000000 = 1 Million
1435234 = 1.43 Million
350000000 = 350 Million
1000000000 = 1 Billion
1765000000 = 1.76 Billion
1000000000000 = 1 Trillion
1345342345000 = 1.34 Trillion
1000000000000000 = 1 Quadrillion
100000000000000000 = 100 Quadrillion
百万= 1百万
1435234 = 143万
3.5亿= 350百万
十亿= 10亿
17.65亿= 1.76亿
万亿= 1万亿
1345342345000 = 1.34兆
千万亿= 1千万亿
100000000000000000 = 100千万亿
and further.
并进一步。
I have tried like this below:
我试过如下:
public String truncateNumber(float floatNumber) {
long million = 1000000L;
long billion = 1000000000L;
long trillion = 1000000000000L;
long number = Math.round(floatNumber);
if ((number >= million) && (number < billion)) {
float fraction = calculateFraction(number, million);
return Float.toString(fraction) + "M";
} else if ((number >= billion) && (number < trillion)) {
float fraction = calculateFraction(number, billion);
return Float.toString(fraction) + "B";
}
return Long.toString(number);
}
public float calculateFraction(long number, long divisor) {
long truncate = (number * 10L + (divisor / 2L)) / divisor;
float fraction = (float) truncate * 0.10F;
return fraction;
}
but I think my solution is not quite true. So, what is a fastest way to do that in Java? Many Thanks.
但我认为我的解决方案并不完全正确。那么,在 Java 中最快的方法是什么?非常感谢。
采纳答案by Marco13
The first problem is that float
does not have enough precision to represent these numbers. In fact, even double
does not have enough precision for values in the Nonillion range - although this may not be so important here, because you obviously want to drop most of the information of this number anyhow.
第一个问题是float
没有足够的精度来表示这些数字。事实上,即使double
对于 Nonillion 范围内的值也没有足够的精度——尽管这在这里可能不那么重要,因为无论如何你显然想删除这个数字的大部分信息。
Nevertheless, I have implemented it here using BigInteger
. Converting this to use double
should be straightforward, if you don't care about the precision issues.
不过,我在这里使用BigInteger
. double
如果您不关心精度问题,将其转换为 use应该很简单。
The basic idea here is to create a NavigableMap
from powers of 1000 to the respective number name. This map can be quickly looked up using floorEntry
to find the best matching power (and thus, the number name).
这里的基本思想是创建一个NavigableMap
从 1000 的幂到相应数字名称的名称。可以使用此地图快速查找floorEntry
以找到最佳匹配功率(以及数字名称)。
import java.math.BigInteger;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;
public class NumberNames
{
public static void main(String[] args)
{
test("100", "Nearly nothing");
test("1000", "1 Thousand");
test("1230", "1.23 Thousand");
test("1000000", "1 Million");
test("1435234", "1.43 Million");
test("350000000", "350 Million");
test("1000000000", "1 Billion");
test("1765000000", "1.76 Billion");
test("1000000000000", "1 Trillion");
test("1345342345000", "1.34 Trillion");
test("1000000000000000", "1 Quadrillion");
test("100000000000000000", "100 Quadrillion");
test("1230000000000000000000000000000000000000000000000000000000000000", "1.23 Vigintillion");
}
private static void test(String numberString, String string)
{
BigInteger number = new BigInteger(numberString);
System.out.println(number+" is "+createString(number)+" should be "+string);
}
private static final String NAMES[] = new String[]{
"Thousand",
"Million",
"Billion",
"Trillion",
"Quadrillion",
"Quintillion",
"Sextillion",
"Septillion",
"Octillion",
"Nonillion",
"Decillion",
"Undecillion",
"Duodecillion",
"Tredecillion",
"Quattuordecillion",
"Quindecillion",
"Sexdecillion",
"Septendecillion",
"Octodecillion",
"Novemdecillion",
"Vigintillion",
};
private static final BigInteger THOUSAND = BigInteger.valueOf(1000);
private static final NavigableMap<BigInteger, String> MAP;
static
{
MAP = new TreeMap<BigInteger, String>();
for (int i=0; i<NAMES.length; i++)
{
MAP.put(THOUSAND.pow(i+1), NAMES[i]);
}
}
public static String createString(BigInteger number)
{
Entry<BigInteger, String> entry = MAP.floorEntry(number);
if (entry == null)
{
return "Nearly nothing";
}
BigInteger key = entry.getKey();
BigInteger d = key.divide(THOUSAND);
BigInteger m = number.divide(d);
float f = m.floatValue() / 1000.0f;
float rounded = ((int)(f * 100.0))/100.0f;
if (rounded % 1 == 0)
{
return ((int)rounded) + " "+entry.getValue();
}
return rounded+" "+entry.getValue();
}
}
回答by Peter Lawrey
I wouldn't use a float
as it doesn't have much precision. Use double instead.
我不会使用 afloat
因为它没有太多的精度。使用 double 代替。
static final long MILLION = 1000000L;
static final long BILLION = 1000000000L;
static final long TRILLION = 1000000000000L;
public static String truncateNumber(double x) {
return x < MILLION ? String.valueOf(x) :
x < BILLION ? x / MILLION + "M" :
x < TRILLION ? x / BILLION + "B" :
x / TRILLION + "T";
}
回答by Zoe
Personally, I use this. If you need decimals in the input numbers, you can use BigDecimal instead.
就个人而言,我使用这个。如果您需要输入数字中的小数,您可以使用 BigDecimal 代替。
BigInteger/BigDecimal is better than Float or Double or Long as it can keep even bigger values.
BigInteger/BigDecimal 比 Float 或 Double 或 Long 更好,因为它可以保持更大的值。
public static String customFormat(String pattern, BigInteger value) {
//To force the output to be equal if the language is set to english, spanish, norwegian or japanese.
NumberFormat nf = NumberFormat.getNumberInstance(Locale.ENGLISH);
DecimalFormat df = (DecimalFormat)nf;
df.applyPattern(pattern);
String output = df.format(value);
return output;
}
public static String numberConverter(BigInteger input) {
String points = customFormat("###,###,###,###,###,###,###,###,###.###", input);
String[] letters = new String[]{"Kc","Mc","Gc","Tc","Pc","Ec","Zc","Yc","Bc"};//your value names. Is not limited to two letters. Can also be more based on your maximum amount
int size = points.length();
String after = points;
if (size > 3) {
int firstPoint = points.indexOf(".");
String re = points;
re = points.substring(0,3);
System.out.println(re);
int pVar = 7;
if(re.contains(",")){
String[] parts = re.split(",");
if(parts[0].length() == 2){
pVar = 6;
}else if(parts[0].length() == 1){
pVar = 5;
}
}
after = points.substring(0, pVar);
int x = (size - firstPoint - 4/*3*/)/5;
String bafter = after + " " + letters[x];//adds the value designation to the letter.
after = bafter;
}
return after;
}
I realize this is not the most efficient piece of code due to its length, but it works flawlessly.
我意识到这不是最有效的一段代码,因为它的长度,但它完美无缺。
All values under 1000 show up as their full value. Upon reaching 1000 it shows as 1.000k. The code is designed to ensure 3 decimal spaces at all times. Changing pvar settings down by one in the if statement(which sets it down to two decimals at all times.) Removing the if statement will set a more dynamic number that changes by max chars.
1000 以下的所有值都显示为它们的完整值。达到 1000 后,它显示为 1.000k。该代码旨在始终确保 3 个小数位。在 if 语句中将 pvar 设置降低 1(始终将其设置为两位小数。)删除 if 语句将设置一个更动态的数字,该数字会根据 max chars 变化。
Some technical info about the max size of the BigINteger. Extracted from this question:
关于 BigINteger 的最大大小的一些技术信息。从这个问题中提取:
"There is no theoretical limit. The BigInteger class allocates as much memory as it needs for all the bits of data it is asked to hold.
“没有理论上的限制。BigInteger 类为它要求保存的所有数据位分配所需的尽可能多的内存。
There are, however, some practical limits, dictated by the memory available. And there are further technical limits, although you're very unlikely to be affected: some methods assume that the bits are addressable by int indexes, so things will start to break when you go above Integer.MAX_VALUE
bits."
然而,存在一些实际限制,由可用内存决定。还有进一步的技术限制,虽然你不太可能受到影响:一些方法假设这些位可以通过 int 索引寻址,所以当你超过Integer.MAX_VALUE
位时,事情就会开始崩溃。”
So if you are creating for computers, make sure you have enough memory for those massive numbers.
因此,如果您正在为计算机创建,请确保您有足够的内存来存储这些庞大的数字。