【问题标题】:Streamtokenizer to read very large numbers?Streamtokenizer 读取非常大的数字?
【发布时间】:2013-10-13 10:12:39
【问题描述】:

我必须在 Java 中输入一个包含大量 10^9 阶的输入。如何快速处理输入?此外,由于 streamtokenizer.nval 给出了双倍,我怎样才能读取更大的值?

【问题讨论】:

  • 你可以试试BigDecimal
  • 这无助于接受输入。从 double 转换为 BigInteger 时也不行。
  • 1.您可以将输入作为String 传递给BigDecimal 构造函数; 2. 从double 转换为BigInteger 没有意义,因为它用于整数 并且因为double 无法表示这么大的值,所以你会转换错误的值。
  • @BackSlash BigInteger 不是必需的——即使是 32 位 int 也可以处理 10^9 阶数。

标签: java input iostream largenumber


【解决方案1】:

在解析之前,重置分词器语法表并初始化它以将数字识别为单词:

StreamTokenizer tokenizer = new StreamTokenizer(r);
tokenizer.resetSyntax();

tokenizer.whitespaceChars(0, 32);

tokenizer.wordChars('0', '9');
tokenizer.wordChars('-', '.');
tokenizer.wordChars('+', '+');
tokenizer.wordChars('a', 'z');
tokenizer.wordChars('A', 'Z');
tokenizer.wordChars(0xa0, 0xff); // not really needed here. */
tokenizer.slashSlashComments(true);
tokenizer.slashStarComments(true);

tokenizer.quoteChar('"');
tokenizer.quoteChar('\'');

然后,当遇到一个单词时,检查它是否可以解析为数字(这里有点粗略,但它显示了大致的想法):

...
case StreamTokenizer.TT_WORD:
  if ("true".equals(tokenizer.sval)) {
    result = Boolean.TRUE;
  } else if ("false".equals(tokenizer.sval)) {
    result = Boolean.FALSE;
  } else if ("null".equals(tokenizer.sval)) {
    result = null;
  } else {
    try {
      result = Long.parseLong(tokenizer.sval);
    } catch(NumberFormatException e) {
      try {
        result = Double.parseDouble(tokenizer.sval);
      } catch (NumberFormatException e2) {
        throw new IllegalStateException(
           "Unexpected token: " + tokenizer.toString());
      }
   }
 }
 tokenizer.nextToken();
 break;

这是否有效取决于用例:如果您想解析表达式(而不仅仅是像我这样的 JSON),您可能不想将 +- 设置为单词字符,但是一般的想法应该仍然可以通过将它们视为一元运算符并在稍后阶段检测常量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-17
    • 2017-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    相关资源
    最近更新 更多