2011-07-07 12 views
24

किसी संख्या को आधार 2 में परिवर्तित करने का सबसे आसान तरीका क्या होगा (एक स्ट्रिंग में, उदाहरण के लिए 5 को "0000000000000101" में परिवर्तित किया जाएगा) आर में? वहाँ intToBits है, लेकिन यह एक स्ट्रिंग के बजाय तार का एक वेक्टर रिटर्न:आर में दशमलव में बाइनरी कनवर्ट करना?

> intToBits(12) 
[1] 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[26] 00 00 00 00 00 00 00 

मैं कुछ अन्य कार्यों की कोशिश की है, लेकिन कोई सफलता मिली:

> toString(intToBits(12)) 
[1] "00, 00, 01, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00" 
+1

'intToBits' _not_ तार का एक वेक्टर वापसी करता है की कोशिश करो। यह एक कच्चे वेक्टर लौटाता है। ध्यान दें कि वेक्टर में 32 तत्व हैं। यह प्रत्येक बिट के लिए एक तत्व है (चूंकि आर 32-बिट पूर्णांक का उपयोग करता है)। मैं ऐसी स्थिति के बारे में नहीं सोच सकता जहां बिट्स की शाब्दिक स्ट्रिंग के रूप में एक संख्या का प्रतिनिधित्व करना उपयोगी होगा ... आप क्या करने की कोशिश कर रहे हैं? –

+0

मैं क्रिप्टैनालिसिस में कुछ उदाहरणों पर काम कर रहा हूं, और चाबियों को बिट अनुक्रमों के रूप में दिखाने में सक्षम होना अच्छा लगता है, "011010110", आदि – Jay

+1

@Jay: आर जीएनयू –

उत्तर

17

@ निको के जवाब का एक मामूली विस्तार निकाल देता है। इस को हटा अग्रणी "0" प्रत्येक बिट से:

paste(sapply(strsplit(paste(rev(intToBits(12))),""),`[[`,2),collapse="") 
[1] "00000000000000000000000000001100" 
+0

वहाँ एक अतिरिक्त 'rev' है, लेकिन इसे हटाने से पूरी तरह से काम करता है! धन्यवाद! – Jay

+0

@ जे: निश्चित। मेरा Ctrl + C/Ctrl + V कौशल की कमी है। –

+0

बहुत सारे बिट्स, इसे ठीक करने का एक साफ तरीका क्या है? – bubakazouba

22

paste(rev(as.integer(intToBits(12))), collapse="") काम

करता है pastecollapse पैरामीटर के साथ वेक्टर को एक स्ट्रिंग में ध्वस्त कर देता है। यद्यपि सही बाइट ऑर्डर प्राप्त करने के लिए आपको rev का उपयोग करना होगा।

as.integer अतिरिक्त शून्य

+0

'rev' का उपयोग करें ... जब तक कि आप सूर्य प्रणाली पर न हों। ;-) –

+0

एचएम, लेकिन प्रत्येक बिट को दो अंकों के रूप में सूचीबद्ध किया गया है: '00' या' 01' ... क्या 'intToBits' द्वारा लौटा कच्चा वेक्टर प्राप्त करने का कोई तरीका है और केवल एक अंक का उपयोग करके प्रत्येक बिट लिखें? – Jay

+0

मैंने इसे करने के लिए एक और आसान तरीका के साथ उत्तर अद्यतन किया। – nico

12

मुझे लगता है कि लगता है कि है आप R.utils पैकेज, तो intToBin() फ़ंक्शन

>library(R.utils) 

>intToBin(12) 
[1] "1100" 

> typeof(intToBin(12)) 
[1] "character" 
3

उपयोग कर सकते हैं इस समारोह एक दशमलव संख्या लेने के लिए और इसी बाइनरी अनुक्रम वापस आ जाएगी, यानी 1 का एक वेक्टर और 0 के

dectobin <- function(y) { 
    # find the binary sequence corresponding to the decimal number 'y' 
    stopifnot(length(y) == 1, mode(y) == 'numeric') 
    q1 <- (y/2) %/% 1 
    r <- y - q1 * 2 
    res = c(r) 
    while (q1 >= 1) { 
    q2 <- (q1/2) %/% 1 
    r <- q1 - q2 * 2 
    q1 <- q2 
    res = c(r, res) 
    } 
    return(res) 
} 
+0

मुझे लगता है कि वाई% /% 2 – skan

2

ओह, लेकिन अगर आपके पास बिट 64 पैकेज द्वारा सक्षम 64 बिट पूर्णांक है तो क्या करें? प्रत्येक उत्तर दिया गया है, @epwalsh के अलावा 64 बिट पूर्णांक पर काम नहीं करेगा क्योंकि आर और आर.यूटल्स के सी आधारित इंटर्नल इसका समर्थन नहीं करते हैं। @ एपवाल्श का समाधान बहुत अच्छा है और यदि आप bit64 पैकेज लोड करते हैं तो आर में काम करता है, इसके अलावा आर में (लूप का उपयोग करके) कुत्ता धीमा है (सभी गति रिश्तेदार हैं)।

o.dectobin <- function(y) { 
    # find the binary sequence corresponding to the decimal number 'y' 
    stopifnot(length(y) == 1, mode(y) == 'numeric') 
    q1 <- (y/2) %/% 1 
    r <- y - q1 * 2 
    res = c(r) 
    while (q1 >= 1) { 
    q2 <- (q1/2) %/% 1 
    r <- q1 - q2 * 2 
    q1 <- q2 
    res = c(r, res) 
    } 
    return(res) 
} 

