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