为什么 java 和 lisp 中的这两个等价表达式有不同的结果?
Why do these two equivalent expressions in java and lisp have different outcomes?
lisp中的表达式是:
(* (+ a b) (- a (/ 1 b)))
Java 中的等效表达式(我认为)是:
(a + b) * (a - (1/b));
但是当我向两者输入相同的 a
和 b
float
值时,它们的计算结果不同。这是为什么?
如果您使用相同的浮点类型(两者都是单精度或双精度),那么您看到的可能是 打印 浮点数的不同行为。很可能数字实际上是相同的。默认的 CL 打印机(或应该)相当小心地打印足够的信息,以便可以读回浮点数并与它打印的相同。所以给出
(defun f (a b)
(* (+ a b) (- a (/ 1 b))))
然后我们可以用
测试读打印一致性
(defun tsrp (x)
(with-standard-io-syntax
(eql (read-from-string (write-to-string x))
x)))
现在在一个实现中(第一个示例使用单精度,第二个使用双精度,这是 CL 使用默认 reader 设置读取它们的方式):
> (f 1.001 1.0003)
0.0026016448
> (tsrp (f 1.001 1.0003))
t
> (f 1.001d0 1.0003d0)
0.002601509937018715D0
> (tsrp (f 1.001d0 1.0003d0))
t
另一个:
? (f 1.001 1.0003)
0.0026016447
? (tsrp (f 1.001 1.0003))
t
? (f 1.001d0 1.0003d0)
0.002601509937018715D0
? (tsrp (f 1.001d0 1.0003d0))
t
请注意,在单精度情况下,两种实现打印出不同的外观结果。但是可以确认这两个表示是同一个single-float:
> (= 0.0026016448 0.0026016447)
t
和
? (= 0.0026016448 0.0026016447)
t
我不知道如何让 Java 打印一个浮点数以便可以像这样读回它:我认为它可能是 %s
格式控件。如果那是对的,并且你确保你的浮点类型是相同的,那么你应该得到相同的表示,或者只在实际上无关紧要的数字上有所不同的表示(你可以检查,与上面的代码等效).
lisp中的表达式是:
(* (+ a b) (- a (/ 1 b)))
Java 中的等效表达式(我认为)是:
(a + b) * (a - (1/b));
但是当我向两者输入相同的 a
和 b
float
值时,它们的计算结果不同。这是为什么?
如果您使用相同的浮点类型(两者都是单精度或双精度),那么您看到的可能是 打印 浮点数的不同行为。很可能数字实际上是相同的。默认的 CL 打印机(或应该)相当小心地打印足够的信息,以便可以读回浮点数并与它打印的相同。所以给出
(defun f (a b)
(* (+ a b) (- a (/ 1 b))))
然后我们可以用
测试读打印一致性(defun tsrp (x)
(with-standard-io-syntax
(eql (read-from-string (write-to-string x))
x)))
现在在一个实现中(第一个示例使用单精度,第二个使用双精度,这是 CL 使用默认 reader 设置读取它们的方式):
> (f 1.001 1.0003)
0.0026016448
> (tsrp (f 1.001 1.0003))
t
> (f 1.001d0 1.0003d0)
0.002601509937018715D0
> (tsrp (f 1.001d0 1.0003d0))
t
另一个:
? (f 1.001 1.0003)
0.0026016447
? (tsrp (f 1.001 1.0003))
t
? (f 1.001d0 1.0003d0)
0.002601509937018715D0
? (tsrp (f 1.001d0 1.0003d0))
t
请注意,在单精度情况下,两种实现打印出不同的外观结果。但是可以确认这两个表示是同一个single-float:
> (= 0.0026016448 0.0026016447)
t
和
? (= 0.0026016448 0.0026016447)
t
我不知道如何让 Java 打印一个浮点数以便可以像这样读回它:我认为它可能是 %s
格式控件。如果那是对的,并且你确保你的浮点类型是相同的,那么你应该得到相同的表示,或者只在实际上无关紧要的数字上有所不同的表示(你可以检查,与上面的代码等效).