【问题标题】:How to convert a binary fraction number into decimal fraction number in R?如何将二进制小数转换为R中的十进制小数?
【发布时间】:2019-06-01 22:58:08
【问题描述】:

我需要在 R 中编写一个将二进制小数转换为十进制小数的函数。例如f(0.001) # 0.125

我做了什么:我在R包中搜索了相关函数:

DescTools::BinToDec(0.001) # NA
DescTools::BinToDec("0.001") # NA
base::strtoi(0.001, base=2) # NA
base::strtoi("0.001", base=2) # NA

base::packBits(intToBits(0.001), "integer") # 0
base::packBits(intToBits("0.001"), "integer") # 0

compositions::unbinary(0.001) # 0.001
compositions::unbinary("0.001") # NA

我在 SOF 中搜索,发现如下:

base2decimal <- function(base_number, base = 2) {
  split_base <- strsplit(as.character(base_number), split = "")
  return(sapply(split_base, function(x) sum(as.numeric(x) * base^(rev(seq_along(x) - 1)))))}
base2decimal(0.001) # NA
base2decimal("0.001") # NA

0.001 是:

(0 * 2^(-1)) + (0 * 2^(-2)) + (1 * 2^(-3)) # 0.125
(0 * 1/2) + (0 * (1/2)^2) + (1 * (1/2)^3) # 0.125
(0 * 0.5) + (0 * (0.5)^2) + (1 * 0.5^3) # 0.125

所以,像内积的总和(0,0,1) * (0.5^1, 0.5^2, 0.5^3) 似乎解决了这个问题,我不知道在一般情况下如何做到这一点。

javascript案例:
How to convert a binary fraction number into decimal fraction number? How to convert binary fraction to decimal lisp 案例:
Convert fractions from decimal to binary

【问题讨论】:

  • 我理解所有推导,包括你推理中的最后一部分 x=2^(-3)。不幸的是,我看不到您如何获得(0.001)base2 = (x)base10 =&gt; log_2(x) = log_10(0.001);注意 0.001 和 x 在相反的一边!
  • @jenesaisquoi 2^log(0.001, 10) 技术在某些情况下会失败!观察:2^log(0.101, 10) # 0.5014999 而 0.101 = (1*1/2) + (0*1/2^2) + (1*1/2^3)=1*0.5 + 0*0.25 + 1*0.125=0.625。和 0.50149990.625.
  • 我在附近有一个解决方案:sum(c(0,0,1)* (0.5^(1:3))) # 0.125sum(c(1,0,1)* (0.5^(1:3))) # 0.625

标签: r decimal base fractions


【解决方案1】:

您可以扩展您在问题中发布的solution,使其还包括从小数分隔符位置开始的两个负幂,如下所示:

base2decimal <- function(base_number, base = 2) {
    base_number = paste(as.character(base_number), ".", sep = "")
    return (mapply(function (val, sep) {
                      val = val[-sep];
                      if (val[[1]] == "-") {
                          sign = -1
                          powmax = sep[[1]] - 3
                          val = val[-1]
                      } else {
                          sign = 1
                          powmax = sep[[1]] - 2
                      };
                      sign * sum(as.numeric(val) * (base ^ seq(powmax, by = -1, length = length(val))))},
        strsplit(base_number, NULL), gregexpr("\\.", base_number)))
}

此代码也适用于小于(或等于)10 的其他基数:

base2decimal(c('0.101', '.101', 0.101, 1101.001, 1101, '-0.101', '-.101', -0.101, -1101.001, -1101))
#[1]   0.625   0.625   0.625  13.125  13.000  -0.625  -0.625  -0.625 -13.125
#[10] -13.000
base2decimal(1110.111)
# 14.875
base2decimal(256.3, 8)
# [1] 174.375

【讨论】:

    【解决方案2】:
    library(cwhmisc) # int, frac
    from2to10 <- function(n) {
    SignOfNumber <- ""
    if (n < 0) {
    n <- abs(n)
    SignOfNumber <- "-"}
    
    nWhole <- int(n)
    nWhole <- as.character(nWhole)
    
    nFraction <- frac(n)
    nFraction <- as.character(nFraction)
    
    DecimalWhole   <- sapply(strsplit(nWhole, split=""), function(x) sum(as.numeric(x) * 2^(rev(seq_along(x) - 1))))
    
    if (nFraction == 0) {
    DecimalFraction <- ""
    paste0(SignOfNumber, DecimalWhole)
    } else { # Find decimal fraction part
    
    part3 <- function(x, y, z) { eval(parse(text=(paste(x, y, z,sep="")))) }
    y <- as.numeric(strsplit(substr(part3("\"",n,"\""), which(strsplit(part3("\"",n,"\""), "")[[1]]==".") + 1, nchar(part3("\"",n,"\""))),"")[[1]])
    DecimalFraction <- sum(y * (0.5^(1:length(y))))
    paste0(SignOfNumber, DecimalWhole + DecimalFraction)
    }
    }
    
    from2to10(0.001) # "0.125"
    as.numeric(from2to10(0.001)) # 0.125
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-05
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 2014-12-04
      相关资源
      最近更新 更多