2024 Clojure 状态调查!中分享您的观点。

欢迎!请参阅关于页面以获取更多关于此如何工作的信息。

+1
文档
重新标记

说明说:

返回 num 的有理值

但是 (rationalize 1.6) 的结果为 8/5,而不是预期的 3602879701896397/2251799813685248。未说明执行了哪种舍入方式。

2 个回答

0

选中
0
by

你为什么期望3602879701896397/2251799813685248呢?

by
因为它表示的数字是`1.6`的文本形式,而文档中没有提到四舍五入。我已经检查了Common Lisp现在
```
(print (rationalize 1.6d0))
(print (rational 1.6d0))
```
```
8/5
3602879701896397/2251799813685248
```
所以`rationalize`也是一样的,而精确转换称为`rational`,但是如果在遇到这个问题之前我只知道Clojure中只有一个近似转换函数且其行为未在文档中记录,我该如何知道这一点呢?
by
`rationalize`是通过找到缩放输入和10的幂的GCD,并用该GCD来表示分子和分母,因此这总是简化后的分数(所以这里基于gcd 2简化16/10)。但是我不明白这为什么是不精确的或者为什么你会期望这个结果。我不认为有任何四舍五入发生,所以没有提到。
by
编辑 by
四舍五入是转换为十进制时的副作用,因为双精度字面值`1.6`在二进制中代表一个有限小数,但在十进制中~~无限大~~(抱歉,不可能;正在调查中)。因此,`rationalize`会找到一个分数,该分数在四舍五入到双精度后与相同的数字匹配,这在某些情况下可能很有用,但它并不明显,我只希望它作为精确转换的补充实现,而不是替代。与其他语言进行比较
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`
by
BigDecimal.valueOf
> 使用double提供的Double.toString(double)方法提供的规范字符串表示形式将double转换为BigDecimal。
Double.toString
> m或a的小数部分必须打印多少位数字?必须至少有一位数来表示小数部分,并且在此之外,需要这么多位,但不能超过需要这么多位,以便唯一地区分类型double的相邻值。也就是说,假设x是该方法为有限非零参数d生成的十进制表示所表示的确切数学值。那么d必须是x最近的double值;如果两个double值与x同样接近,那么d必须是其中之一,而d的有效数字的平均值的最低有效位必须是0。

`rationalize`的实现使用`BigDecimal.valueOf`,它执行四舍五入。精确转换将是`new BigDecimal(double)`构造函数。
by
谢谢!我现在明白了。
...