Using the in-built capabilities of your language, calculate the integer value of:
62060698786608744707...92256259918212890625
Note:
V y = String(BigInt(5) ^ 4 ^ 3 ^ 2)print(‘5^4^3^2 = #....#. and has #. digits’.format(y[0.<20], y[(len)-20..], y.len))
5^4^3^2 = 62060698786608744707...92256259918212890625 and has 183231 digits
200000n#5432bfloat^^^"%.0f"s:strfmtdups:len."digits".crdup20s:lsub."...".20s:rsub.cr
183231 digits62060698786608744707...92256259918212890625
(in-package"ACL2")(include-book"arithmetic-3/floor-mod/floor-mod":dir:system)(set-print-length0state)(defunarbitrary-precision()(declare(xargs:mode:program))(let*((x(expt5(expt4(expt32))))(s(mv-let(colstr)(fmt1-to-string"~xx"(list(cons#\xx))0)(declare(ignorecol))str)))(cw"~s0 ... ~x1 (~x2 digits)~%"(subseqs020)(modx(expt1020))(1-(lengths)))))
62060698786608744707 ... 92256259918212890625 (183231 digits)
Using GMP, Ada bindings provided in GNATColl
withAda.Text_IO;useAda.Text_IO;withGNATCOLL.GMP;useGNATCOLL.GMP;withGNATCOLL.GMP.Integers;useGNATCOLL.GMP.Integers;procedureArbitraryIntistypestraccisaccessString;BigInt:Big_Integer;len:Natural;str:stracc;beginSet(BigInt,5);Raise_To_N(BigInt,Unsigned_Long(4**(3**2)));str:=newString'(Image(BigInt));len:=str'Length;Put_Line("Size is:"&Natural'Image(len));Put_Line(str(1..20)&"....."&str(len-19..len));endArbitraryInt;
Size is: 18323162060698786608744707.....92256259918212890625
Tested with Agena 5.0.3 Win32
The Agena distribution includes Mike's Arbitrary Precision Math Library by Michael C. Ring.
Note, the MAPM library handles real numbers, not just integers.
On some platforms, an explicit "import" statement is required to use it.
In order to get the full result, we need to specify how many digits we want otherwise, we get a few digits followed by a lot of zeros.
We handle this here by first calculating with the default precision, finding where the decimal point is and then recalculating with the actual number of digits ( plus some more for decimal places - which aren't used, obviously ).
scope # calculate 5^4^3^2 using Mike's Arbitrary Precision Math library import mapm; # explicit import needed for: Linux, Mac OS X, Windows and Solaris # returns a string containing 5^4^3^2 as calculated by mapm local constant calc5up4up3up2 := proc() is return mapm.xtostring( mapm.xround( mapm.xnumber( 5 ) ^ mapm.xnumber( 4 ^ ( 3 ^ 2 ) ) ) ) end; # do the calculation with default precision local p := calc5up4up3up2(); # find the number of digits before the point local d := size( p ); local point := "." in p; if point <> null then d := point - 1 fi; # redo the calculation with the actual number of required digits ( plus a bit extra ) mapm.xdigits( d + 30 ); p := calc5up4up3up2(); d := size( p ); point := "." in p; if point <> null then d := point - 1 fi; io.write( "5^4^3^2 has ", d, " digits: ", p[ 1 to 20 ], "...", p[ d - 19 to d ], "\n" )end
5^4^3^2 has 183231 digits: 62060698786608744707...92256259918212890625
BEGINCOMMENT The task specifies "Strictly speaking, this should not be solved by fixed-precision numeric libraries where the precision has to be manually set to a large value; although if this is the only recourse then it may be used with a note explaining that the precision must be set manually to a large enough value." Now one should always speak strictly, especially to animals and small children and, strictly speaking, Algol 68 Genie requires that a non-default numeric precision for a LONG LONG INT be specified by "precision=<integral denotation>" either in a source code PRAGMAT or as a command line argument. However, that specification need not be made manually. This snippet of code outputs an appropriate PRAGMAT printf (($gg(0)xgl$, "PR precision=", ENTIER (1.0 + log (5) * 4^(3^(2))), "PR")); and the technique shown in the "Call a foreign-language function" task used to write, compile and run an Algol 68 program in which the precision is programmatically determined. The default stack size on this machine is also inadequate but twice the default is sufficient. The PRAGMAT below can be machine generated with printf (($gg(0)xgl$, "PR stack=", 2 * system stack size, "PR"));COMMENT PR precision=183231 PR PR stack=16777216 PR INT digits = ENTIER (1.0 + log (5) * 4^(3^(2))), exponent = 4^(3^2); LONG LONG INT big = LONG LONG 5^exponent; printf (($gxg(0)l$, " First 20 digits:", big % LONG LONG 10 ^ (digits - 20))); printf (($gxg(0)l$, " Last 20 digits:", big MOD LONG LONG 10 ^ 20)); printf (($gxg(0)l$, "Number of digits:", digits))END
First 20 digits: 62060698786608744707 Last 20 digits: 92256259918212890625Number of digits: 183231
def Main() var len as Int var result as Str result = Str(5**4**3**2) len = result.length() Print(len) Print(result[:20]) Print(result[len-20:])end
num:to:string5^4^3^2print[first.n:20num".."last.n:20num"=>"sizenum"digits"]
62060698786608744707 .. 92256259918212890625 => 183231 digits
Many of BBC BASIC's advanced features are provided by libraries, in this case by the suppliedbigint.bbc library.
10INSTALL@lib$+"bigint"20t1=TIME30x=FNbignew(200000)40PROCbigval(x,"5")50PROCbigpow(x,x,4^(3^2))60x$=FNbigstr(x)70t2=TIME80PRINT"First twenty digits: "LEFT$(x$,20)90PRINT" Last twenty digits: "RIGHT$(x$,20)100PRINT"Total number of digits: ";LEN(x$)110PRINT"Approximate run time: ";(t2-t1)/100" seconds"
First twenty digits: 62060698786608744707 Last twenty digits: 92256259918212890625Total number of digits: 183231Approximate run time: 4.43 seconds
/* 5432.bc */y=5^4^3^2c=length(y)" First 20 digits: "; y/(10^(c-20))" Last 20 digits: "; y%(10^20)"Number of digits: "; cquit
Output:
$ time bc 5432.bc First 20 digits: 62060698786608744707 Last 20 digits: 92256259918212890625Number of digits: 183231 0m24.81s real 0m24.81s user 0m0.00s system
At the prompt type the following one-liner:
{?} @(5^4^3^2:?first [20 ? [-21 ?last [?length)&str$(!first "..." !last "\nlength " !length){!} 62060698786608744707...92256259918212890625length 183231 S 0,11 sec (4372.4475)
#include<gmp.h>#include<stdio.h>#include<string.h>intmain(){mpz_ta;mpz_init_set_ui(a,5);mpz_pow_ui(a,a,1<<18);/* 2**18 == 4**9 */intlen=mpz_sizeinbase(a,10);printf("GMP says size is: %d\n",len);/* because GMP may report size 1 too big; see doc */char*s=mpz_get_str(0,10,a);printf("size really is %d\n",len=strlen(s));printf("Digits: %.20s...%s\n",s,s+len-20);// free(s); /* we could, but we won't. we are exiting anyway */return0;}
GMP says size is: 183231size really is 183231Digits: 62060698786608744707...92256259918212890625
OpenSSL is about 17 times slower than GMP (on one computer), but still fast enough for this small task.
/* 5432.c */#include<openssl/bn.h>/* BN_*() */#include<openssl/err.h>/* ERR_*() */#include<stdlib.h>/* exit() */#include<stdio.h>/* fprintf() */#include<string.h>/* strlen() */voidfail(constchar*message){fprintf(stderr,"%s: error 0x%08lx\n",ERR_get_error());exit(1);}intmain(){BIGNUMtwo,three,four,five;BIGNUManswer;BN_CTX*context;size_tlength;char*string;context=BN_CTX_new();if(context==NULL)fail("BN_CTX_new");/* answer = 5 ** 4 ** 3 ** 2 */BN_init(&two);BN_init(&three);BN_init(&four);BN_init(&five);if(BN_set_word(&two,2)==0||BN_set_word(&three,3)==0||BN_set_word(&four,4)==0||BN_set_word(&five,5)==0)fail("BN_set_word");BN_init(&answer);if(BN_exp(&answer,&three,&two,context)==0||BN_exp(&answer,&four,&answer,context)==0||BN_exp(&answer,&five,&answer,context)==0)fail("BN_exp");/* string = decimal answer */string=BN_bn2dec(&answer);if(string==NULL)fail("BN_bn2dec");length=strlen(string);printf(" First 20 digits: %.20s\n",string);if(length>=20)printf(" Last 20 digits: %.20s\n",string+length-20);printf("Number of digits: %zd\n",length);OPENSSL_free(string);BN_free(&answer);BN_free(&five);BN_free(&four);BN_free(&three);BN_free(&two);BN_CTX_free(context);return0;}
$ make LDLIBS=-lcrypto 5432 cc -O2 -pipe -o 5432 5432.c -lcrypto$ time ./5432 First 20 digits: 62060698786608744707 Last 20 digits: 92256259918212890625Number of digits: 183231 0m1.30s real 0m1.30s user 0m0.00s system
System.Numerics.BigInteger
was added in C# 4. The exponent ofBigInteger.Pow()
is limited to a 32-bit signed integer, which is not a problem in this specific task.
usingSystem;usingSystem.Diagnostics;usingSystem.Linq;usingSystem.Numerics;staticclassProgram{staticvoidMain(){BigIntegern=BigInteger.Pow(5,(int)BigInteger.Pow(4,(int)BigInteger.Pow(3,2)));stringresult=n.ToString();Debug.Assert(result.Length==183231);Debug.Assert(result.StartsWith("62060698786608744707"));Debug.Assert(result.EndsWith("92256259918212890625"));Console.WriteLine("n = 5^4^3^2");Console.WriteLine("n = {0}...{1}",result.Substring(0,20),result.Substring(result.Length-20,20));Console.WriteLine("n digits = {0}",result.Length);}}
n = 5^4^3^2n = 62060698786608744707...92256259918212890625n digits = 183231
To compile link with GMP-lgmp
#include<iostream>#include<boost/multiprecision/gmp.hpp>#include<string>namespacemp=boost::multiprecision;intmain(intargc,charconst*argv[]){// We could just use (1 << 18) instead of tmpres, but let's point out one// pecularity with gmp and hence boost::multiprecision: they won't accept// a second mpz_int with pow(). Therefore, if we stick to multiprecision// pow we need to convert_to<uint64_t>().uint64_ttmpres=mp::pow(mp::mpz_int(4),mp::pow(mp::mpz_int(3),2).convert_to<uint64_t>()).convert_to<uint64_t>();mp::mpz_intres=mp::pow(mp::mpz_int(5),tmpres);std::strings=res.str();std::cout<<s.substr(0,20)<<"..."<<s.substr(s.length()-20,20)<<std::endl;return0;}
62060698786608744707...92256259918212890625
Be sure to import ceylon.whole in your module.ceylon file.
importceylon.whole{wholeNumber,two}sharedvoidrun(){valuefive=wholeNumber(5);valuefour=wholeNumber(4);valuethree=wholeNumber(3);valuebigNumber=five^four^three^two;valuefirstTwenty="62060698786608744707";valuelastTwenty="92256259918212890625";valuebigString=bigNumber.string;"The number must start with ``firstTwenty`` and end with ``lastTwenty``"assert(bigString.startsWith(firstTwenty),bigString.endsWith(lastTwenty));valuebigSize=bigString.size;print("The first twenty digits are ``bigString[...19]``");print("The last twenty digits are ``bigString[(bigSize - 20)...]``");print("The number of digits in 5^4^3^2 is ``bigSize``");}
The first twenty digits are 62060698786608744707The last twenty digits are 92256259918212890625The number of digits in 5^4^3^2 is 183231
(defnexp[nk](reduce *(repeatkn)))(defbig(->>2(exp3)(exp4)(exp5)))(defsbig(strbig))(assert(="62060698786608744707"(.substringsbig020)))(assert(="92256259918212890625"(.substringsbig(-(countsbig)20))))(println(countsbig)"digits")(println(str(.substringsbig020)".."(.substringsbig(-(countsbig)20)))(str"("(countsbig)" digits)"))
output> 62060698786608744707..92256259918212890625 (183231 digits)
Redefiningexp as follows speeds up the calculation ofbig about a hundred times:
(defnexp[nk](cond(zero?(modk2))(recur(*nn)(/k2))(zero?(modk3))(recur(*nnn)(/k3)):else(reduce *(repeatkn))))
This program uses thebigint
type that is supplied with Portable CLU, inmisc.lib
. The program must be merged with that library in order to work.
The type is not included in the CLU specification, however it is included as a librarywith the reference implementation.
start_up = proc () % Get bigint versions of 5, 4, 3 and 2 five: bigint := bigint$i2bi(5) four: bigint := bigint$i2bi(4) three: bigint := bigint$i2bi(3) two: bigint := bigint$i2bi(2) % Calculate 5**4**3**2 huge_no: bigint := five ** four ** three ** two % Turn answer into string huge_str: string := bigint$unparse(huge_no) % Scan for first digit (the string will have some leading whitespace) i: int := 1 while huge_str[i] = ' ' do i := i + 1 end po: stream := stream$primary_output() stream$putl(po, "First 20 digits: " || string$substr(huge_str, i, 20)) stream$putl(po, "Last 20 digits: " || string$substr(huge_str, string$size(huge_str)-19, 20)) stream$putl(po, "Amount of digits: " || int$unparse(string$size(huge_str) - i + 1))end start_up
First 20 digits: 62060698786608744707Last 20 digits: 92256259918212890625Amount of digits: 183231
This entry might be pushing the limits of the spirit of the task. COBOL does not have arbitrary-precision integers in the spec, but it does mandate a precision of some 1000 digits with intermediate results, from 10^-999 through 10^1000, for purposes of rounding financially sound decimal arithmetic. GnuCOBOL uses libgmp or equivalent to meet and surpass this requirement, but this precision is not exposed to general programming in the language. The capabilities are included in the GnuCOBOL implementation run-time support, but require access to some of the opaque features of libgmp for use in this task.
This listing includes a few calculations, 12345**9 is an example that demonstrates the difference between the library's view of certain string lengths and a native C view of the data.
identificationdivision.program-id.arbitrary-precision-integers.remarks.Usesopaquelibgmpinternalsthatarebuiltintolibcob.datadivision.working-storagesection.01gmp-number.05mp-allocusagebinary-long.05mp-sizeusagebinary-long.05mp-limbusagepointer.01gmp-build.05mp-allocusagebinary-long.05mp-sizeusagebinary-long.05mp-limbusagepointer.01the-intusagebinary-c-longunsigned.01the-exponentusagebinary-c-longunsigned.01valid-exponentusagebinary-longvalue1.88cant-usevalue0whensettofalse1.01number-stringusagepointer.01number-lengthusagebinary-long.01window-widthconstantas20.01limit-widthusagebinary-long.01number-bufferpic x(window-width)based.proceduredivision.arbitrary-main. *> calculate 10 ** 19performinitialize-integers.display"10 ** 19 : "withnoadvancingmove10tothe-intmove19tothe-exponentperformraise-pow-accrete-exponentperformshow-all-or-portionperformclean-up *> calculate 12345 ** 9performinitialize-integers.display"12345 ** 9 : "withnoadvancingmove12345tothe-intmove9tothe-exponentperformraise-pow-accrete-exponentperformshow-all-or-portionperformclean-up *> calculate 5 ** 4 ** 3 ** 2performinitialize-integers.display"5 ** 4 ** 3 ** 2: "withnoadvancingmove3tothe-intmove2tothe-exponentperformraise-pow-accrete-exponentmove4tothe-intperformraise-pow-accrete-exponentmove5tothe-intperformraise-pow-accrete-exponentperformshow-all-or-portionperformclean-upgoback. *> **************************************************************initialize-integers.call"__gmpz_init"usinggmp-numberreturningomittedcall"__gmpz_init"usinggmp-buildreturningomitted.raise-pow-accrete-exponent. *> check before using previously overflowed exponent intermediateifcant-usethendisplay"Error: intermediate overflow occured at "the-exponentuponsyserrgobackend-ifcall"__gmpz_set_ui"usinggmp-numberbyvalue0returningomittedcall"__gmpz_set_ui"usinggmp-buildbyvaluethe-intreturningomittedcall"__gmpz_pow_ui"usinggmp-numbergmp-buildbyvaluethe-exponentreturningomittedcall"__gmpz_set_ui"usinggmp-buildbyvalue0returningomittedcall"__gmpz_get_ui"usinggmp-numberreturningthe-exponentcall"__gmpz_fits_ulong_p"usinggmp-numberreturningvalid-exponent. *> get string representation, base 10show-all-or-portion.call"__gmpz_sizeinbase"usinggmp-numberbyvalue10returningnumber-lengthdisplay"GMP length: "number-length", "withnoadvancingcall"__gmpz_get_str"usingnullbyvalue10byreferencegmp-numberreturningnumber-stringcall"strlen"usingbyvaluenumber-stringreturningnumber-lengthdisplay"strlen: "number-length *> slide based string across first and last of buffermovewindow-widthtolimit-widthsetaddressofnumber-buffertonumber-stringifnumber-length<=window-widththenmovenumber-lengthtolimit-widthdisplaynumber-buffer(1:limit-width)elsedisplaynumber-bufferwithnoadvancingsubtractwindow-widthfromnumber-lengthmovefunctionmax(0,number-length)tonumber-lengthifnumber-length<=window-widththenmovenumber-lengthtolimit-widthelsedisplay"..."withnoadvancingend-ifsetaddressofnumber-bufferupbyfunctionmax(window-width,number-length)displaynumber-buffer(1:limit-width)end-if.clean-up.call"free"usingbyvaluenumber-stringreturningomittedcall"__gmpz_clear"usinggmp-numberreturningomittedcall"__gmpz_clear"usinggmp-buildreturningomittedsetaddressofnumber-buffertonullsetcant-usetofalse.endprogramarbitrary-precision-integers.
prompt$ cobc -xj arbitrary-integer.cob10 ** 19 : GMP length: +0000000020, strlen: +00000000201000000000000000000012345 ** 9 : GMP length: +0000000038, strlen: +000000003766591661114886562814868071520097656255 ** 4 ** 3 ** 2: GMP length: +0000183231, strlen: +000018323162060698786608744707...92256259918212890625
Common Lisp has arbitrary precision integers, inherited from MacLisp: "[B]ignums—arbitrary precision integer arithmetic—were added [to MacLisp] in 1970 or 1971 to meet the needs of Macsyma users." [Evolution of Lisp[1], 2.2.2]
(let((s(format()"~s"(expt5(expt4(expt32))))))(formatt"~a...~a, length ~a"(subseqs020)(subseqs(-(lengths)20))(lengths)))
62060698786608744707...92256259918212890625, length 183231
require"big"z=(BigInt.new(5)**4**3**2).to_szSize=z.sizeputs"5**4**3**2 =#{z[0,20]} ..#{z[zSize-20,20]} and has#{zSize} digits"
5**4**3**2 = 62060698786608744707 .. 92256259918212890625 and it has 183231 digits
voidmain(){importstd.stdio,std.bigint,std.conv;autos=text(5.BigInt^^4^^3^^2);writefln("5^4^3^2 = %s..%s (%d digits)",s[0..20],s[$-20..$],s.length);}
5^4^3^2 = 62060698786608744707..92256259918212890625 (183231 digits)
With dmd about 0.55 seconds compilation time (-release -noboundscheck) and about 3.3 seconds run time.
Originally Dart's integral typeint supported arbitrary length integers, but this is no longer the case; Dart now supports integral typeBigInt.
import'dart:math'showpow;intfallingPowers(intbase)=>base==1?1:pow(base,fallingPowers(base-1));voidmain(){finalexponent=fallingPowers(4),s=BigInt.from(5).pow(exponent).toString();print('First twenty:${s.substring(0,20)}');print('Last twenty:${s.substring(s.length-20)}');print('Number of digits:${s.length}');
First twenty: 62060698786608744707Last twenty: 92256259918212890625Number of digits: 183231
[5432.dc]sz5 4 3 2 ^ ^ ^ sy[y = 5 ^ 4 ^ 3 ^ 2]szly Z sc[c = length of y]sz[ First 20 digits: ]P ly 10 lc 20 - ^ / p sz[y / (10 ^ (c - 20))]sz[ Last 20 digits: ]P ly 10 20 ^ % p sz[y % (10 ^ 20)]sz[Number of digits: ]P lc p sz
$ time dc 5432.dc First 20 digits: 62060698786608744707 Last 20 digits: 92256259918212890625Number of digits: 183231 0m24.80s real 0m24.81s user 0m0.00s system
Thanks for Rudy Velthuis, BigIntegers Library[2].
programArbitrary_precision_integers;{$APPTYPE CONSOLE}usesSystem.SysUtils,Velthuis.BigIntegers;varvalue:BigInteger;result:string;beginvalue:=BigInteger.pow(3,2);value:=BigInteger.pow(4,value.AsInteger);value:=BigInteger.pow(5,value.AsInteger);result:=value.tostring;Write('5^4^3^2 = ');Write(result.substring(0,20),'...');Write(result.substring(result.length-20,20));Writeln(' (',result.Length,' digits)');readln;end.
5^4^3^2 = 62060698786608744707...92256259918212890625 (183231 digits)
E implementations are required to support arbitrary-size integers transparently.
? def value := 5**(4**(3**2)); null? def decimal := value.toString(10); null? decimal(0, 20)# value: "62060698786608744707"? decimal(decimal.size() - 20)# value: "92256259918212890625"? decimal.size()# value: 183231
;; to save space and time, we do'nt stringify Ω = 5^4^3^2 ,;; but directly extract tail and head and number of decimal digits(lib'bigint);; arbitrary size integers(definee10000(expt1010000));; 10^10000(define(last-nbig(n20))(string-append"..."(number->string(modulobig(expt10n)))))(define(first-nbig(n20))(while(>bige10000)(set!big(/bige10000)));; cut 10000 digits at a time(string-append(take(number->stringbig)n)"..."));; faster than directly using (number-length big)(define(digitsbig(digits0))(while(>bige10000)(set!big(/bige10000))(set!digits(1+digits)))(+(*digits10000)(number-lengthbig)))(defineΩ(expt5(expt4(expt32))))(last-nΩ)→"...92256259918212890625"(first-nΩ)→"62060698786608744707..."(digitsΩ)→183231
defmoduleArbitrarydodefpow(_,0),do:1defpow(b,e)whene>0,do:pow(b,e,1)defppow(b,1,acc),do:acc*bdefppow(b,p,acc)whenrem(p,2)==0,do:pow(b*b,div(p,2),acc)defppow(b,p,acc),do:pow(b,p-1,acc*b)deftestdos=pow(5,pow(4,pow(3,2)))|>to_stringl=String.length(s)prefix=String.slice(s,0,20)suffix=String.slice(s,-20,20)IO.puts"Length:#{l}\nPrefix:#{prefix}\nSuffix:#{suffix}"endendArbitrary.test
Length: 183231Prefix:62060698786608744707Suffix:92256259918212890625
As of Emacs 27.1, bignums are supported via GMP. However, there is a configurable limit on the maximum bignum size. If the limit is exceeded, an overflow error is raised.
(let*((integer-width(*6553616)); raise bignum limit from 65536 bits to avoid overflow error(answer(number-to-string(expt5(expt4(expt32)))))(length(lengthanswer)))(message"%s has %d digits"(if(>length40)(format"%s...%s"(substringanswer020)(substringanswer(-length20)length))answer)length))
Emacs versions older than 27.1 do not support bignums, but include Calc, a library that implements big integers. Thecalc-eval
function takes an algebraic formula in a string, and returns the result in a string.
(let*((answer(calc-eval"5**4**3**2"))(length(lengthanswer)))(message"%s has %d digits"(if(>length40)(format"%s...%s"(substringanswer020)(substringanswer(-length20)length))answer)length))
This implementation isvery slow; one computer, running GNU Emacs 23.4.1, needed about seven minutes to find the answer.
62060698786608744707...92256259918212890625 has 183231 digits
Erlang supports arbitrary precision integers. However, the math:pow function returns a float. This implementation includes an implementation of pow for integers with exponent greater than 0.
-module(arbitrary).-compile([export_all]).pow(B,E)whenE>0->pow(B,E,1).pow(_,0,_)->0;pow(B,1,Acc)->Acc*B;pow(B,P,Acc)whenPrem2==0->pow(B*B,Pdiv2,Acc);pow(B,P,Acc)->pow(B,P-1,Acc*B).test()->I=pow(5,pow(4,pow(3,2))),S=integer_to_list(I),L=length(S),Prefix=lists:sublist(S,20),Suffix=lists:sublist(S,L-19,20),io:format("Length:~b~nPrefix:~s~nSuffix:~s~n",[L,Prefix,Suffix]).
23> arbitrary:test().
Length: 183231Prefix:62060698786608744707Suffix:92256259918212890625ok
You can specifiy arbitrary-precision integers (bigint or System.Numeric.BigInteger) in F# by postfixing the number with the letter 'I'. While '**' is the power function, two things should be noted:
let()=letanswer=5I**(int(4I**(int(3I**2))))letsans=answer.ToString()printfn"Length = %d, digits %s ... %s"sans.Length(sans.Substring(0,20))(sans.Substring(sans.Length-20));;Length=183231,digits62060698786608744707...92256259918212890625
Factor has built-in bignum support. Operations on integers overflow to bignums.
USING:formattingkernelmath.functionsmath.parsersequences;IN:rosettacode.bignums:test-bignums(--)5 4 3 2^^^number>string[20head][20tail*][length]tri"5^4^3^2 is %s...%s and has %d digits\n"printf;
It prints:5^4^3^2 is 62060698786608744707...92256259918212890625 and has 183231 digits
ANS Forth has no in-built facility for arbitrarily-sized numbers, but libraries are available.
Here is a solution using The Forth Scientific Library, availablehere.
Thebig.fth needs to be patched to allow printingof numbers with more than 256 digits. Note that this restriction is only on the printing routines, as the size of numbers handled by the library is only limited by the available memory.
The patch is:
388c388< CREATE big_string 256 CHARS ALLOT---> CREATE big_string 500000 CHARS ALLOT394c394< big_string 256 CHARS + bighld ! ; \ Haydon p 67---> big_string 500000 CHARS + bighld ! ; \ Haydon p 67403c403< big_string 256 CHARS + \ One past end of string---> big_string 500000 CHARS + \ One past end of string
Here is the solution:
INCLUDEbig.fthbig_digit_pointer*exp\ iteration counterbig_digit_pointer*base\ point to base of number being exponentiatedbig_digit_pointer*0\ store 0big_digit_pointer*1\ store 1big_digit_pointer*result\ point to result of exponentiationbig_digit_pointer*temp\ point to temporary result:big--( addr-n -- )DUP0*1big-( addr-n addr-n-1 )\ decrement valueSWAPDUP@ABS1+CELLSMOVE( )\ overwrite addr-n with addr-n-1;:big>( addr1 addr2 -- flag )2DUPbig<>R( addr1 addr2 )( R: flag1 )big=( flag2 )( R: flag1 )R>OR0=( ! <= );:big^( addr-base addr-exp - addr )to_pointer*expto_pointer*baseHERE1,0,to_pointer*0\ create limit value for counterHERE1,1,to_pointer*1\ create subtraend for counterHERE1,1,to_pointer*result\ create result = 1BEGIN0*exp0*0big>( flag )\ loop while exp > 00*expbig--\ prepare for next iterationWHILE0*result0*basebig*to_pointer*temp\ temp = result * base0*temp0*resultreposition\ move [temp,HERE[ to [result,result+size[REPEAT0*result0*0reposition\ overwrite *0 with result0*0\ and return its address;:big-show( addr -- )\ show first 20 and last 20 digits of the big number<big#big#s#big>( addr n )\ returns stringDUP.." digits"CR\ show number of digitsDUP50>IFOVER20TYPE."..."\ show first 20 digits+20-20TYPECR\ show last 20 digitsELSETYPECRTHEN;\ compute 5^(4^(3^2))big5big4big3big2big^big^big^big-showCR
and the output:
183231 digits62060698786608744707...92256259918212890625
Modern Fortran has no in-built facility for arbitrarily-sized numbers, but libraries are available.
Here is a solution using David M. Smith's FM library, availablehere.
programbignumusefmzmimplicit none type(im)::ainteger::ncallfm_set(50)a=to_im(5)**(to_im(4)**(to_im(3)**to_im(2)))n=to_int(floor(log10(to_fm(a))))callim_print(a/to_im(10)**(n-19))callim_print(mod(a,to_im(10)**20))end program
6206069878660874470792256259918212890625
freebasic has it's own gmp static library.Here, a power function operates via a string and uinteger.
#Includeonce"gmp.bi"DimSharedAsZstring*100000000outtextFunctionPower(numberAsString,nAsUinteger)AsString'automate precision#definedp3321921DimAs__mpf_struct_number,FloatAnswerDimAsUlongintln=Len(number)*(n)*4Ifln>dpThenln=dpmpf_init2(@FloatAnswer,ln)mpf_init2(@_number,ln)mpf_set_str(@_number,number,10)mpf_pow_ui(@Floatanswer,@_number,n)gmp_sprintf(@outtext,"%."&Str(n)&"Ff",@FloatAnswer)Varouttxt=Trim(outtext)IfInstr(outtxt,".")Thenouttxt=Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")ReturnTrim(outtxt)EndFunctionExterngmp_versionAlias"__gmp_version"AsZstringPtrPrint"GMP version ";*gmp_versionPrintvarans=power("5",(4^(3^2)))PrintLeft(ans,20)+" ... "+Right(ans,20)Print"Number of digits ";Len(ans)Sleep
GMP version 5.1.162060698786608744707 ... 92256259918212890625Number of digits 183231
Frink has built-in arbitrary-precision integers and all operations automatically promote to arbitrary precision when needed.
Fun Fact: The drastically faster arbitrary-precision integer operations that landed in Java 8 (for much faster multiplication, exponentiation, and toString) were taken from Frink's implementation and contributed to Java. Another fun fact is that it took employees from Java 11 years to integrate the improvements.
a = 5^4^3^2as = "$a" // Coerce to stringprintln["Length=" + length[as] + ", " + left[as,20] + "..." + right[as,20]]
This printsLength=183231, 62060698786608744707...92256259918212890625
Thanks, Ken
/*Uses GMP for Multiple Precision ArithmeticInstall GMP using terminal and Homebrew command, "brew install gmp"before running this app in FutureBasic.Homebrew available here, https://brew.sh*/include "NSLog.incl"void local fn GMPoutput CFStringRef sourcePath = fn StringByAppendingPathComponent( @"/tmp/", @"temp.m" ) CFStringRef executablePath = fn StringByAppendingPathComponent( @"/tmp/", @"temp" ) CFStringRef gmpStr = @"#import <Foundation/Foundation.h>\n#import <gmp.h>\n¬ int main(int argc, const char * argv[]) {\n¬ @autoreleasepool {\n¬ mpz_t a;\n¬ mpz_init_set_ui(a, 5);\n¬ mpz_pow_ui(a, a, 1 << 18);\n¬ size_t len = mpz_sizeinbase(a, 10);\n¬ printf(\"GMP says size is: %zu\\n\", len);\n¬ char *s = mpz_get_str(0, 10, a);\n¬ size_t trueLen = strlen(s);\n¬ printf(\" Actual size is: %zu\\n\", trueLen);\n¬ printf(\"First & Last 20 digits: %.20s…%s\\n\", s, s + trueLen - 20);\n¬ }\n¬ return 0;\n¬ }" fn StringWriteToURL( gmpStr, fn URLFileURLWithPath( sourcePath ), YES, NSUTF8StringEncoding, NULL ) TaskRef task = fn TaskInit TaskSetExecutableURL( task, fn URLFileURLWithPath( @"usr/bin/clang" ) ) CFArrayRef arguments = @[@"-o", executablePath, sourcePath, @"-lgmp", @"-fobjc-arc"] TaskSetArguments( task, arguments ) PipeRef pipe = fn PipeInit TaskSetStandardInput( task, pipe ) fn TaskLaunch( task, NULL ) TaskWaitUntilExit( task ) if ( fn TaskTerminationStatus( task ) == 0 ) TaskRef executionTask = fn TaskInit TaskSetExecutableURL( executionTask, fn URLFileURLWithPath( executablePath ) ) PipeRef executionPipe = fn PipeInit TaskSetStandardOutput( executionTask, executionPipe ) FileHandleRef executionFileHandle = fn PipeFileHandleForReading( executionPipe ) fn TaskLaunch( executionTask, NULL ) TaskWaitUntilExit( executionTask ) CFDataRef outputData = fn FileHandleReadDataToEndOfFile( executionFileHandle, NULL ) CFStringRef outputStr = fn StringWithData( outputData, NSUTF8StringEncoding ) NSLog( @"%@", outputStr ) else alert 1,, @"GMP required but not installed" end if fn FileManagerRemoveItemAtURL( fn URLFileURLWithPath( sourcePath ) ) fn FileManagerRemoveItemAtURL( fn URLFileURLWithPath( executablePath ) )end fnfn GMPoutputHandleEvents
GMP says size is: 183231 Actual size is: 183231First & Last 20 digits: 62060698786608744707…92256259918212890625
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.
Programs in Fōrmulæ are created/edited online in itswebsite.
Inthis page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.
Solution
In the following script, the result is converted to a string, in order to calculate its size, and its first/last digits.
n:=5^(4^(3^2));;s:=String(n);;m:=Length(s);# 183231s{[1..20]};# "62060698786608744707"s{[m-19..m]};# "92256259918212890625"
Usingmath/big
'sInt.Exp
.
packagemainimport("fmt""math/big")funcmain(){x:=big.NewInt(2)x=x.Exp(big.NewInt(3),x,nil)x=x.Exp(big.NewInt(4),x,nil)x=x.Exp(big.NewInt(5),x,nil)str:=x.String()fmt.Printf("5^(4^(3^2)) has %d digits: %s ... %s\n",len(str),str[:20],str[len(str)-20:],)}
5^(4^(3^2)) has 183231 digits: 62060698786608744707 ... 92256259918212890625
5 4 3 2??? # Calculate 5^(4^(3^2))`.. # Convert to string and make two copies20<p # Print the first 20 digits-20>p # Print the last 20 digits,p # Print the length
Thep command prints the top element from the stack, so the output of this program is just three lines:
"62060698786608744707""92256259918212890625"183231
Solution:
defbigNumber=5G**(4**(3**2))
Test:
defbigString=bigNumber.toString()assertbigString[0..<20]=="62060698786608744707"assertbigString[-20..-1]=="92256259918212890625"printlnbigString.size()
183231
Haskell comes with built-in support for arbitrary precision integers. The type of arbitrary precision integers isInteger.
main::IO()main=dolety=show(5^4^3^2)letl=lengthyputStrLn("5**4**3**2 = "++take20y++"..."++drop(l-20)y++" and has "++showl++" digits")
5**4**3**2 = 62060698786608744707...92256259918212890625 and has 183231 digits
=+ big=(pow 5 (pow 4 (pow 3 2))) =+ digits=(lent (skip <big> |=(a/* ?:(=(a '.') & |)))) [digits (div big (pow 10 (sub digits 20))) (mod big (pow 10 20))]
[183.231 62.060.698.786.608.744.707 92.256.259.918.212.890.625]
As of 23 July 2016, the standard library lacks a base-10 logarithm, so the length is computed by pretty-printing the number and counting the length of the resulting string without grouping dots.
Both Icon and Unicon have built-in support for bignums.
Note: It takes far longer to convert the result to a string than it does to do the computation itself.
proceduremain()x:=5^4^3^2write("done with computation")x:=string(x)write("5 ^ 4 ^ 3 ^ 2 has ",*x," digits")write("The first twenty digits are ",x[1+:20])write("The last twenty digits are ",x[0-:20])end
->apdone with computation5 ^ 4 ^ 3 ^ 2 has 183231 digitsThe first twenty digits are 62060698786608744707The last twenty digits are 92256259918212890625->
J has built-in support for extended precision integers. See alsoJ:Essays/Extended Precision Functions.
Pow5432=:5^4^3^2xPow5432=:^/5432xNB. alternate J solution#":Pow5432NB. number of digits18323120({.,'...',-@[{.])":Pow5432NB. 20 first & 20 last digits62060698786608744707...92256259918212890625
Java library'sBigInteger class provides support for arbitrary precision integers.
importjava.math.BigInteger;classIntegerPower{publicstaticvoidmain(String[]args){BigIntegerpower=BigInteger.valueOf(5).pow(BigInteger.valueOf(4).pow(BigInteger.valueOf(3).pow(2).intValueExact()).intValueExact());Stringstr=power.toString();intlen=str.length();System.out.printf("5**4**3**2 = %s...%s and has %d digits%n",str.substring(0,20),str.substring(len-20),len);}}
5**4**3**2 = 62060698786608744707...92256259918212890625 and has 183231 digits
The ECMA-262 JavaScript standard now defines a BigInt[3] type for for abitrary precision integers.
BigInt is already implemented by Chrome and Firefox, but not yet by Explorer or Safari.
>>> const y = (5n**4n**3n**2n).toString();>>> console.log(`5**4**3**2 = ${y.slice(0,20)}...${y.slice(-20)} and has ${y.length} digits`);5**4**3**2 = 62060698786608744707...92256259918212890625 and has 183231 digits
Works with gojq, the Go implementation of jq
There is a BigInt.jq library for jq, but gojq, the Go implementation of jq, supports unbounded-precision integer arithmetic, so the output shown below is that produced by gojq.
def power($b): . as $in | reduce range(0;$b) as $i (1; . * $in); 5|power(4|power(3|power(2))) | tostring| .[:20], .[-20:], length
6206069878660874470792256259918212890625183231
Julia includes built-in support for arbitrary-precision arithmetic using theGMP (integer) andGNU MPFR (floating-point) libraries, wrapped by the built-inBigInt
andBigFloat
types, respectively.
julia>@elapsedbigstr=string(BigInt(5)^4^3^2)0.017507363julia>length(bigstr)183231julia>bigstr[1:20]"62060698786608744707"julia>bigstr[end-19:end]"92256259918212890625"
n::$5^4^3^2 .p("5^4^3^2 = ",(20#n),"...",((-20)#n)," and has ",($#n)," digits")
5^4^3^2 = 62060698786608744707...92256259918212890625 and has 183231 digits
importjava.math.BigIntegerfunmain(args:Array<String>){valx=BigInteger.valueOf(5).pow(Math.pow(4.0,3.0*3.0).toInt())valy=x.toString()vallen=y.lengthprintln("5^4^3^2 = ${y.substring(0, 20)}...${y.substring(len - 20)} and has $len digits")}
5^4^3^2 = 62060698786608744707...92256259918212890625 and has 183231 digits
Just using Javascript's BigInt
{defN{BI.**5{BI.**4{BI.**32}}}}->Nlength:{defL{W.length{N}}}->L=18323120firstdigits:{W.slice020{N}}->6206069878660874470720lastdigits:{W.slice-20{L}{N}}->92256259918212890625
Arbitrary precision is native in langur.
val xs = string(5 ^ 4 ^ 3 ^ 2)writeln len(xs), " digits"if len(xs) > 39 and s2s(xs, of=1..20) == "62060698786608744707" and s2s(xs, of=-20 .. -1) == "92256259918212890625" { writeln "SUCCESS"}
183231 digitsSUCCESS
Interestingly, we have to define our own method for integer powers.
defineinteger->pow(factor::integer)=>{#factor<=0?return0local(retVal)=1loop(#factor)=>{#retVal*=self}return#retVal}local(bigint)=string(5->pow(4->pow(3->pow(2))))#bigint->sub(1,20)+` ... `+#bigint->sub(#bigint->size-19)"\n"`Number of digits: `+#bigint->size
62060698786608744707 ... 92256259918212890625Number of digits: 183231
Interestingly this takes a LONG time in LB.
It takes however only seconds in RunBASIC, which is written by the same author, shares most of LB's syntax, and is based on later Smalltalk implementation.
Note the brackets are needed to enforce the desired order of exponentiating.
a$ = str$( 5^(4^(3^2))) print len( a$)print left$( a$, 20); "......"; right$( a$, 20)
18323162060698786608744707......92256259918212890625
Pure/native off-the-shelf Lua does not include support for arbitrary-precision arithmetic. However, there are a number of optional libraries that do, including several from an author of the language itself - one of which this example will use. (citing the "..may be used instead" allowance)
bc=require("bc")-- since 5$=5^4$, and IEEE754 can handle 4$, this would be sufficient:-- n = bc.pow(bc.new(5), bc.new(4^3^2))-- but for this task:n=bc.pow(bc.new(5),bc.pow(bc.new(4),bc.pow(bc.new(3),bc.new(2))))s=n:tostring()print(string.format("%s...%s (%d digits)",s:sub(1,20),s:sub(-20,-1),#s))
62060698786608744707...92256259918212890625 (183231 digits)
Integer Power accept 4 digits the most. So we get z as the number of power then we get z1 the times of multiplications (256-1) per number^1024So now we can stop the execution by pressing Esc.
modulecheckit{z=4^(3^2)z1=z/1024-1m=Biginteger("5")withm,"ToString"asm.ToStringp=Biginteger("1024")methodm,"intpower",pasm1m=m1fori=1toz1methodm1,"multiply",masm?len(m.tostring),irefreshnexta=m.tostringPrintleft$(a,20)+"..."+Right$(a,20)}checkit
.............. 182516 254 183231 25562060698786608744707...92256259918212890625
Maple supports large integer arithmetic natively.
> n := 5^(4^(3^2)):> length( n ); # number of digits 183231> s := convert( n, 'string' ):> s[ 1 .. 20 ], s[ -20 .. -1 ]; # extract first and last twenty digits "62060698786608744707", "92256259918212890625"
In the Maple graphical user interface it is also possible to set things up so that only (say) the first and last 20 digits of a large integer are displayed explicitly. This is done as follows.
> interface( elisiondigitsbefore = 20, elisiondigitsafter = 20 ):> 5^(4^(3^2)): 62060698786608744707[...183191 digits...]92256259918212890625
Mathematica can handle arbitrary precision integers on almost any size without further declarations.To view only the first and last twenty digits:
s:=ToString[5^4^3^2];Print[StringTake[s,20]<>"..."<>StringTake[s,-20]<>" ("<>ToString@StringLength@s<>" digits)"];
62060698786608744707...92256259918212890625 (183231 digits)
Using theVariable Precision Integer library this task is accomplished thusly:
>>answer=vpi(5)^(vpi(4)^(vpi(3)^vpi(2)));>>numDigits=order(answer)+1numDigits=183231>>[sprintf('%d',leadingdigit(answer,20))'...'sprintf('%d',trailingdigit(answer,20))]%First and Last 20 Digitsans=62060698786608744707...92256259918212890625
block([s,n],s:string(5^4^3^2),n:slength(s),print(substring(s,1,21),"...",substring(s,n-19)),n);/* 62060698786608744707...92256259918212890625183231 */
Integer values are arbitrary-precision by default in Nanoquery.
value = str(5^(4^(3^2)))first20 = value.substring(0,20)last20 = value.substring(len(value) - 20)println "The first twenty digits are " + first20println "The last twenty digits are " + last20if (first20 = "62060698786608744707") && (last20 = "92256259918212890625")println "\nThese digits are correct.\n"endprintln "The result is " + len(str(value)) + " digits long"
The first twenty digits are 62060698786608744707The last twenty digits are 92256259918212890625These digits are correct.The result is 183231 digits long
usingSystem.Console;usingSystem.Numerics;usingSystem.Numerics.BigInteger;moduleBigInt{Main():void{defn=Pow(5,Pow(4,Pow(3,2):>int):>int).ToString();deflen=n.Length;deffirst20=n.Substring(0,20);deflast20=n.Substring(len-20,20);assert(first20=="62060698786608744707","High order digits are incorrect");assert(last20=="92256259918212890625","Low order digits are incorrect");assert(len==183231,"Result contains wrong number of digits");WriteLine("Result: {0} ... {1}",first20,last20);WriteLine($"Length of result:$len digits");}}
Output:
Result: 62060698786608744707 ... 92256259918212890625Length of result: 183231 digits
=
;;;No built-in big integer exponentiation(define(exp-bigxn)(setqx(bigintx))(let(y1L)(if(=n0)1L(while(>n1)(if(odd?n)(setqy(*xy)))(setqx(*xx)n(/n2)))(*xy))));;;; task(define(test)(local(res);drop the "L" at the end(setqres(0(-(lengthres)1)(string(exp-big5(exp-big4(exp-big32))))))(println"The result has: "(lengthres)" digits")(println"First 20 digits: "(020res))(println"Last 20 digits: "(-2020res))))
The result has: 183231 digitsFirst 20 digits: 62060698786608744707Last 20 digits: 92256259918212890625
/* NetRexx */optionsreplaceformatcommentsjavacrossrefsavelogsymbolsimportjava.math.BigIntegernumericdigits30--neededtoreporttherun-timenanoFactor=10**9t1=System.nanoTimex=BigInteger.valueOf(5)x=x.pow(BigInteger.valueOf(4).pow(BigInteger.valueOf(3).pow(2).intValue()).intValue())n=Rexx(x.toString)t2=System.nanoTimetd=t2-t1say"Run time in seconds:"td/nanoFactorsaycheck="62060698786608744707...92256259918212890625"sample=n.left(20)"..."n.right(20)say"Expected result:"checksay" Actual result:"samplesay" digits:"n.lengthsayifcheck=samplethensay"Result confirmed"elsesay"Result does not satisfy test"return
Run time in seconds: 6.696671 Expected result: 62060698786608744707...92256259918212890625 Actual result: 62060698786608744707...92256259918212890625 digits: 183231 Result confirmed
/* NetRexx */optionsreplaceformatcommentsjavacrossrefsavelogsymbolsimportjava.math.BigDecimalnumericdigits30--neededtoreporttherun-timenanoFactor=10**9t1=System.nanoTimex=BigDecimal.valueOf(5)x=x.pow(BigDecimal.valueOf(4).pow(BigDecimal.valueOf(3).pow(2).intValue()).intValue())n=Rexx(x.toString)t2=System.nanoTimetd=t2-t1say"Run time in seconds:"td/nanoFactorsaycheck="62060698786608744707...92256259918212890625"sample=n.left(20)"..."n.right(20)say"Expected result:"checksay" Actual result:"samplesay" digits:"n.lengthsayifcheck=samplethensay"Result confirmed"elsesay"Result does not satisfy test"return
Run time in seconds: 7.103424 Expected result: 62060698786608744707...92256259918212890625 Actual result: 62060698786608744707...92256259918212890625 digits: 183231 Result confirmed
LikeRexx, NetRexx comes with built-in support for numbers that can be manually set to very large values of precision.Compared to the two methods shown above however, the performance is extremely poor.
/* NetRexx */optionsreplaceformatcommentsjavacrossrefsavelogsymbols/* precision must be set manually */numericdigits190000nanoFactor=10**9t1=System.nanoTimen=5**(4**(3**2))t2=System.nanoTimetd=t2-t1say"Run time in seconds:"td/nanoFactorsaycheck="62060698786608744707...92256259918212890625"sample=n.left(20)"..."n.right(20)say"Expected result:"checksay" Actual result:"samplesay" digits:"n.lengthsayifcheck=samplethensay"Result confirmed"elsesay"Result does not satisfy test"
Run time in seconds: 719.660995Expected result: 62060698786608744707...92256259918212890625 Actual result: 62060698786608744707...92256259918212890625 digits: 183231Result confirmed
# Solution for https://rosettacode.org/wiki/Arbitrary-precision_integers_(included)importbigintsimportstd/mathvarx=5.initBigInt.pow4^(3^2)vars=$xechos[0..19]echos[s.high-19..s.high]echos.len
Output:
6206069878660874470792256259918212890625183231
openNumopenStropenStringlet()=letanswer=(Int5)**/(Int4)**/(Int3)**/(Int2)inletanswer_string=string_of_numanswerinPrintf.printf"has %d digits: %s ... %s\n"(lengthanswer_string)(first_charsanswer_string20)(last_charsanswer_string20)
A more readable program can be obtained usingDelimited Overloading:
let()=letanswer=Num.(5**4**3**2)inlets=Num.(to_stringanswer)inPrintf.printf"has %d digits: %s ... %s\n"(String.lengths)(Str.first_charss20)(Str.last_charss20)
has 183231 digits: 62060698786608744707 ... 92256259918212890625
Oforth handles arbitrary precision integers :
import: mapping5 4 3 2 pow pow pow >string dup left( 20 ) . dup right( 20 ) . size .
62060698786608744707 92256259918212890625 183231
(definex(expt5(expt4(expt32))))(print(divx(expt10(-(log10x)20)))"..."(modx(expt1020)))(print"totally digits: "(log10x))
62060698786608744707...92256259918212890625totally digits: 183231
--REXXprogramtoshowarbitraryprecisionintegers.numericdigits200000check='62060698786608744707...92256259918212890625'start=.datetime~newn=5**(4**(3**2))time=.datetime~new-startsay'elapsed time for the calculation:'timesaysampl=left(n,20)"..."right(n,20)say' check:'checksay'Sample:'samplsay'digits:'length(n)sayifcheck=samplthensay'passed!'elsesay'failed!'
prompt$ rexx rexx-arbitrary.rexxelapsed time for the calculation: 00:00:45.373140 check: 62060698786608744707...92256259918212890625Sample: 62060698786608744707...92256259918212890625digits: 183231passed!
declare Pow5432 = {Pow 5 {Pow 4 {Pow 3 2}}} S = {Int.toString Pow5432} Len = {Length S}in {System.showInfo {List.take S 20}#"..."# {List.drop S Len-20}#" ("#Len#" Digits)"}
62060698786608744707...92256259918212890625 (183231 Digits)
PARI/GP natively supports integers of arbitrary size, so one could just useN=5^4^3^2
. But this would be foolish (using a lot of unneeded memory) if the task is to get just the number of, and the first and last twenty digits. The number of and the leading digits are given as 1 + the integer part, resp. 10^(fractional part + offset), of the logarithm to base 10 (not as log(N) with N=A^B, but as B*log(A); one needs at least 20 correct decimals of the log, on 64 bit machines the default precision is 39 digits, but on 32 bit architecture one should setdefault(realprecision,30)
to be on the safe side). To get the trailing digits, one would use modular exponentiation which is also built-in and very efficient even for extremely huge exponents:
num_first_last_digits(a=5,b=4^3^2,n=20)={ my(L = b*log(a)/log(10), m=Mod(a,10^n)^b);[L\1+1, 10^frac(L)\10^(1-n), lift(m)] \\ where x\y = floor(x/y) but more efficient}print("Length, first and last 20 digits of 5^4^3^2: ", num_first_last_digits()) \\ uses default values a=5, b=4^3^2, n=20
Length, first and last 20 digits of 5^4^3^2: [183231, 62060698786608744707, 92256259918212890625]
If an integer is already given, thenlogint(N,10)+1
is the most efficient way to get its number of digits.
An alternate but much slower method for counting decimal digits is#Str(n)
. Note thatsizedigit
is not exact—in particular, it may be off by one (thus the function below).
digits(x)={my(s=sizedigit(x)-1);if(x<10^s,s,s+1)};N=5^(4^(3^2));[precision(N*1.,20), Mod(N,10^20), digits(N)]
[6.20606987866087447074832055728 E183230, Mod(92256259918212890625, 100000000000000000000), 183231]
FreePascal comes with a header unit for gmp. Starting from the C program, this is a Pascal version:
programGMP_Demo;usesmath,gmp;vara:mpz_t;out:pchar;len:longint;i:longint;beginmpz_init_set_ui(a,5);mpz_pow_ui(a,a,4**(3**2));len:=mpz_sizeinbase(a,10);writeln('GMP says size is: ',len);out:=mpz_get_str(NIL,10,a);writeln('Actual size is: ',length(out));write('Digits: ');fori:=0to19dowrite(out[i]);write('...');fori:=len-20tolendowrite(out[i]);writeln;end.
GMP says size is: 183231Actual size is: 183231Digits: 62060698786608744707...92256259918212890625
beginvarresult:string:=power(5bi,integer(power(4,power(3,2)))).tostring;result[1:21].Println;result[result.Length-19:].Println;result.Length.Println;end.
6206069878660874470792256259918212890625183231
Perl'sMath::BigInt core module handles big integers:
useMath::BigInt;my$x=Math::BigInt->new('5')**Math::BigInt->new('4')**Math::BigInt->new('3')**Math::BigInt->new('2');my$y="$x";printf("5**4**3**2 = %s...%s and has %i digits\n",substr($y,0,20),substr($y,-20),length($y));
You can enable "transparent" big integer support by enabling thebigint pragma:
usebigint;my$x=5**4**3**2;my$y="$x";printf("5**4**3**2 = %s...%s and has %i digits\n",substr($y,0,20),substr($y,-20),length($y));
Math::BigInt is very slow. Perl 5.10 was about 120 times slower than Ruby 1.9.2 (on one computer); Perl used more than one minute, but Ruby used less than one second.
$timeperltransparent-bigint.pl5**4**3**2=62060698786608744707...92256259918212890625andhas183231digits1m4.28sreal1m4.30suser0m0.00ssystem
withjavascript_semanticsincludempfr.eatomt0=time()mpzres=mpz_init()mpz_ui_pow_ui(res,5,power(4,power(3,2)))strings=mpz_get_short_str(res),e=elapsed(time()-t0)printf(1,"5^4^3^2 = %s (%s)\n",{s,e})
5^4^3^2 = 62060698786608744707...92256259918212890625 (183,231 digits) (0.1s)
PHP has two separate arbitrary-precision integer services.
The first is the BC library.[4] It represents the integers as strings, so may not be very efficient. The advantage is that it is more likely to be included with PHP.
<?php$y=bcpow('5',bcpow('4',bcpow('3','2')));printf("5**4**3**2 = %s...%s and has %d digits\n",substr($y,0,20),substr($y,-20),strlen($y));?>
5**4**3**2 = 62060698786608744707...92256259918212890625 and has 183231 digits
The second is the GMP library.[5] It represents the integers as an opaque type, so may be faster. However, it is less likely to be compiled into your version of PHP (it isn't compiled into mine).
main => X = to_string(5**4**3**2), Y = len(X), println("Result: "), print("Number of digits: "), println(Y), println("First 20 digits: " ++ X[1..20]), println("Last 20 digits: " ++ X[Y-19..Y]).
(let L (chop (** 5 (** 4 (** 3 2)))) (prinl (head 20 L) "..." (tail 20 L)) (length L) )
62060698786608744707...92256259918212890625-> 183231
>stringres=(string)pow(5,pow(4,pow(3,2)));>res[..19]=="62060698786608744707";Result:1>res[<19..]=="92256259918212890625";Result:1>sizeof(result);Result:183231
Works but took 107 seconds on my machine (core i7) to do so.
localbigint=require"bigint"localfmt=require"fmt"localp=bigint.new(3)^bigint.new(2)p=bigint.new(4)^pp=bigint.new(5)^plocals=p:tostring()fmt.print("5 ^ 4 ^ 3 ^ 2 has %s digits.\n",fmt.int(#s))print("The first twenty and last twenty are: ")print(fmt.abridge(s,20))
5 ^ 4 ^ 3 ^ 2 has 183,231 digits.The first twenty and last twenty are: 62060698786608744707...92256259918212890625
# Perform calculation$BigNumber=[BigInt]::Pow(5,[BigInt]::Pow(4,[BigInt]::Pow(3,2)))# Display first and last 20 digits$BigNumberString=[string]$BigNumber$BigNumberString.Substring(0,20)+"..."+$BigNumberString.Substring($BigNumberString.Length-20,20)# Display number of digits$BigNumberString.Length
62060698786608744707...92256259918212890625183231
importjava.math.BigInteger;// Variable definitionsBigInteger_5,_4,powResult;_5=BigInteger.valueOf(5);_4=BigInteger.valueOf(4);//calculationspowResult=_5.pow(_4.pow(9).intValueExact());StringpowStr=powResult.toString();intpowLen=powStr.length();StringpowStrStart=powStr.substring(0,20);StringpowStrEnd=powStr.substring(powLen-20);//outputSystem.out.printf("5**4**3**2 = %s...%s and has %d digits%n",powStrStart,powStrEnd,powLen);
5**4**3**2 = 62060698786608744707...92256259918212890625 and has 183231 digits
task(Length):-Nis5^4^3^2,number_codes(N,Codes),append(`62060698786608744707`,_,Codes),append(_,`92256259918212890625`,Codes),length(Codes,Length).
Query like so:
?-task(N).N=183231;false.
PureBasic has in its current version (today 4.50) no internal support for large numbers, but there are several free libraries for this.
UsingDecimal.pbi, e.g. the same included library as inLong multiplication#PureBasic, this task is solved as below.
IncludeFile"Decimal.pbi";-DeclarethevariablesthatwillbeusedDefine.Decimal*aDefinen,L$,R$,out$,digits.s;-4^3^2iswithing32bitrange,sonormalprocedurescanbeusedn=Pow(4,Pow(3,2));-5^nislargerthen31^2,sothesamelibrarycallasinthe"Long multiplication"taskisused*a=PowerDecimal(IntegerToDecimal(5),IntegerToDecimal(n));-Convertthelargenumberintoastring&presenttheresultsout$=DecimalToString(*a)L$=Left(out$,20)R$=Right(out$,20)digits=Str(Len(out$))out$="First 20 & last 20 chars of 5^4^3^2 are;"+#CRLF$+L$+#CRLF$+R$+#CRLF$out$+"and the result is "+digits+" digits long."MessageRequester("Arbitrary-precision integers, PureBasic",out$)
Python comes with built-in support for arbitrary precision integers. The type of arbitrary precision integers islong in Python 2.x (overflowing operations onint's are automatically converted intolong's), andint in Python 3.x.
>>>y=str(5**4**3**2)>>>print("5**4**3**2 =%s...%s and has%i digits"%(y[:20],y[-20:],len(y)))5**4**3**2=62060698786608744707...92256259918212890625andhas183231digits
As a dialogue in the Quackery shell. (REPL)
> quackeryWelcome to Quackery.Enter "leave" to leave the shell./O> 5 4 3 2 ** ** **... number$ dup 20 split swap echo$... say "..." -20 split echo$ drop cr... size echo say " digits" cr... 62060698786608744707...92256259918212890625183231 digitsStack empty./O>
R does not come with built-in support for arbitrary precision integers, but it can be implemented with the GMP library.
library(gmp)large<-pow.bigz(5,pow.bigz(4,pow.bigz(3,2)))largestr<-as.character(large)cat("first 20 digits:",substr(largestr,1,20),"\n","last 20 digits:",substr(largestr,nchar(largestr)-19,nchar(largestr)),"\n","number of digits: ",nchar(largestr),"\n")
first 20 digits: 62060698786608744707 last 20 digits: 92256259918212890625 number of digits: 183231
#langracket(defineanswer(number->string(foldrexpt1'(5432))))(definelen(string-lengthanswer))(printf"Got ~a digits~n"len)(printf"~a ... ~a~n"(substringanswer020)(substringanswer(-len20)len))
Got 183231 digits62060698786608744707 ... 92256259918212890625
(formerly Perl 6)
given [**]5,4,3,2 {useTest;ok /^62060698786608744707<digit>*92256259918212890625$/,'5**4**3**2 has expected first and last twenty digits';printf'This number has %d digits', .chars;}
ok 1 - 5**4**3**2 has expected first and last twenty digitsThis number has 183231 digits
$ENTRY Go { , <Pow (5) <Pow (4) <Pow (3) 2>>>: e.X , <Symb e.X>: e.Y , <First 20 e.Y>: (e.DF) e.1 , <Last 20 e.Y>: (e.2) e.DL , <Lenw e.Y>: s.L e.Y = <Prout e.DF '...' e.DL> <Prout 'Length: ' s.L>;}Pow { (e.N) 0 = 1; (e.N) e.P, <Divmod (e.P) 2>: { (e.P2) 0, <Pow (e.N) e.P2>: e.X = <Mul (e.X) e.X>; (e.P2) 1, <Pow (e.N) e.P2>: e.X = <Mul (e.N) <Mul (e.X) e.X>>; };};
62060698786608744707...92256259918212890625Length: 183231
REXX comes with built-in support for fixed precision integers that can be manually set to a large value of precision (digits).
Most REXXes have a practical limit of around eight million bytes, but that is mostly an underlying limitation of addressing virtual storage.
Note: both REXX versions (below) don't work with:
as those REXX versions have a practical maximum of around3,700 or less fornumeric digits (officially, it's4K).
The3,700 limit is based on the setting of RXISA, program size, and the amount of storage used by REXX variables.
Both (below) REXX programs have been tested with:
/*REXX program calculates and demonstrates arbitrary precision numbers (using powers). */numericdigits200000/*two hundred thousand decimal digits. */#=5**(4**(3**2))/*calculate multiple exponentiations. */true=62060698786608744707...92256259918212890625/*what answer is supposed to look like.*/rexx=left(#,20)'...'right(#,20)/*the left and right 20 decimal digits.*/say' true:'true/*show what the "true" answer is. */say' REXX:'rexx/* " " " REXX " " */say'digits:'length(#)/* " " " length of answer is. */sayiftrue==rexxthensay'passed!'/*either it passed, ··· */elsesay'failed!'/* or it didn't. *//*stick a fork in it, we're all done. */
check: 62060698786608744707...92256259918212890625sample: 62060698786608744707...92256259918212890625digits: 183231passed!
/*REXX program calculates and demonstrates arbitrary precision numbers (using powers). */numericdigits5/*just use enough digits for 1st time. */#=5**(4**(3**2))/*calculate multiple exponentiations. */parsevar#'E'pow./*POW might be null, so N is OK. */ifpow\==''thendo/*general case: POW might be < zero.*/numericdigitsabs(pow)+9/*recalculate with more decimal digits.*/#=5**(4**(3**2))/*calculate multiple exponentiations. */end/* [↑] calculation is the real McCoy. */true=62060698786608744707...92256259918212890625/*what answer is supposed to look like.*/rexx=left(#,20)'...'right(#,20)/*the left and right 20 decimal digits.*/say' true:'true/*show what the "true" answer is. */say' REXX:'rexx/* " " " REXX " " */say'digits:'length(#)/* " " " length of answer is. */sayiftrue==rexxthensay'passed!'/*either it passed, ··· */elsesay'failed!'/* or it didn't. *//*stick a fork in it, we're all done. */
def bignum : 5**4**3**2def num_length : to_string(bignum).length()num_lengthto_string(bignum).substring(..20)to_string(bignum).substring(num_length-20..num_length)
183231"62060698786608744707""92256259918212890625"
Ruby comes with built-in support for arbitrary precision integers.
y=(5**4**3**2).to_sputs"5**4**3**2 =#{y[0..19]}...#{y[-20..-1]} and has#{y.length} digits"
5**4**3**2 = 62060698786608744707...92256259918212890625 and has 183231 digits
x$ = str$( 5^(4^(3^2))) print "Length:";len( x$)print left$( x$, 20); "......"; right$( x$, 20)
Length:18323162060698786608744707......92256259918212890625
This is accomplished via the `num` crate. This used to be part of the standard library, but was relegated to an external crate when Rust hit 1.0. It is still owned and maintained by members of the Rust core team and is the de-facto library for numerical generics and arbitrary precision arithmetic.
externcratenum;usenum::bigint::BigUint;usenum::FromPrimitive;usenum::pow::pow;fnmain(){letbig=BigUint::from_u8(5).unwrap();letanswer_as_string=format!("{}",pow(big,pow(4,pow(3,2))));// The rest is output formatting.letfirst_twenty:String=answer_as_string.chars().take(20).collect();letlast_twenty_reversed:Vec<char>=answer_as_string.chars().rev().take(20).collect();letlast_twenty:String=last_twenty_reversed.into_iter().rev().collect();println!("Number of digits: {}",answer_as_string.len());println!("First and last digits: {:?}..{:?}",first_twenty,last_twenty);}
Number of digits: 183231First and last digits: "62060698786608744707".."92256259918212890625"
class MAIN is main is r:INTI; p1 ::= "62060698786608744707"; p2 ::= "92256259918212890625"; -- computing 5^(4^(3^2)), it could be written -- also e.g. (5.inti)^((4.inti)^((3.inti)^(2.inti))) r := (3.pow(2)).inti; r := (4.inti).pow(r); r := (5.inti).pow(r); sr ::= r.str; -- string rappr. of the number if sr.head(p1.size) = p1 and sr.tail(p2.size) = p2 then #OUT + "result is ok..\n"; else #OUT + "oops\n"; end; #OUT + "# of digits: " + sr.size + "\n"; end;end;
result is ok..# of digits: 183231
Scala does not come with support for arbitrary precision integers powered to arbitrary precision integers, except if performed on a module. It can use arbitrary precision integers in other ways, including powering them to 32-bits integers.
scala>BigInt(5)modPow(BigInt(4)pow(BigInt(3)pow2).toInt,BigInt(10)pow20)res21:scala.math.BigInt=92256259918212890625scala>(BigInt(5)pow(BigInt(4)pow(BigInt(3)pow2).toInt).toInt).toStringres22:String=6206069878660874470748320557284679309194219265199117173177383244784468904205446208395532859313213494850352537703036636839828417945902879392179078964130015628130561306487423619895511492129692248763240674232665969222856219538746210423235340883954495598715281862895110697243759768434501295076608139350684049011911606999299265680993012599382719755265877195653099952764389980932831750802415583322472485597797001511259412892659458720566242186172378900120827518429339991013912158886504596553858675842231519094813553261073608575593794241686443569888058927325243163232494924205126409626916731046183783815452026387714010611719680528732141494546392505589930793377490407881991138732421797631123887580287831048303725533789567769926391314746986316354035923183981697660495275234703657750678459919...scala>res22take20res23:String=62060698786608744707scala>res22lengthres24:Int=183231scala>
R4RS andR5RS encourage, andR6RS requires, that exact integers be of arbitrary precision.
(definex(expt5(expt4(expt32))))(definey(number->stringx))(definel(string-lengthy))(display(string-append"5**4**3**2 = "(substringy020)"..."(substringy(-l20)l)" and has "(number->stringl)" digits"))(newline)
5**4**3**2 = 62060698786608744707...92256259918212890625 and has 183231 digits
$ include "seed7_05.s7i"; include "bigint.s7i";const proc: main is func local var bigInteger: fiveToThePowerOf262144 is 5_ ** 4 ** 3 ** 2; var string: numberAsString is str(fiveToThePowerOf262144); begin writeln("5**4**3**2 = " <& numberAsString[..20] <& "..." <& numberAsString[length(numberAsString) - 19 ..]); writeln("decimal digits: " <& length(numberAsString)); end func;
5**4**3**2 = 62060698786608744707...92256259918212890625decimal digits: 183231
program p_5432; x := 5 ** 4 ** 3 ** 2; y := str x; print("First 20 digits: ", y(1..20)); print("Last 20 digits: ", y(#y-19..#y)); print("Amount of digits:", #y);end program;
First 20 digits: 62060698786608744707Last 20 digits: 92256259918212890625Amount of digits: 183231
varx=5**(4**(3**2))vary=x.to_sprintf("5**4**3**2 = %s...%s and has %i digits\n",y.first(20),y.last(20),y.len)
5**4**3**2 = 62060698786608744707...92256259918212890625 and has 183231 digits
This example isincomplete. Number of digits in result not given. Please ensure that it meets all task requirements and remove this message. |
SIMPOL supports arbitrary precision integers powered to arbitrary precision integers. This is the only integer data type in SIMPOL. SIMPOL supports conversion from its integer data type to other formats when calling external library functions.
constant FIRST20 "62060698786608744707"constant LAST20 "92256259918212890625"function main() integer i string s, s2 i = .ipower(5, .ipower(4, .ipower(3, 2))) s2 = .tostr(i, 10) if .lstr(s2, 20) == FIRST20 and .rstr(s2, 20) == LAST20 s = "Success! The integer matches both the first 20 and the last 20 digits. There are " + .tostr(.len(s2), 10) + " digits in the result.{d}{a}" else s = "" if .lstr(s2, 20) != FIRST20 s = "Failure! The first 20 digits are: " + .lstr(s2, 20) + " but they should be: " + FIRST20 + "{d}{a}" end if if .rstr(s2, 20) != LAST20 s = s + "Failure! The first 20 digits are: " + .lstr(s2, 20) + " but they should be: " + LAST20 + "{d}{a}" end if end ifend function s
This code in Squeak Smalltalk ¹ returns a string containing the first 20 digits, last 20 digits and length of the result.
A very simple approach:
|num|num:= (5raisedTo: (4raisedTo: (3raisedTo:2)))asString.Transcriptshow: (numfirst:20),'...', (numlast:20);cr;show:'digits: ',numsizeasString.
On a Transcript window:
62060698786608744707...92256259918212890625digits: 183231
And a more advanced one:
|num numstr|num:= (2to:5)fold: [:exp:base|baseraisedTo:exp].numstr:=numasString.'<1s>...<2s> digits:<3p>'expandMacrosWith: (numstrfirst:20)with: (numstrlast:20)with:numstrsize.
'62060698786608744707...92256259918212890625 digits: 183231'
Note 1) should work in all Smalltalk dialects; tried in Smalltalk/X and VisualWorks.
t = #.str(5^(4^(3^2)))n = #.size(t)#.output(n," digits")#.output(#.mid(t,1,20),"...",#.mid(t,n-19,20))
183231 digits62060698786608744707...92256259918212890625
letvalanswer=IntInf.pow(5,IntInf.toInt(IntInf.pow(4,IntInf.toInt(IntInf.pow(3,2)))))vals=IntInf.toStringanswervallen=sizesinprint("has "^Int.toStringlen^" digits: "^substring(s,0,20)^" ... "^substring(s,len-20,20)^"\n")end;
it took too long to run
mLite does not have a logarithm function so one was constructed (see fun log10)
funntol(0,x)=iflenx<1then[0]elsex|(n,x)=ntol(ndiv10,(nmod10)::x)|n=ntol(n,[])andpowers_of_109=1000000000|8=100000000|7=10000000|6=1000000|5=100000|4=10000|3=1000|2=100|1=10|0=1andsize(c,0)=c|(c,n>9999999999)=size(c+10,trunc(n/10000000000))|(c,n)=size(c+1,trunc(n/10))|n=size(0,trunc(n/10))andmakeVisibleL=map(fnx=ifintxthenchr(x+48)elsex)Landlog10(n,0,x)=ston`implode`makeVisible`revx|(n,c,x)=letvaln'=n^10;valsize_n'=sizen'inlog10(n'/powers_of_10size_n',c-1,size_n'::x)end|(n,c)=letvalsize_n=sizeninlog10(n/10^size_n,c,#"."::rev(ntolsize_n)@[])end;valfourThreeTwo=4^3^2;valfiveFourThreeTwo=5^fourThreeTwo;valdigitCount=trunc(log10(5,6)*fourThreeTwo+0.5);print"Count = ";printlndigitCount;valend20=fiveFourThreeTwomod(10^20);print"End 20 = ";printlnend20;valtop20=fiveFourThreeTwodiv(10^(digitCount-20));print"Top 20 = ";printlntop20;
Output
Count = 183231 End 20 = 92256259918212890625 Top 20 = 62060698786608744707
Took 1 hour and 9 minutes to run (AMD A6, Windows 10)
Stata does not have builtin support for arbitrary-precision integers. However, since version 16 Stata hasbuiltin support for Python, so arbitrary-precision integers are readily available from a Python prompt within Stata.
Tcl supports arbitrary precision integers (and an exponentiation operator) from 8.5 onwards.
setbigValue[expr{5**4**3**2}]puts"5**4**3**2 has [string length $bigValue] digits"if{[stringmatch"62060698786608744707*92256259918212890625"$bigValue]}{puts"Value starts with 62060698786608744707, ends with 92256259918212890625"}else{puts"Value does not match 62060698786608744707...92256259918212890625"}
5**4**3**2 has 183231 digitsValue starts with 62060698786608744707, ends with 92256259918212890625
#langtransdMainModule:{_start:(λlocals:aBigLong(5)ssStringStream()s""(textoutto:ss(powa(pow4(pow32))))(=s(strss))(withlen(sizes)(lout"The number of digits is: "len)(lout(subs020)" ... "(subs(-len20)))))}
The number of digits is: 18323162060698786608744707 ... 92256259918212890625
@(bind (f20 l20 ndig) @(let* ((str (tostring (expt 5 4 3 2))) (len (length str))) (list [str :..20] [str -20..:] len)))@(bind f20 "62060698786608744707")@(bind l20 "92256259918212890625")@(output)@f20...@l20ndigits=@ndig@(end)
62060698786608744707...92256259918212890625ndigits=183231
The Ursa standard library provides the moduleunbounded_int
which contains the definition of theunbounded_int
type. In Cygnus/X Ursa,unbounded_int
is essentially a wrapper forjava.math.BigInteger
import "unbounded_int"decl unbounded_int xx.set ((x.valueof 5).pow ((x.valueof 4).pow ((x.valueof 3).pow 2)))decl string first last xstrset xstr (string x)# get the first twenty digitsdecl int ifor (set i 0) (< i 20) (inc i)set first (+ first xstr<i>)end for# get the last twenty digitsfor (set i (- (size xstr) 20)) (< i (size xstr)) (inc i)set last (+ last xstr<i>)end forout "the first and last digits of 5^(4^(3^2)) are " first "..." consoleout last " (the result was " (size xstr) " digits long)" endl endl consoleif (and (and (= first "62060698786608744707") (= last "92256259918212890625")) (= (size xstr) 183231))out "(pass)" endl consoleelseout "FAIL" endl consoleend if
the first and last digits of 5^(4^(3^2)) are 62060698786608744707...92256259918212890625 (the result was 183231 digits long)(pass)
There are no infix arithmetic operators in the language, but there is apower
function in thebcd
library, which is part of the standard distribution from the home site.
There is no distinction between ordinary and arbitrary precision integers, but the binary converted decimal representation used here is more efficient than the usual binary representation in calculations that would otherwise be dominated by the conversion to decimal output.
#import std#import nat#import bcd#show+main = <.@ixtPX take/$20; ^|T/~& '...'--@x,'length: '--@h+ %nP+ length@t>@h %vP power=> <5_,4_,3_,2_>
With this calculation taking about a day to run, correct results are attainable but not performant.
62060698786608744707...92256259918212890625length: 183231
Addressing the issue of theBigInteger.Pow() function having the exponent value limited toInt32.MaxValue (2147483647), here are a couple of alternative implementations using aBigInteger for the exponent.
ImportsSystem.ConsoleImportsBI=System.Numerics.BigIntegerModuleModule1DimImplems()AsString={"Built-In","Recursive","Iterative"},powers()AsInteger={5,4,3,2}FunctionintPowR(valAsBI,expAsBI)AsBIIfexp=0ThenReturn1DimneAsBI,vsAsBI=val*valIfexp.IsEvenThenne=exp>>1:ReturnIf(ne>1,intPowR(vs,ne),vs)ne=(exp-1)>>1:ReturnIf(ne>1,intPowR(vs,ne),vs)*valEndFunctionFunctionintPowI(valAsBI,expAsBI)AsBIintPowI=1 :While(exp>0):IfNotexp.IsEvenThenintPowI*=valval*=val :exp>>=1:EndWhileEndFunctionSubDoOne(titleAsString,p()AsInteger)DimstAsDateTime=DateTime.Now,resAsBI,resStrAsStringSelectCase(Array.IndexOf(Implems,title))Case0:res=BI.Pow(p(0),CInt(BI.Pow(p(1),CInt(BI.Pow(p(2),p(3))))))Case1:res=intPowR(p(0),intPowR(p(1),intPowR(p(2),p(3))))CaseElse:res=intPowI(p(0),intPowI(p(1),intPowI(p(2),p(3))))EndSelect:resStr=res.ToString()DimetAsTimeSpan=DateTime.Now-stDebug.Assert(resStr.Length=183231)Debug.Assert(resStr.StartsWith("62060698786608744707"))Debug.Assert(resStr.EndsWith("92256259918212890625"))WriteLine("n = {0}",String.Join("^",powers))WriteLine("n = {0}...{1}",resStr.Substring(0,20),resStr.Substring(resStr.Length-20,20))WriteLine("n digits = {0}",resStr.Length)WriteLine("{0} elasped: {1} milliseconds."&vblf,title,et.TotalMilliseconds)EndSubSubMain()ForEachitmAsStringinImplems:DoOne(itm,powers) :NextIfDebugger.IsAttachedThenConsole.ReadKey()EndSubEndModule
n = 5^4^3^2n = 62060698786608744707...92256259918212890625n digits = 183231Built-In elasped: 2487.4002 milliseconds.n = 5^4^3^2n = 62060698786608744707...92256259918212890625n digits = 183231Recursive elasped: 2413.0434 milliseconds.n = 5^4^3^2n = 62060698786608744707...92256259918212890625n digits = 183231Iterative elasped: 2412.5477 milliseconds.
Remarks: Not much difference in execution times for three methods. But the exponents are relatively small. If one does need to evaluate an exponent greater thanInt32.MaxValue, the execution time will be measured in hours.
import math.bigimport mathfn main() { mut x := u32(math.pow(3,2)) x = u32(math.pow(4,x))mut y := big.integer_from_int(5)y = y.pow(x)str := y.str()println("5^(4^(3^2)) has $str.len digits: ${str[..20]} ... ${str[str.len-20..]}")}
5^(4^(3^2)) has 183231 digits: 62060698786608744707 ... 9225625991821289062
import"./fmt"forFmtimport"./big"forBigIntvarp=BigInt.three.pow(BigInt.two)p=BigInt.four.pow(p)p=BigInt.five.pow(p)vars=p.toStringFmt.print("5 ^ 4 ^ 3 ^ 2 has $,d digits.\n",s.count)System.print("The first twenty are :%(s[0..19])")System.print("and the last twenty are :%(s[-20..-1])")
5 ^ 4 ^ 3 ^ 2 has 183,231 digits.The first twenty are : 62060698786608744707and the last twenty are : 92256259918212890625
conststd=@import("std");constbigint=std.math.big.int.Managed;pubfnmain()!void{vara=trybigint.initSet(std.heap.c_allocator,5);trya.pow(&a,trystd.math.powi(u32,4,trystd.math.powi(u32,3,2)));defera.deinit();varas=trya.toString(std.heap.c_allocator,10,.lower);deferstd.heap.c_allocator.free(as);std.debug.print("{s}...{s}\n",.{as[0..20],as[as.len-20..]});std.debug.print("{} digits\n",.{as.len});}
62060698786608744707...92256259918212890625183231 digits
Using the GNU big num library:
var BN=Import("zklBigNum");n:=BN(5).pow(BN(4).pow(BN(3).pow(2)));s:=n.toString();"%,d".fmt(s.len()).println();println(s[0,20],"...",s[-20,*]);
183,23162060698786608744707...92256259918212890625