首页 > 解决方案 > 使用 R 中的 MASS::fractions 将浮点数转换为分数时出现奇怪的结果

问题描述

我正在尝试做一些类似于这篇文章中讨论的事情,但在 R 而不是 Python 中。

然而:

require(MASS)
fractions(0.723618,max.denominator = 1000000)
#[1] 89/123

这似乎表明浮点数 0.723618 用分数 89/123 比用 361809/500000 更好地描述,这对我来说似乎不正确。

更令人费解的是:

fractions(0.7236,max.denominator = 100000000000)
#[1] 89/123

当然,将 0.7236 写成 1809/5000 会更好,不是吗?

你知道为什么会这样吗?你觉得“正常”吗?

对于上下文:我问是因为这会在尝试为浮点数向量找到公分母 <= 1000000 时导致问题,人们可能希望使用该公分母将它们转换为具有指定最小有效位数的整数向量位数。
这些奇怪的分母的出现,使得分母向量的 LCM 非常大。


编辑:Jon Spring 建议的后续行动

for (i in 1:18) (print(fractions(0.723618,cycles=i)))
#[1] 1
#[1] 2/3
#[1] 3/4
#[1] 5/7
#[1] 8/11
#[1] 13/18
#[1] 21/29
#[1] 34/47
#[1] 55/76
#[1] 89/123
#[1] 144/199
#[1] 40121/55445
#[1] 40265/55644
#[1] 80386/111089
#[1] 281423/388911
#[1] 361809/5e+05
#[1] 361809/5e+05
#[1] 361809/5e+05

然而:

fractions(0.3333,cycles=1)
#[1] 1/3
fractions(0.3333,cycles=10)
#[1] 1/3
fractions(0.3333,cycles=100)
#[1] 1/3
fractions(0.3333,cycles=100,max.denominator = 1000)
#[1] 1/3
fractions(0.3333,cycles=100,max.denominator = 10000)
#[1] 3333/10000

所以看起来确实,这两个参数max.denominatorcycles以某种方式决定了分母可以变得多大,但乍一看,这种关系看起来并不是很简单。

标签: rmathprimes

解决方案


这是一种只考虑 max.denominator 并cycles通过将其分配给一个大数字而忽略它的方法:

library(purrr)

max.denominator = 1000000
decimal_num <- 0.723618
max_cycles <- 1000
do_not_know_cycles <- map(1:max_cycles,
                            function(x) {
                              try <- fractions(decimal_num,cycles = x,
                                               max.denominator = max.denominator)
                              nom_denom <- strsplit(attr(try,"fracs"),"/")
                              int_denom <- nom_denom[[1]][2]
                              list_return <- list(try,int_denom)
                              }) 
binded_ <- do_not_know_cycles %>% 
  do.call(rbind,.)

cc <- max.denominator - as.numeric(binded_[,2])
indx <- which.min(cc[cc>=0])
out <- do_not_know_cycles[[indx]][1]
out

如前所述,您只需要放max_cycles足够大并指定max.denominator哪个将为给定小数带来最大分母分数。

以下是最大分母的输出0.723618:1000000,100000,100

> out
[[1]]
[1] 361809/5e+05

> out
[[1]]
[1] 40265/55644

> out
[[1]]
[1] 55/76

推荐阅读