r-statistics-fanの日記

統計好きの現場の臨床医の覚書のようなもの

多倍長出力をキレイに桁を揃えて出力する(改良版

多倍長精度計算結果を見やすく出力 - 裏 RjpWiki
さんの所で、多倍長出力をキレイに出力する
記事があった。

自分の前の記事だと
小数点以下が出力されて、無駄に長くなってダメダメですね。
反省です。

今回もコードを勉強させていただいた。
ありがとうございます。

その過程で正規表現が、段々と分かってきたのが嬉しい。
なるほど文字列というのは、こう操作するんですね。
白状すると"\\..+"とか、さっきまで暗号以外の何物
でもなかったです。
勉強を兼ねて、小数部分にも対応できるように改変した。

ただ、現状小数の一番下の桁はそのままの出力。
四捨五入にしたい場合は、欲しい桁+1桁を表示して
脳内で四捨五入して欲しい。

#2014.9.23追記 指数表示にも対応

library(Rmpfr)

one <- mpfr(1,200000)

fact.x <- Reduce("*", c(one, rep(7,1000))) / 8 

print.mpfr <- function(mpfr, n = 100, m = 10, deci = 10, fill = "¥x09") {
      num <- strsplit(formatMpfr(mpfr), "\\.")
      int <- num[[1]][1]
      dec <- substr(num[[1]][2], 1, deci)
      blk <- n-nchar(int) %% n
      if (nchar(int) %% n == 0) blk <- 0
      #整数部分
      int <- c(rep(fill, blk), unlist(strsplit(int, "")))
      int <- matrix(int, m)
      int <- matrix(apply(int, 2, paste, collapse = ""), n %/% m)
      int <- apply(int, 2, paste, collapse = " ")
      int <- gsub("  +", "", int)
      int[[length(int)]] <- paste(int[[length(int)]], ".", sep = "", collapse = NULL)
      #小数部分
      blk2 <- n - nchar(dec) %% n
      if (nchar(dec) %% n == 0) blk2 <- 0
      dec <- c(unlist(strsplit(dec, "")), rep(fill, blk2))
      dec <- matrix(dec, m)
      dec <- matrix(apply(dec, 2, paste, collapse = ""), n %/% m)
      dec <- apply(dec, 2, paste, collapse = " ")
      dec <- gsub("  +", "", dec)
      #指数部分
      num2 <- strsplit(formatMpfr(mpfr), "e")
      e <- num2[[1]][2]
      invisible(sapply(int, cat, "\n"))
      invisible(sapply(dec, cat, "\n"))
      if(!is.na(e)) cat("e", e)
}

print.mpfr(fact.x, n=50, m=10, deci=200, fill = "_") #揃えるためにfillで埋める

_____15665 7079995714 7897634443 5404784177 5770623134 
3851232714 3293687594 0121324539 6726455405 6104881793 
9400953998 2698994394 9259585728 6236834078 7784522385 
4783856822 4787518889 0583265049 8078044866 2290714519 
6475183801 2038208512 1884516592 0787790336 1906317673 
2408948032 6108556176 0302096077 2135236990 3586700499 
0288890710 4649018808 3614459229 4073767155 1943137732 
3199556874 0946936655 9238915685 6679731224 7350760618 
8857342752 5147954528 9465927513 6943478735 9894126103 
6213980568 8125288107 0480164874 3391517780 4934167749 
0741259195 2811617177 4317062576 8628776314 0990039303 
8002046069 5969364204 2185165226 4187098033 8451142966 
8130674917 1685764076 4600699116 9425374102 8990613987 
9500337951 4035397616 9840969018 1468300164 7284332137 
5920401955 7585478159 2450144551 8285556929 5789308700 
6331270101 5777267908 8283327439 6587722525 0358306279 
7788539824 1007671413 7876036605 0889265096 6410075000. 
1250000000 0000000000 0000000000 0000000000 0000000000 
0000000000 0000000000 0000000000 0000000000 0000000000 
0000000000 0000000000 0000000000 0000000000 0000000000 
0000000000 0000000000 0000000000 0000000000 0000000000