source("http://macosa.dima.unige.it/r.R")    # If I have not already loaded the library
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
S 10 Calculations with "big" numbers. Strings <-> Numbers. Bases  ten
 
If x and y are two integers ≥ 0 (however big), with add(x,y) and pro(x,y) you have
their sum and product.  If z is another integer you get, for example, (x*y)*(x+z)  by
pro( pro(x,y), add(x,z) )
 
dif(x,y)  calculates the non-negative difference: x-y if x >= y, 0 otherwise.
app(x) converts the string of numbers x into an approximate number
  [ if a number has more than 17 digits you have to put it between " ]
 
Strings are sequences of characters, enclosed in quotes (" or '). If a string is only
formed by digits I can transform it into an integer with the command strtoi.  I can
calculate the number of characters in a string by nchar and extract a substring by
substr.  Instead, I can turn a number into a string with toString, but you should use
NUMBER that does not put quotation marks: NUMBER(3*2) is 6 understood as string
representation. To paste strings S,T,… with nothing in the middle I use paste0(S,T,…).
To produce a sequence of N strings equal to the string X I use char(X ,N).
 
To transform an integer N into Roman notation use as.roman(N).
 
To represent the M/N ratio (M,N integer, M<N) under base B displaying C digits use
MNb(M,N, B, C)
 
##   Big numbers
 
111111111*111111111;  pro("111111111","111111111")
#  1.234568e+16         "12345678987654321"
 
## The calculation of  x*(10+x)+5*x^3  where  x = 123456789012345
x = "123456789012345"
add( pro(x, add(10,x)), pro(5, pro(x, pro(x,x))))
# "9408381861768148891412848380186556157340600"
## Check. I digit the number and get the exponential representation:
9408381861768148891412848380186556157340600
# 9.408382e+42
## Here is what I would get directly:
x = 123456789012345; x*(10+x)+5*x^3; more(last())
# 9.408382e+42  9.40838186176815e+42
#
## 40!
n = 40; y = 0;z = 1;j = 1; while(j<=n){y<- add(y,1); z<- pro(z,y); j<-j+1}; z
# "815915283247897734345611269596115894272000000000"
## 171!
n = 171; y = 0;z = 1;j = 1; while(j<=n){y<- add(y,1); z<- pro(z,y); j<-j+1}; z
#   "1241018070217667823424840524103103992616605577501693185388951803
     6119960752216917529927519781204875855764649595016703870528098898
     5869071076733124203221848436431047357788996854827829075454156196
     4852153468318044293239598173696899657235903947616152278558180061
     176365108428800000000000000000000000000000000000000000"
## A trick to print a long string over multiple rows:
str = z; col = 80; for(n in 0:(nchar(str)/col)) print(substr(str,n*col+1,(n+1)*col))
# "12410180702176678234248405241031039926166055775016931853889518036119960752216917"
# "52992751978120487585576464959501670387052809889858690710767331242032218484364310"
# "47357788996854827829075454156196485215346831804429323959817369689965723590394761"
# "6152278558180061176365108428800000000000000000000000000000000000000000"
#
## 2^1024 can not be calculated directly
2^1023;   2^1024
# 8.988466e+307  Inf
## Using the program, for 2^1024 I get:
y = 1; for(i in 1:1024) y = pro(y,2)
str = y; col = 80; for(n in 0:(nchar(str)/col)) print(substr(str,n*col+1,(n+1)*col))
#  "17976931348623159077293051907890247336179769789423065727343008115773267580550096"
   "31327084773224075360211201138798713933576587897688144166224928474306394741243777"
   "67893424865485276302219601246094119453082952085005768838150682342462881473913110"
   "7237163350510684586298239947245938479716304835356329624224137216"
## nchar(y) -> 309   There are 309 digits (those of 2^1023 were 308)
#
## Approximation in scientific notation
x = "12345678901234567890"; app(x)
# 1.234568e+19
#
## 1000^20-999^20
y = 1; for(i in 1:20) y = pro(y,999)
z = 1; for(i in 1:20) z = pro(z,1000)
dif(z,y)
# "19811135170465317394197775411834107481255499156139810019999"
app(z); app(y); app(dif(z,y))
#  1e+60  9.801889e+59  1.981114e+58
#
##   Noninteger Numbers
 
# If I cannot use WolframAlpha I can use these commands for calculations with noninteger
# numbers. An example: 20 digits of sqrt(13)
more(sqrt(13))
# 3.60555127546399
x="360555127546399"; pro(x,x)
# "130000000000000050973897867201"             # the number ends with 398
x="3605551275463985"; pro(x,x)
# "12999999999999969041877032080225"
x="3605551275463988"; pro(x,x)
# "12999999999999990675184684864144"
x="3605551275463989"; pro(x,x)
# "12999999999999997886287235792121"           # it ends with 3989
x="36055512754639895"; pro(x,x)
# "1300000000000000149183851125611025"
> x="36055512754639893"; pro(x,x)
# "1300000000000000004961800107051449"
x="36055512754639892"; pro(x,x)
# "1299999999999999932850774597771664"         # it ends with 39892
# ...
x="36055512754639892932"; pro(x,x)
# "1300000000000000000058250372420423556624"
x="36055512754639892931"; pro(x,x)
# "1299999999999999999986139346911143770761"   # it ends with 39892931
# The truncation to 20 digits is 3.6055512754639892931
 
# With WoframAlpha:  3.60555127546398929311922126747049594625129657...
#
##   Strings <-> Numbers
 
N = NUMBER(137); S = substr(N,2,3); S; nchar(S); strtoi(paste0(S,"0",S))
#                                   "37"     2       37037
##   Roman numbers
as.roman(1944)
#  MCMXLIV
##   Ratios < 1 in various bases  (4/100 in base 2, 55 digits)
MNb(4,100, 2,55)
# 0. 0 0 0 0 1 0 1 0 0 0 1 1 1 1 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0 
# 0 1 1 1 1 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0 0 1 1 1 1   remanider 36 
# To get more digits I can use MNb(4,100, 2,C) with C>55 or I can find which ones
# to add with MNb(36,100, 2,…)
#
##    char
paste0(char("a",10), char("B",5), char("c",10) )
#  "aaaaaaaaaaBBBBBcccccccccc"
for(i in 3:5) cat( char("(I[H{Z}X]O)", i), "\n" )
# (I[H{Z}X]O)(I[H{Z}X]O)(I[H{Z}X]O) 
# (I[H{Z}X]O)(I[H{Z}X]O)(I[H{Z}X]O)(I[H{Z}X]O) 
# (I[H{Z}X]O)(I[H{Z}X]O)(I[H{Z}X]O)(I[H{Z}X]O)(I[H{Z}X]O)
#
## 105! (see here):
n = 105; y = 0;z = 1;j = 1; while(j<=n){y<- add(y,1); z<- pro(z,y); j<-j+1}
n=1;k=0;h=35; while(n<nchar(z)) {cat(char(" ",h),substr(z,n,n+k),"\n"); k=k+2;n=n+k-1;h=h-1}
#                                    1 
#                                   081 
#                                  39675 
#                                 8240290 
#                                900504101 
#                               30580032964 
#                              9720646107774 
#                             902579144176636 
#                            57322653190990515 
#                           3326984536526808240 
#                          339776398934872029657 
#                         99387290781343681609728 
#                        0000000000000000000000000 

Other examples of use