strange results when converting floating point numbers to fractions using MASS::fractions in R

浪尽此生 提交于 2020-01-23 12:07:16

问题


I am trying to do something similar to what is discussed in this post, but in R rather than Python.

However:

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

This seems to indicate that floating point number 0.723618 is better described by fraction 89/123 than by 361809/500000, which does not seem correct to me.

Even more puzzling:

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

Surely it would be better to write 0.7236 as 1809/5000, wouldn't it?

Do you know why this happens? Do you think it's 'normal'?

For context: I'm asking because this causes issues when trying to find a common denominator <= 1000000 for a vector of floating point numbers, which one may want to use to convert them to a vector of integers with a specified minimal number of significant digits.
The appearance of these weird denominators makes the LCM of the vector of denominators very large.


EDIT : follow-up from Jon Spring's suggestion

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

However:

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

So it seems that indeed, the two parameters max.denominator and cycles somehow determine how large the denominator can become, but at first sight the relationship does not look very straightforward.


回答1:


This is one way of considering only max.denominator and disregarding cycles by assigning it to a big number:

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

As said, you need only to put max_cycles big enough and specify max.denominator which will bring the max-denominator fraction for a given decimal.

Here are the outputs of 0.723618 for max.denominators: 1000000,100000,100

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

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

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


来源:https://stackoverflow.com/questions/58474026/strange-results-when-converting-floating-point-numbers-to-fractions-using-mass

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!