странные результаты при преобразовании чисел с плавающей запятой в дроби с использованием MASS :: дроби в R - PullRequest
2 голосов
/ 20 октября 2019

Я пытаюсь сделать что-то похожее на то, что обсуждается в этом посте , но в 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 для вектора чисел с плавающей запятой, который может потребоватьсяиспользовать для преобразования их в вектор целых чисел с указанным минимальным числом значащих цифр. <br>Появление этих странных знаменателей делает LCM вектора знаменателей очень большим.


EDIT : продолжение предложения Джона Спринга

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.denominator и cycles так или иначеопределить, насколько большим может стать знаменатель, но на первый взгляд отношения выглядят не очень простыми.

1 Ответ

0 голосов
/ 20 октября 2019

Это один из способов учета только 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
...