解析双数和数百万

Posted

技术标签:

【中文标题】解析双数和数百万【英文标题】:Parsing double numbers and millions 【发布时间】:2016-12-23 12:09:41 【问题描述】:

我有一个文件,它代表像 29.879.999 这样的数百万和像这样 28.09 这样的双倍数字。我正在尝试使用NumberFormat 解析它们并将它们全部(整数和双精度)转换为double。这是我写的:

for (String[] entry : data) 
NumberFormat nf = NumberFormat.getInstance();
Number value = nf.parse(entry[4]).doubleValue();
System.out.println("closingvalue: "+value);

结果是:

closingvalue  2925.0
closingvalue  2.9879999E7
closingvalue  2809.0
closingvalue  2.7219999E7
closingvalue  2.5969999E7
closingvalue  2491.0
closingvalue  2635.0
closingvalue  2591.0

输入文件是这样的:

Date;Open;High;Low;Close;Log Return
2/1/2009;31.190.001;31.639.999;30.469.999;31.35;-
5/1/2009;30.73;30.77;29.08;29.25;-0.0693
6/1/2009;29.790.001;30.42;29.51;29.879.999;0.0213
7/1/2009;29.15;29.40;28.00;28.09;-0.0618
8/1/2009;27.90;27.950.001;26.860.001;27.219.999;-0.0315

我想将它们全部解析为 double 就像 28.09 甚至数百万。任何帮助表示赞赏。谢谢!

【问题讨论】:

文件是否包含 1000-999999 范围内的数字? (例如,看起来像 1.000-999.999 的数字)你如何区分它们和双精度数? 它代表 20.000 这样的数千,120.000.000 这样的百万和 30.42 或 -0.0315 这样的十进制数 那么你怎么知道“20.000”的意思是“20000”而不是“20,精确到小数点后3位”? 所以你想使用NumberFormat而不是使用默认格式来确定大值的格式? 26.000.000 或 20.68 都应该是股票的收盘价。我将如何确定特定格式? 【参考方案1】:

假设以下是有效格式

contains decimals
0.<any number> 
-0.<any number>
1.234.567.89 (last third digit is ".")

all others are integers. 

那么您所要做的就是将 3 位小数条件更改为“,”。这会将您的号码更改为

0,<any number>
-0,<any number>
1.234.567,89 (last third digit is now ",") 

并使用 Locale.GERMANY 进行解析

NumberFormat nf = NumberFormat.getInstance(Locale.GERMANY);
Double parsedNumber = nf.parse(value[4]).doubleValue();

编辑:这就是我要转换小数的方法。

String testString = value[4];
if(testString.size() >= 3)  //must be at least 3 digits
    int last3rdPosition = testString.size() - 3; 

    if(testString.charAt(last3rdPosition) == '.')

         //check if the last third char is "."
         //handle cases like 31.35 (change it to 31,35)
         testString.setChar(last3rdPosition, ',');
     else if (testString.charAt(0) == '0' 
               && testString.charAt(1) == '.')

         //handle cases like 0.0213 (change it to 0,0213)
         testString.setChar(1, ',')
    else if (testString.charAt(0) == '-' 
               && testString.charAt(1) == '0'
               && testString.charAt(2) == '.')

         //handle cases like -0.0315 (change it to -0,0315)
         testString.setChar(2, ',')
     

  
// do converting as per normal using Locale.GERMANY
// Locale.GERMANY will treat "." as the thousands separator
//                       and "," as the decimal separator
NumberFormat nf = NumberFormat.getInstance(Locale.GERMANY);
Double parsedNumber = nf.parse(testString).doubleValue(); 

【讨论】:

我得到的结果是这样的: 关闭值 2925.0 关闭值 2.9879999E7 关闭值 2809.0 关闭值 2.7219999E7 关闭值 2.5969999E7 关闭值 2491.0 关闭值 2635.0 我相信例如 2491.0 格式是错误的,因为它应该是 24.91跨度> @flower,您需要先将字符串 29.25 转换为 29,25 ... 检查最后第三位数字是否为“。”如果是这样,将其更改为“,” - 直接用逗号尝试 nf.parse("29,25")? 我正在尝试使用split("."),以便我只能将上述内容用于具有两个以上“。”的数字。但它根本不分裂,它的长度为零。 for (String[] entry : data) String[] entryparsed = entry[4].split("."); for(int i=0; i&lt;entryparsed.length; i++) System.out.println(entryparsed[i]); System.out.println(entryparsed.length); @flower,看看编辑,看看是否符合你的要求。基本上我会检查奇怪的情况,并将它们转换为 Locale.GERMANY 的格式【参考方案2】:

您的值不是双精度数,而是整数(数百万或十亿)实际上是因为 java 不理解带点的大数字。顺便说一句,我推荐你 BigIntegerBigDecimal 来处理大数字。

【讨论】:

【参考方案3】:

使用DecimalFormat 格式化文本,如下所示。

DecimalFormat decimal = new DecimalFormat("#0.00");
System.out.println(decimal.format(487384.321313112));

【讨论】:

我试过这个坚果我得到一个 java.lang.IllegalArgumentException: Cannot format given Object as a Number DecimalFormat decimal = new DecimalFormat("#0.00"); String value = decimal.format(entry[4]); System.out.println("closingvalue "+value); @flower 格式不接受“字符串”作为输入。它只接受原语及其对象变体,如 Long、Double、BigDecimal、BigInteger、AtomicInteger 等...根据您的问题,首先您需要解析输入。

以上是关于解析双数和数百万的主要内容,如果未能解决你的问题,请参考以下文章

在 R 中估计具有数百万个观测值和数千个变量的 OLS 模型

1月末中国域名商解析量13强:西数破百万指日可待

ArrayUtil-将集合按指定个数分为多个集合

全方位解析Java学习路线图,从入坑到年薪百万

从草根到百万年薪程序员的十年风雨之路,实战解析

春节保卫战:腾讯百万 QPS 线上环境云压测方案解析