Create a sequence from big power numbers - r

I'm trying to create a sequence of integers from big numbers and couldn't find a way to suceed. Is there a way to do this ?
I tried :
(2^128):(2^128+3000) which returns: [1] 3.402824e+38
So I tried to use the gmp library :
library(gmp)
as.bigz(2^128):as.bigz(2^128+3000)
and got
messages: 1: In as.bigz(2^128):as.bigz(2^128 + 3000) : numerical
expression has 32 elements: only the first used 2: In
as.bigz(2^128):as.bigz(2^128 + 3000) : numerical expression has 32
elements: only the first used

Add your sequence to your "big number":
library(gmp)
as.bigz(2^128) + 0:3000
Big Integer ('bigz') object of length 3001:
[1] 340282366920938463463374607431768211456 340282366920938463463374607431768211457
[3] 340282366920938463463374607431768211458 340282366920938463463374607431768211459
[5] 340282366920938463463374607431768211460 340282366920938463463374607431768211461
# ...

We can use seq
library(gmp)
seq(as.bigz(2^128), length.out = 3001)

Related

Internal representation of a number in R

> trunc(26015)
[1] 26015
> 260.15*100
[1] 26015
> trunc(260.15*100)
[1] 26014
> floor(260.15*100)
[1] 26014
> as.integer(260.15*100)
[1] 26014
For this code in R, is there an issue with the internal representation of the number?
When I do 260.15*100, the number being printed is still 26015, but when I use a function like trunc() or as.integer(), it becomes 26014.
Usually, my value containing the decimal comes from another variable. So how do I overcome this issue?
The print method for a numeric is not the same as its internal representation. 260.15 * 100 is never actually 26015, it is just printed as such. print.numeric uses rounding. The underlying numeric data is floating point. You can see this by changing your print options:
# set print.numeric() to display up to 22 digits, the maximum possible
> options(digits = 22)
> 260.15 * 100
[1] 26014.99999999999636202
> 26015
[1] 26015
In lieu of trunc() or as.integer(), does round() meet your needs?

Does R treat numbers as double internally?

Does R treat numbers mainly as double?
The following code suggests that R treats numbers as double. Even if I make it integer, it easily becomes double after some calculation. (Code1)
Also, even if the result looks like integer, interanlly it is treated as double. (Code2)
Is my understanding right?
Code 1:
> typeof(5)
[1] "double"
> typeof( 5 / 1 )
[1] "double"
> typeof( as.integer(c(1,2,3)) )
[1] "integer"
> typeof( as.integer(c(1,2,3)) + 1 )
[1] "double"
> typeof( as.integer(c(1,2,3)) / 1 )
[1] "double"
Code 2:
> 1 + 2
[1] 3
> typeof( 1 + 2)
[1] "double"
R handles numbers in different ways. In R both integers and double precision float defaults to their 32 bit version.
As pointed out by Andrey, there are two different types of numbers in R.
Literals 1L, 2L, 3L, ...., this is equivalent to as.integer(1)
regular numbers (1, 2, 3.4, any number really)
As well as their complex counterparts.
Literals are integers as such
typeof(1) #double
class(1) #numeric
typeof(1L) #integer
class(1L) #integer
is well defined. However upon calculation, if any part of the calculation is not stored as a lower or equal type than integer, it will automatically be converted to a double:
typeof(1L + 1L) #integer
typeof(1L + 1) #double
typeof(1L + TRUE) #integer
typeof(1L * 3) #double
typeof(1L * 3L) #integer
One should note however, as R runs with 32 bit variables, these have a limited range, compared to python 3.x. However one can get around the 32 bit variables ( in most cases! ) by using the packages bit64 for 64 bit integers and Rmpfr which gives an interface for arbitrary floating point precision (according to their documentation).
Edit
I wrongly stated that "In R both integers and double precision float defaults to their 32 bit version". This is not the case for double precision variables, which default to a their 64 bit counterpart in almost all releases of R nowadays.
To make a number an integer from the start, add L to it:
typeof(1L)
# [1] "integer"
There are dangers in working with 32 bit integers though:
2e9L
# [1] 2000000000
2e9L + 2e9L
# [1] NA
# Warning message:
# In 2000000000L + 2000000000L : NAs produced by integer overflow

Write large numbers into a file in R

