将 2 进制数(带小数部分)转换为 R 中的 10 进制数?
Convert a base2 number (with fractional part) to a base10 number in R?
如何在 R 中将 2 进制数(带小数部分)转换为 10 进制数?这个数字也可以是负数。
示例:
from2to10(10100101) # "165"
from2to10(0) # "0"
from2to10(10100101.01) # "165.25"
from2to10(-10100101) # "-165"
from2to10(-10100101.01) # "-165.25"
from2to10(111101111.010111) # "495.359375"
Edit:我意识到我假设输入是 character
,这对我来说可能是一个错误的假设。我相信相信 R 会保留你所有的 0 和 1(考虑到 R FAQ 7.31)有点信任,但我会保留我的答案 as-is unless/until 一些更好的事情会出现。
这很有趣...不确定 non-decimal 中是否有处理 floating-point 的 R 函数,所以这里有一个...
#' Convert floating-point binary to decimal
#'
#' @param s 'character'
#' @return 'numeric'
#' @examples
#' tests <- c("10100101", "0", "10100101.01", "-10100101", "-10100101.01", "111101111.010111")
#' base2float(tests)
#' # [1] 165.0000 0.0000 165.2500 -165.0000 -165.2500 495.3594
base2float <- function(s, base = 2L) {
# ensure the strings seem logical:
# - start with "-", "+", or "[01]"
# - zero or more "[01]"
# - optional decimal "." (can easily change to "," for alternate reps)
# - zero or more "[01]"
stopifnot(all(grepl("^[-+]?[01]*\.?[01]*$", s)))
splits <- strsplit(s, "\.")
wholes <- sapply(splits, `[[`, 1L)
wholes[wholes %in% c("", "-", "+")] <- paste0(wholes[wholes %in% c("", "-", "+")], "0")
fracs <- sapply(splits, `[`, 2L)
fracs[is.na(fracs)] <- "0"
# because string-length is used in our calcs ...
fracs <- gsub("0+$", "0", fracs)
whole10 <- strtoi(wholes, base = base)
frac10 <- strtoi(fracs, base = base) / (base^nchar(fracs))
whole10 + sign(whole10)*frac10
}
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(10100101) # "165"
from2to10(0) # "0"
from2to10(10100101.01) # "165.25"
from2to10(-10100101) # "-165"
from2to10(-10100101.01) # "-165.25"
from2to10(111101111.010111) # "495.359375"; numeric to string; exact conversion
base2float("111101111.010111") # 495.3594; string to numeric; conversion with rounding. (r2evans)
如何在 R 中将 2 进制数(带小数部分)转换为 10 进制数?这个数字也可以是负数。
示例:
from2to10(10100101) # "165"
from2to10(0) # "0"
from2to10(10100101.01) # "165.25"
from2to10(-10100101) # "-165"
from2to10(-10100101.01) # "-165.25"
from2to10(111101111.010111) # "495.359375"
Edit:我意识到我假设输入是 character
,这对我来说可能是一个错误的假设。我相信相信 R 会保留你所有的 0 和 1(考虑到 R FAQ 7.31)有点信任,但我会保留我的答案 as-is unless/until 一些更好的事情会出现。
这很有趣...不确定 non-decimal 中是否有处理 floating-point 的 R 函数,所以这里有一个...
#' Convert floating-point binary to decimal
#'
#' @param s 'character'
#' @return 'numeric'
#' @examples
#' tests <- c("10100101", "0", "10100101.01", "-10100101", "-10100101.01", "111101111.010111")
#' base2float(tests)
#' # [1] 165.0000 0.0000 165.2500 -165.0000 -165.2500 495.3594
base2float <- function(s, base = 2L) {
# ensure the strings seem logical:
# - start with "-", "+", or "[01]"
# - zero or more "[01]"
# - optional decimal "." (can easily change to "," for alternate reps)
# - zero or more "[01]"
stopifnot(all(grepl("^[-+]?[01]*\.?[01]*$", s)))
splits <- strsplit(s, "\.")
wholes <- sapply(splits, `[[`, 1L)
wholes[wholes %in% c("", "-", "+")] <- paste0(wholes[wholes %in% c("", "-", "+")], "0")
fracs <- sapply(splits, `[`, 2L)
fracs[is.na(fracs)] <- "0"
# because string-length is used in our calcs ...
fracs <- gsub("0+$", "0", fracs)
whole10 <- strtoi(wholes, base = base)
frac10 <- strtoi(fracs, base = base) / (base^nchar(fracs))
whole10 + sign(whole10)*frac10
}
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(10100101) # "165"
from2to10(0) # "0"
from2to10(10100101.01) # "165.25"
from2to10(-10100101) # "-165"
from2to10(-10100101.01) # "-165.25"
from2to10(111101111.010111) # "495.359375"; numeric to string; exact conversion
base2float("111101111.010111") # 495.3594; string to numeric; conversion with rounding. (r2evans)