R:数字精度,如何防止舍入?

时间:2018-07-24 03:25:27

标签: r numbers precision

在R中,我具有以下数字向量:

numbers <- c(0.0193738397702257, 0.0206218006695066, 0.021931558829559, 
             0.023301378178208, 0.024728095594751, 0.0262069239112787, 0.0277310799996657, 
             0.0292913948762414, 0.0308758879014822, 0.0324693108459748, 0.0340526658271053, 
             0.03560271425176, 0.0370915716288017, 0.0384863653635563, 0.0397490272396821, 
             0.0408363289939899, 0.0417002577578561, 0.0422890917131629, 0.0425479537267193, 
             0.0424213884467212, 0.0418571402964338, 0.0408094991140723, 0.039243951482081, 
             0.0371450856007627, 0.0345208537496488, 0.0314091884865658, 0.0278854381969885, 
             0.0240607638577763, 0.0200808932436969, 0.0161193801903312, 0.0123615428382314, 
             0.00920410652651576, 0.00628125319205829, 0.0038816517651031, 
             0.00214210795679701, 0.00103919307280354, 0.000435532895812429, 
             0.000154730641092234, 4.56593150728962e-05, 1.09540661898799e-05, 
             2.08952167815574e-06, 3.10045314287095e-07, 3.51923218134997e-08, 
             3.02121734299694e-09, 1.95269500257237e-10, 9.54697530552714e-12, 
             3.5914029230041e-13, 1.07379981978647e-14, 2.68543048763588e-16, 
             6.03891613157815e-18, 1.33875697089866e-19, 3.73885699170518e-21, 
             1.30142752487978e-22, 5.58607581840324e-24, 2.92551478380617e-25, 
             1.85002124085815e-26, 1.39826890505611e-27, 1.25058972437096e-28, 
             1.31082961467944e-29, 1.59522437605631e-30, 2.23371981458205e-31, 
             3.5678974253211e-32, 6.44735482309705e-33, 1.30771083084868e-33, 
             2.95492180915218e-34, 7.3857554006177e-35, 2.02831084124162e-35, 
             6.08139499028838e-36, 1.97878175996974e-36, 6.94814886769478e-37, 
             2.61888070029751e-37, 1.05433608968287e-37, 4.51270543356897e-38, 
             2.04454840598946e-38, 9.76544451781597e-39, 4.90105271869773e-39, 
             2.5743371658684e-39, 1.41165292292001e-39, 8.06250933233367e-40, 
             4.78746160076622e-40, 2.94835809615626e-40, 1.87667170875529e-40, 
             1.22833908072915e-40, 8.21091993733535e-41, 5.53869254991177e-41, 
             3.74485710867631e-41, 2.52485401054841e-41, 1.69027430542613e-41, 
             1.12176290106797e-41, 7.38294520887852e-42, 4.8381070000246e-42, 
             3.20123319815522e-42, 2.16493953538386e-42, 1.50891804884267e-42, 
             1.09057070511506e-42, 8.1903023226717e-43, 6.3480235351625e-43, 
             5.13533594742621e-43, 4.25591269645348e-43, 3.57422485839717e-43, 
             3.0293235331048e-43, 2.58514651313175e-43, 2.21952686649801e-43, 
             1.91634521841049e-43, 1.66319240529025e-43, 1.45043336371471e-43, 
             1.27052593975384e-43, 1.11752052211757e-43, 9.86689196888877e-44, 
             8.74248543892126e-44)

我使用cumsum来获取累计金额。由于R的数值精度,向量结尾处的许多数字现在都等于1(即使从技术上讲它们并不完全等于1,只是非常接近1)。

因此,当我尝试使用numbers恢复原始diff(cumulative)时,我得到了很多0,而不是很小的数字。如何防止R“四舍五入”?

cumulative <- cumsum(numbers)
diff(cumulative)

2 个答案:

答案 0 :(得分:3)

我认为Rmpfr软件包可以满足您的要求:

library(Rmpfr)
x <- mpfr(numbers,200) # set arbitrary precision that's greater than R default
cumulative <- cumsum(x)
diff(cumulative)

这是输出的顶部和底部:

> diff(cumulative)
109 'mpfr' numbers of precision  200   bits 
  [1]         0.02062180066950659862445860426305443979799747467041015625
  [2]        0.021931558829559001655429284483034280128777027130126953125
  [3]         0.02330137817820800150148130569505156017839908599853515625
  [4]       0.0247280955947510004688805196337852976284921169281005859375
  ...
[107] 1.117520522117570086014450710640040701536080790307716261438975e-43
[108] 9.866891968888769759087690539062888824928577731689952701181586e-44
[109] 8.742485438921260418707338389502002282130643811990663213422948e-44

您可以通过将第二个参数更改为mpfr来调整精度。

答案 1 :(得分:0)

您可能想试用软件包lookup : {A : Set}(xs : List A)(n : ℕ) → (isTrue (n < length xs)) → A lookup [] zero () lookup [] (suc _) () lookup (x :: xs) zero p = x lookup (x :: xs) (suc n) p = lookup xs n p