Periodicamente, existem problemas, mesmo na vida cotidiana, quando a precisão dos bits float64
/ int64
não é suficiente para obter uma resposta com a precisão necessária. Correndo em busca de outro instrumento? Também é uma opção.
Ou você não pode fazer isso, mas fique curioso e descubra que, para calcular com precisão arbitrária, a biblioteca GNU MPFR foi criada há muito tempo para a qual existem wrappers para quase todos os idiomas. A prática mostra que poucas pessoas estão familiarizadas com esta biblioteca, o que provavelmente é causado pelas peculiaridades dos programas de estudo nas universidades e pelo subsequente mainstream do programador.
A biblioteca é boa e merece atenção, pelo menos no âmbito de ampliar seus horizontes. Em R, há um wrapper Rmpfr . Abaixo, darei um exemplo simples de problemas para crianças em idade escolar (bem, não toque nos dados do projeto sob a NDA) e abordarei vários rakes clássicos que são atacados quase imediatamente.
É uma continuação de publicações anteriores .
Por exemplo, considere o problema nº 39 da competição do ano letivo de 2019/2020 no Quantum: Os
números positivos x e y são tais que na desigualdade abaixo da fração esquerda é maior que a direita. Qual é maior: x ou y?

Naturalmente, ele deve ser resolvido analiticamente (alternando a desigualdade), mas esse não é um motivo para não usá-lo como demonstração.
Desenhamos um código simples para calcular a sequência de frações. Você pode definir imediatamente o valor final, mas depois o demoscene para mpfr
, então avançamos em pequenas etapas.
Resolvemos por métodos padrãolibrary(tidyverse)
library(magrittr)
options(digits=15)
frec <- function(stopval, n, x){
res <- ifelse(n == stopval,
(stopval - 1) + stopval/(stopval + 1 + x),
(n - 1 ) + n / (frec(stopval, n + 2, x))
)
res
}
frec_wrap <- function(stopval, x){
res <- frec(stopval = stopval, n = 1, x = x)
print(glue::glue("{stopval}: {res}"))
res
}
sol_df <- tibble(stopval = seq(1, 29, by = 2)) %>%
mutate(val1 = purrr::map_dbl(stopval, frec_wrap, x = 1),
val2 = purrr::map_dbl(stopval, frec_wrap, x = 5),
delta = val1 - val2)
E aqui está uma má sorte, já na 14ª iteração (número de parada = 29), a precisão não é suficiente para distinguirmos entre frações. E você deve considerar até 2019!

? , Rmfpr
. — float64
mpfr
.
library(tidyverse)
library(magrittr)
library(Rmpfr)
frec2 <- function(stopval, n, x){
if(n == stopval){
(stopval - 1) + stopval/(stopval + 1 + x)} else {
(n - 1 ) + n / (frec2(stopval, n + 2, x))
}
}
frec2_wrap <- function(stopval, x){
.precision <- 5000
res <- frec2(stopval = mpfr(stopval, .precision),
n = mpfr(1, .precision),
x = mpfr(x, .precision)
)
print(glue::glue("{stopval}: {formatMpfr(res, drop0trailing = TRUE)}"))
res
}
sol2_df <- tibble(stopval = seq(1, 29, by = 2)) %>%
mutate(val1 = purrr::map(stopval, frec2_wrap, x = 1),
val2 = purrr::map(stopval, frec2_wrap, x = 5))
. , tibble
. .

№1:
tibble
, vctrs
. ( mpfr
S4 ) list-column. - .
, vctrs
. , :
for(jj in 1:12){
flags_df[[glue("bp_2_{jj}_T")]] <- flags_df[[glue("bp_2_{jj}_in")]] & flags_df[[glue("flag_2_{jj}")]]
flags_df[[glue("bp_2_{jj}_F")]] <- flags_df[[glue("bp_2_{jj}_in")]] & ! flags_df[[glue("flag_2_{jj}")]]
}
№2:
list-column . mpfr
list-column.
№3
rpfm
. StackOverflow . . R?
? --! R, Python! !
. RTFM, .
- №1. —
tibble
. data.frame
. - №2.
rpfm
. , . data.frame
. - №3.
formatMpfr
.
.
library(tidyverse)
library(magrittr)
library(Rmpfr)
frec2 <- function(stopval, n, x){
if(n == stopval){
(stopval - 1) + stopval/(stopval + 1 + x)} else {
(n - 1 ) + n / (frec2(stopval, n + 2, x))
}
}
frec2_wrap <- function(stopval, x){
.precision <- 5000
res <- frec2(stopval = mpfr(stopval, .precision),
n = mpfr(1, .precision),
x = mpfr(x, .precision)
)
print(glue::glue("{stopval}: {formatMpfr(res, drop0trailing = TRUE)}"))
res
}
sol_df <- data.frame(stopval = seq(111, 119, by = 2)) %>%
mutate(val1 = new("mpfr", unlist(purrr::map(stopval, frec2_wrap, x = 1))),
val2 = new("mpfr", unlist(purrr::map(stopval, frec2_wrap, x = 5))),
delta = val1 - val2)
sol_txt_df <- sol_df %$%
tibble(stopval = stopval,
val1_txt = formatMpfr(val1, drop0trailing = TRUE),
val2_txt = formatMpfr(val2, drop0trailing = TRUE),
delta_txt = formatMpfr(delta, drop0trailing = TRUE))
P.S. . , . , , GNU MPFR.
— « R ?».