Как преобразовать двоичное число дроби в десятичное число дроби в R? - PullRequest
2 голосов
/ 02 июня 2019

Мне нужно написать функцию, которая преобразует двоичное число дроби в десятичное число дроби в 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 case:
Как преобразовать двоичное число в десятичное число? Как преобразовать двоичную дробь в десятичную регистр шрифта:
Преобразовать дробную дробь в двоичную

Ответы [ 2 ]

1 голос
/ 03 июня 2019

Вы можете расширить решение , которое вы разместили в своем вопросе, чтобы включить также отрицательные степени двух, начиная с позиции десятичного разделителя, следующим образом:

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
0 голосов
/ 03 июня 2019
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
...