dat <- sort(sample(0:.Machine$integer.max,1000000)) 
system.time({sapply(dat,o.dectobin)}) 
# user system elapsed 
# 61.255 0.076 61.256 

अगर हम इसे संकलित बाइट हम इस बेहतर बना सकते ...

library(compiler) 
c.dectobin <- cmpfun(o.dectobin) 
system.time({sapply(dat,c.dectobin)}) 
# user system elapsed 
# 38.260 0.010 38.222 

... लेकिन यह अभी भी बहुत धीमी है। हम काफी हद तक तेजी से मिल सकता है अगर हम सी में अपने स्वयं के आंतरिक लिखने (जो मैं यहाँ क्या किया है @ epwalsh के कोड से उधार - मैं, एक सी प्रोग्रामर नहीं कर रहा हूँ स्पष्ट रूप से) ...

library(Rcpp) 
library(inline) 
library(compiler) 
intToBin64.worker <- cxxfunction(signature(x = "string") , '  
#include <string> 
#include <iostream> 
#include <sstream> 
#include <algorithm> 
// Convert the string to an integer 
std::stringstream ssin(as<std::string>(x)); 
long y; 
ssin >> y; 

// Prep output string 
std::stringstream ssout; 


// Do some math 
int64_t q2; 
int64_t q1 = (y/2)/1; 
int64_t r = y - q1 * 2; 
ssout << r; 
while (q1 >= 1) { 
q2 = (q1/2)/1; 
r = q1 - q2 * 2; 
q1 = q2; 
ssout << r; 
} 


// Finalize string 
//ssout << r; 
//ssout << q1; 
std::string str = ssout.str(); 
std::reverse(str.begin(), str.end()); 
return wrap(str); 
', plugin = "Rcpp") 

system.time(sapply(as.character(dat),intToBin64.worker)) 
# user system elapsed 
# 7.166 0.010 7.168 

`` `

+1

लिखना बेहतर है ... जो अब मुझे नोटिस पूरी तरह से बेतुका है क्योंकि बिट 64 में एक .bitstring फ़ंक्शन है जो मेरे आरसीपीपी फ़ंक्शन के रूप में दोगुना तेज़ है ... लेकिन मैं इसे यहां छोड़ दूंगा मूर्खता के स्मारक के रूप में और integer64 से C++ और वापस से पुल करने के संभावित अनुस्मारक के रूप में ... लेकिन निश्चित रूप से बिट 64 स्रोत कोड देखें यदि आपको ऐसा करने के लिए एक और अधिक प्रभावी तरीका चाहिए। – russellpierce

5

intToBits अधिकतम 2^32 तक सीमित है, लेकिन क्या होगा यदि हम 1e10 को बाइनरी में परिवर्तित करना चाहते हैं? फ्लोट नंबरों को बाइनरी में परिवर्तित करने के लिए यहां कार्य किया गया है, यह मानते हुए कि वे numeric के रूप में संग्रहीत बड़े पूर्णांक हैं।

dec2bin <- function(fnum) { 
    bin_vect <- rep(0, 1 + floor(log(fnum, 2))) 
    while (fnum >= 2) { 
    pow <- floor(log(fnum, 2)) 
    bin_vect[1 + pow] <- 1 
    fnum <- fnum - 2^pow 
    } # while 
    bin_vect[1] <- fnum %% 2 
    paste(rev(bin_vect), collapse = "") 
} #dec2bin 

इस समारोह 2^53 = 9.007199e15 के बाद अंक ढीला करने के लिए शुरू होता है, लेकिन छोटे संख्या के लिए ठीक काम करता है।

microbenchmark(dec2bin(1e10+111)) 
# Unit: microseconds 
#     expr  min  lq  mean median  uq max neval 
# dec2bin(1e+10 + 111) 123.417 125.2335 129.0902 126.0415 126.893 285.64 100 
dec2bin(9e15) 
# [1] "11111111110010111001111001010111110101000000000000000" 
dec2bin(9e15 + 1) 
# [1] "11111111110010111001111001010111110101000000000000001" 
dec2bin(9.1e15 + 1) 
# [1] "100000010101000110011011011011011101001100000000000000" 
+0

मुझे ऐसी बड़ी संख्याओं को बदलने की ज़रूरत नहीं है, लेकिन वैसे भी महान जवाब! +1 – Jay

+1

मुझे एक समस्या का सामना करना पड़ा जहां मुझे बड़ी संख्या में काम करने की आवश्यकता है और समाधान के लिए स्टैक ओवरफ्लो पर खोज करने के बाद अंततः अपना कोड लिखा :) – inscaven

2

»binaryLogic«

library(binaryLogic) 

ultimate_question_of_life_the_universe_and_everything <- as.binary(42) 

summary(ultimate_question_of_life_the_universe_and_everything) 
#> Signedness Endianess value<0 Size[bit] Base10 
#> 1 unsigned Big-Endian FALSE   6  42 

> as.binary(0:3, n=2) 
[[1]] 
[1] 0 0 

[[2]] 
[1] 0 1 

[[3]] 
[1] 1 0 

[[4]] 
[1] 1 1 
-2
decimal.number<-5 

i=0 

result<-numeric() 

while(decimal.number>0){ 

    remainder<-decimal.number%%2 

    result[i]<-remainder 

    decimal.number<-decimal.number%/%2 

    i<-i+1 
} 
+0

हालांकि यह कोड प्रश्न का उत्तर दे सकता है, ** ** और * के बारे में अतिरिक्त संदर्भ प्रदान करता है। * क्यों ** यह हल करता है समस्या का जवाब उत्तर के दीर्घकालिक मूल्य में सुधार होगा। – Alexander

संबंधित मुद्दे