0

我目前正在用java编写一个计算器程序。这是我的第一个java程序,我习惯了c++。

我注意到 java 中的双精度与 c++ 中的双精度完全不同。在 java 和 c++
4.1*3
that/.1中试试这个

它应该是
12.3,然后是 123,c++ 给出了这个结果,但是 java 给出了
12.299999999999999 和 122.99999999999999

我怎样才能像在 c++ 中使用双打一样进行数学运算,我知道在程序中使用 12.299999999999999 与 12.3 相比没有任何区别,但是当用户阅读数字时,这非常难看。我已经研究过 BigDecimal 类,但我不能用那个类做三角函数和对数等等

4

6 回答 6

8

数学是一样的;显示是不同的,因为大多数 C/C++ 显示格式会舍入数字以避免最低有效位的不精确。

于 2011-03-21T22:43:21.720 回答
7

那么,为什么这是不精确的呢?:4.1已经不能精确地表示为二进制数(无论是定点数还是浮点数),所以它被四舍五入到下一个double值。将其乘以 3 不会改变不可表示性的事实,但会放大错误,因此它现在是与从十进制转换12.3得到的不同的二进制值。因此,当您再次将其转换为十进制时,您会得到带有很多 9 的数字。

将其乘以 10 时,只需将误差再次放大 10。(再次除以 0.1 会引入更多误差,因为0.1也不能完全表示。)

您的 C++ 程序可能使用了完全相同的操作。Java 中显示不同的原因是它显示了从字符串中再现数字所需的所有数字,而您的 C++ 输出函数以某种方式对其进行了舍入。(由于您没有显示输出代码,我们无法确定您在那里做了什么。)

当输出数字供人类用户消化时,使用NumberFormat(在 java.text 中)或Formatter(在 java.util 中)。

于 2011-03-21T23:09:42.313 回答
4

我注意到 java 中的双精度与 c++ 中的双精度完全不同。

事实上,Java 将使用与 C++ 完全相同的双精度表示,并且算法将(很可能)在内部产生完全相同的值。

这里的基本问题是二进制浮点数表示和十进制表示之间没有精确的一对一映射。诸如此类的数字12.3不能精确地表示为二进制浮点数。这是数学上的不可能。

要理解这一点(并且您应该),请阅读“每个计算机科学家应该了解的关于浮点运算的知识”

您观察到的差异将是由于将双精度值转换为数字以进行输出的格式代码的差异。在 Java 案例中,代码给出了它可以实现的实际双精度的最准确的十进制表示。在 C++ 的情况下,它会舍入最低有效数字......这给出了您期望的数字,但不是最准确的十进制表示。

这两种方法都没有错。他们只是不同。如果您希望 Java 显示四舍五入到特定位数的数字,您可以使用 Java 格式化程序类之一来实现。

另一种选择是使用BigDecimal该类在 Java 中执行所有计算器算术运算。这将为您提供精确的数字,以您在高中学习的十进制算术的限制为模;例如,您不能用十进制精确表示像 1/3 这样的分数。缺点是BigDecimal算术比浮点数慢很多数量级,而且 API 使用起来更麻烦。

于 2011-03-22T00:05:19.660 回答
1

Every arithmetic model represents a trade-off between precision, space and speed.

Floating point, regardless of the language sacrifices some of the precision to save space and add speed.

Fixed point is a different trade-off and arbitrary precision arithmetics is yet another one.

If you want complicated calculations of arbitrary precision, you'll need a dedicated maths library like Apache commons-math or apfloat.

于 2011-03-21T22:52:48.450 回答
1

The Dude, Java Doubles 不擅长数学,它们很慢,但与 Java 的 double(小的)(或任何其他 64 位 IEEE 754)一样精确。BigDecimal 甚至更慢。

(所以不知道如果Dude遵守)

于 2011-03-21T22:43:35.967 回答
0

你看过了java.lang.StrictMath吗?从 javadocs 我得到的印象是它可能更接近 C,但我没有做太多的数学运算,也不能确定。

否则我同意 geekosaur:输出可能是唯一的问题,java.text.NumberFormat在这里可能会有所帮助。

于 2011-03-21T22:50:21.467 回答