gpt4 book ai didi

java - BigDecimal 具有 NextBigDecimal 行为

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:07:19 26 4
gpt4 key购买 nike

下面的代码完全符合预期:

import java.math.BigDecimal;
import java.util.Scanner;

public class Test2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
BigDecimal number = new BigDecimal("0");
System.out.print("Enter a number: ");
try {
number = new BigDecimal(input.next());
}
catch(Exception e) {
System.out.println("Not a number.");
}
System.out.println(number);
}
}
  • 正确:如果我输入一个字符串,它会失败。
  • 正确:如果我键入 1,1,它会失败。
  • 正确:如果我输入 1,它会成功。
  • 正确:输入1.1就成功了

如果我删除 try catch block 并将其替换为 while 循环,如下所示,它不会执行预期的操作:

import java.math.BigDecimal;
import java.util.Scanner;

public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter a number: ");
while (!input.hasNextBigDecimal()) {
System.out.print("Not a number, try again: ");
input.next();
}
BigDecimal number = input.nextBigDecimal();
System.out.println(number);
}
}
  • 正确:如果我键入一个字符串,它会失败。
  • 不正确:如果我键入 1.1,它会失败。
  • 正确:如果我输入 1,它会成功。
  • 不正确:如果我输入 1,1 就会成功

这是我运行时的输出:java Test

C:\>java Test
Enter a number: 1,1
1.1

为什么它会接受一个逗号,却打印一个句点?

如果我运行以下代码,它会打印出:en_ZA

import java.util.Locale;

public class Test3 {
public static void main(String[] args) {
System.out.println(Locale.getDefault());
}
}

正如您在以下链接中看到的,我的语言环境的小数点分隔符是句点:

http://www.localeplanet.com/java/en-ZA/index.html

请指出我哪里出错了。

编辑:

经过进一步调查,我发现了以下内容: https://www.sadev.co.za/content/how-correctly-format-currency-south-africa

所以语言环境在技术上确实使用了逗号。脑洞大开:)

最佳答案

Scanner.hasNextBigDecimal() 使用默认区域设置的分组和小数点分隔符(在您的区域设置中,'.' 用于分组,',' 用于小数)来验证下一个标记是否匹配 decimalpattern :

...
DecimalFormat df =
(DecimalFormat)NumberFormat.getNumberInstance(locale);
DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);

// These must be literalized to avoid collision with regex
// metacharacters such as dot or parenthesis
groupSeparator = "\\" + dfs.getGroupingSeparator();
decimalSeparator = "\\" + dfs.getDecimalSeparator();
...

这段代码来自 Scanner 类,在初始化您的 scanner 实例时执行。然后在调用 Scanner.hasNextBigDecimal() 时使用 groupSeparatordecimalSeparator 来检查下一个标记是否与十进制格式匹配。


new BigDecimal(String) 直接使用'.'作为小数点分隔符。


因此,如果您想使用 Scanner.hasNextBigDecimal() 和“.”作为用户输入的小数点分隔符,那么您应该使用 ScanneruseLocale(Locale) 方法。您的代码应如下所示:

Scanner input = new Scanner(System.in);
input.useLocale(Locale.ENGLISH);
System.out.print("Enter a number: ");
while (!input.hasNextBigDecimal()) {
System.out.print("Not a number, try again: ");
input.next();
}
BigDecimal number = input.nextBigDecimal();
System.out.println(number);

the program accepts a comma as valid input, but then prints a period as the decimal point.

再次在 ScannernextBigDecimal() 方法中将所有 groupSeparator 替换为 ""decimalSeparator"." 在调用 'new BigDecimal(String)' 之前。 Scanner 类的一段代码是:

private String processFloatToken(String token) {
String result = token.replaceAll(groupSeparator, "");
if (!decimalSeparator.equals("\\."))
result = result.replaceAll(decimalSeparator, ".");

这就是它接受 , 并打印 . 的原因。

关于java - BigDecimal 具有 NextBigDecimal 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53039685/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com