بشكل دوري ، هناك مشاكل ، حتى في الحياة اليومية ، عندما تكون دقة البت float64
/ int64
غير كافية للحصول على إجابة بالدقة المطلوبة. التسرع في البحث عن صك آخر؟ أيضا خيار.
أو لا يمكنك القيام بذلك ، ولكن أظهر الفضول واكتشف أنه للحساب بدقة تعسفية ، تم إنشاء مكتبة GNU MPFR منذ فترة طويلة والتي توجد بها أغلفة لجميع اللغات تقريبًا. تبين الممارسة أن القليل من الناس على دراية بهذه المكتبة ، والتي ربما تكون ناجمة عن خصوصية برامج الدراسة في الجامعات وما بعدها من التيار السائد للمبرمج.
المكتبة جيدة وتستحق الاهتمام بها ، على الأقل في إطار توسيع آفاقها. على R هناك غلاف Rmpfr . فيما يلي سأعطي مثالًا بسيطًا على المشكلات التي تواجه أطفال المدارس (حسنًا ، لا تلمس بيانات التصميم بموجب قانون عدم الإفشاء) وسوف أتطرق إلى عدد من المكابس الكلاسيكية ، التي تتم مهاجمتها على الفور تقريبًا.
إنه استمرار للمنشورات السابقة .
على سبيل المثال ، خذ المشكلة رقم 39 من مسابقة العام الدراسي 2019/2020 في الكم:
الأعداد الموجبة x و y بحيث تكون في عدم المساواة أسفل الكسر الأيسر أكبر من اليمين. أيهما أكبر: س أم ص؟
![كسور السلسلة](https://habrastorage.org/getpro/habr/post_images/01a/a93/0ef/01aa930ef7e20535af3e0e203f9319b0.png)
بطبيعة الحال ، يجب حلها بشكل تحليلي (عدم المساواة بالتناوب) ، ولكن هذا ليس سببًا لعدم استخدامها كدليل.
نرسم رمزًا بسيطًا لحساب تسلسل الكسور. يمكنك على الفور تعيين القيمة النهائية ، ولكن بعد ذلك demoscene mpfr
، لذلك نتحرك بخطوات صغيرة.
نحل بالطرق القياسيةlibrary(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)
وهنا سوء الحظ ، بالفعل في التكرار الرابع عشر (رقم التوقف = 29) ، الدقة ليست كافية بالنسبة لنا للتمييز بين الكسور. وعليك التفكير حتى عام 2019!
![الفشل 1](https://habrastorage.org/webt/85/vn/ub/85vnubko1bre2fuizrdh35nozpm.png)
? , 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
. .
![الفشل 2](https://habrastorage.org/webt/qx/je/ss/qxjesssej4stppytchqetqgfsqu.png)
№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 ?».