2024 年 Clojure 调查问卷! 分享您的想法。

欢迎!有关本站如何运作的更多信息,请参见 关于 页面。

+1 投票
文档
重新标记

它表示

返回 num 的有理值

(rationalize 1.6) 的结果为 8/5,而不是预期的 3602879701896397/2251799813685248。执行了哪种舍入操作未在文档中说明。

2 个答案

0 投票

选中
0 投票

为什么你期望 3602879701896397/2251799813685248?

因为它代表了实数 `1.6` 的数值,而文档中没有提到四舍五入。我已经检查了 Common Lisp
```
(print (rationalize 1.6d0))
(print (rational 1.6d0))
```
```
8/5
3602879701896397/2251799813685248
```
所以 `rationalize` 执行同样的操作,而精确转换时使用 `rational`,但在我遇到这个问题之前,我怎么能知道这一点,如果 Clojure 中唯一的转换函数是近似且其行为是未记录的呢?
`rationalize` 通过找到缩放输入和10的幂的最大公约数(GCD),并以这种方式表示分子和分母,所以这总是一个简化的分数(所以这里基于gcd 2简化16/10)。但我不明白这是如何近似的,或者你为什么期望这个结果。我认为没有进行任何四舍五入,这就是为什么它没有被提到的。

编辑了

Python
```
from fractions import Fraction
print(Fraction(1.6))
```
`3602879701896397/2251799813685248`
Ruby
`puts 1.6.to_r`
`3602879701896397/2251799813685248`
Racket
```
#lang racket
(println (inexact->exact 1.6))
```
`3602879701896397/2251799813685248`
BigDecimal.valueOf
> 将 double 转换为 BigDecimal,使用 double 的规范字符串表示形式,由 Double.toString(double) 方法提供。
Double.toString
> m 或 a 的分数部分必须打印多少位数字?分数部分必须至少有一位数字,之后可以有更多,但只可以有那么多,以唯一区分 double 类型的相邻值。也就是说,假设 x 是此方法为有限非零参数 d 产生的十进制表示所表示的确切数学值。那么 d 必须是最接近 x 的 double 值;如果两个 double 值与 x 同等接近,那么 d 必须是它们之一,并且 d 的尾数的最不签约必须为 0。

`rationalize` 的实现使用 `BigDecimal.valueOf`,它负责舍入。精确转换将是通过 `BigDecimal(double)` 构造函数实现的。
谢谢!我现在明白了。
...