将字符串转换为双精度浮点数会移除末尾的零

4
我正在尝试将一组以字符串格式表示的双精度浮点数转换为双精度浮点数格式。我将它们放入列表中,并使用 Double.parseDouble(string) 方法进行转换。
这对于大多数数字有效,但当双精度浮点数包含一个尾随零时,parseDouble 方法会将其删除。 我不想删除它。
String[] values = {"124.50", "45.801", "-15.210"};
List<Double> nums = new ArrayList<Double>();

for(String s: values)
nums.add(Double.parseDouble(s));
Collections.sort(nums);

for(Double d: nums){
    System.out.print(d + " ");
}

这将产生输出:
-15.21 45.801 124.5

但我想要保留末尾的零。使用格式化行的问题在于,当打印值时,我必须指定所需的浮点精度,但我没有任何特定的愿望使数字准确到某个点,只是如果有零存在,就让它们保持原样。

我这样做的方式是否不正确?


5
在讨论实际双精度值时,并不存在所谓的“尾随零”。 - Brian Roach
有趣。我不想要一个固定的n位数字。我猜我得在转换之前检查字符串并手动添加零吗?那似乎非常冗余。 - leigero
1
@leigero - 明确一下,这与询问如何保留整数中的“前导零”是相同的(例如 01)... 您正在混淆数字的文本表示与实际二进制值。 - Brian Roach
1
谢谢 @BrianRoach,看来我得从完全不同的角度来处理这个任务了。你说的很有道理。 - leigero
1
一个完整的答案需要一些时间,但其要点是创建一个包含double值和尾随零数的包装类。话虽如此...根据原始字符串,您仍可能遇到精度问题。不过,如果取决于您正在做什么,仅持有对原始字符串的引用可能就足够了。(编辑:哈,看来有人已经发表了这个观点) - Brian Roach
显示剩余2条评论
4个回答

7
您可以存储原始字符串的引用并打印它,而不是解析后的双精度数。
public static void main(String[] args) {
    String[] values = {"124.50", "45.801", "-15.210"};
    List<MyDouble> nums = new ArrayList<MyDouble>();

    for(String s: values)
    nums.add(new MyDouble(s));
    Collections.sort(nums);

    for(MyDouble d: nums){
        System.out.print(d + " ");
    }
}

static class MyDouble implements Comparable<MyDouble> {
    final double val;
    final String string;
    MyDouble(String str) {
        string = str;
        val = Double.parseDouble(str);
    }

    @Override
    public String toString() {
        return string;
    }

    @Override
    public int compareTo(MyDouble o) {
        return (int) (val - o.val);
    }
}

结果:

-15.210 45.801 124.50

如果你的数组对许多其他类可见,而你不希望它们依赖于MyDouble,那么你可以将MyDouble作为java.lang.Number的子类,并指定一个Number数组。 - twj

2
您可以使用BigDecimal来处理这些值。 BigDecimal会保留尾随零。
String[] values = {"124.50", "45.801", "-15.210"};
List<BigDecimal> nums = new ArrayList<BigDecimal>();

for(String s: values)
    nums.add(new BigDecimal(s));
Collections.sort(nums);

for(BigDecimal d: nums) {
    System.out.print(d + " ");
}

0
如果你想要始终保留n位小数,可以执行以下操作:
final DecimalFormat df = new DecimalFormat("#.000");
for (Double d : nums) {
    System.out.print(df.format(d) + " ");
}

更具体地说,这个解决方案适用于您,但正如@BrianRoach在他的评论中提到的那样,在谈论实际双精度数字时,不存在尾随零这样的东西。
final String[] values = {"124.50", "45.801", "-15.210"};
final List<Double> nums = new ArrayList<>();
final List<Double> bkpNums = new ArrayList<>();

for (final String s : values) {
    double d = Double.parseDouble(s);
    nums.add(d);
    bkpNums.add(d);
}
Collections.sort(nums);

for (Double d : nums) {
    System.out.print(values[bkpNums.indexOf(d)] + " ");
}

1
这与OP的描述不符:“我没有任何特定的愿望使数字精确到某个点,如果有零存在,只需将其保留即可”。 - Keppil
@Keppil 第二个(完整的)解决方案实际上打印了“输入”的values数组中的值,并完美地符合要求。不确定是谁对我的解决方案进行了负面投票,但我真心希望他们在投票之前完全阅读我的解决方案。:( - javatarz

-1

尝试使用:

DecimalFormat df = new DecimalFormat("###.#");

打印数字时


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接