I want to write a vector into a file and then read it using Rstudio. The vector includes some large integers (numbers are of order 10^40) and it seems that It can not be written properly since when I want to read it I keep getting these errors:
"ReadList::readn: Invalid real number found when reading from "/Users/Research/RF_improvment/testNTT.txt."
and
"Part::partw: Part 1025 of {$Failed} does not exist.
Set::partw: Part 1025 of {Mod[$Failed + {$Failed}[[1025]], 115792089237316195423570985008687907853269984665640564039457584007913129461761]} does not exist."
Does anyone know how to write large numbers into a file using write function in R? I do not have a problem with calculations and the errors are for reading and writing into a file.
The Maximum integer R can work with can be found this way:
> .Machine$integer.max
# [1] 2147483647
>
So no write or read function within R can deal with integers of this magnitude:
# So when you compute large numbers using R
# they are computed with double precision:
options("scipen"=400, "digits"=4)
anum <- 10^40
bnum <- 9^40
# The above numbers are no longer integers,
# but rather floating values calculated with double precision:
str(anum)
num 10000000000000000304008240626848262428282
If you are using some packages to compute large powers of integers, the result is actually not an integer:
library(gmp)
bigN <- as.bigz(2)^40
bigN
# Big Integer ('bigz') :
# [1] 1099511627776
str(bigN)
# Class 'bigz' raw [1:20] 01 00 00 00 ...
If the goal however is to save these values into a text file and then read them back, then the following approach can be taken:
# Create "big" numbers using gmp package
library(gmp)
bigA <- as.bigz(10)^40
bigB <- as.bigz(9)^40
bigA
# Big Integer ('bigz') :
# [1] 10000000000000000000000000000000000000000
#Save them as character vector:
# write them to a file
write.csv(data.frame(a=as.character(bigA), b=as.character(bigB)), "myfile.csv", row.names=FALSE)
# Let's take a look at the file
system("cat myfile.csv")
#"a","b"
#"10000000000000000000000000000000000000000","147808829414345923316083210206383297601"
# Read them back as a character strings first.
new.dt <- read.csv("myfile.csv", colClasses=c("character","character"))
str(new.dt)
# 'data.frame': 1 obs. of 2 variables:
# $ a: chr "10000000000000000000000000000000000000000"
# $ b: chr "147808829414345923316083210206383297601"
# Convert them back to "bigz" objects:
bigA.new <- as.bigz(new.dt$a)
bigB.new <- as.bigz(new.dt$b)
bigA
#Big Integer ('bigz') :
# [1] 10000000000000000000000000000000000000000

precision of double in R

I have to calculate the difference between two long variables in R.
Initially, it was stored as text. But when I tried to convert them into numeric or double to calculate the difference, R fails to recognize that the difference is 1.
testVariable1 = as.numeric("233203300000000001")
testVariable2 = as.numeric("233203300000000002")
testVariable2 - testVariable1
Result:
[1] 0
What can I do to solve this issue?
Thanks in advance!
library(gmp)
as.bigz("233203300000000002")-as.bigz("233203300000000001")
Big Integer ('bigz') :
[1] 1
You could try using the bit64 package:
library(bit64)
##
testVariable1 <- as.integer64("233203300000000001")
testVariable2 <- as.integer64("233203300000000002")
##
R> testVariable2 - testVariable1
#integer64
#[1] 1
R> as.numeric(testVariable2 - testVariable1)
#[1] 1

Convert hex to decimal in R

I found out that there is function called .hex.to.dec in the fBasics package.
When I do .hex.to.dec(a), it works.
I have a data frame with a column samp_column consisting of such values:
a373, 115c6, a373, 115c6, 176b3
When I do .hex.to.dec(samp_column), I get this error:
"Error in nchar(b) : 'nchar()' requires a character vector"
When I do .hex.to.dec(as.character(samp_column)), I get this error:
"Error in rep(base.out, 1 + ceiling(log(max(number), base =
base.out))) : invalid 'times' argument"
What would be the best way of doing this?
Use base::strtoi to convert hexadecimal character vectors to integer:
strtoi(c("0xff", "077", "123"))
#[1] 255 63 123
There is a simple and generic way to convert hex <-> other formats using "C/C++ way":
V <- c(0xa373, 0x115c6, 0xa373, 0x115c6, 0x176b3)
sprintf("%d", V)
#[1] "41843" "71110" "41843" "71110" "95923"
sprintf("%.2f", V)
#[1] "41843.00" "71110.00" "41843.00" "71110.00" "95923.00"
sprintf("%x", V)
#[1] "a373" "115c6" "a373" "115c6" "176b3"
As mentioned in #user4221472's answer, strtoi() overflows with integers larger than 2^31.
The simplest way around that is to use as.numeric().
V <- c(0xa373, 0x115c6, 0x176b3, 0x25cf40000)
as.numeric(V)
#[1] 41843 71110 95923 10149429248
As #MS Berends noted in the comments, "[a]lso notice that just printing V in the console will already print in decimal."
strtoi() has a limitation of 31 bits. Hex numbers with the high order bit set return NA:
> strtoi('0x7f8cff8b')
[1] 2139946891
> strtoi('0x8f8cff8b')
[1] NA
To get a signed value with 16 bits:
temp <- strtoi(value, base=16L)
if (temp>32767){ temp <- -(65535 - temp) }
In a general form:
max_unsigned <- 65535 #0xFFFF
max_signed <- 32767 #0x7FFF
temp <- strtoi(value, base=16L)
if (temp>max_signed){ temp <- -(max_unsigned- temp) }

Resources