Calculation Pi^Pi^Pi in hexadecimal in High precision

Hello!
I have a math question.

In Wolfram Language I can type this:
BaseForm[N[Pi^Pi^Pi, 100000], 16]

and get VERY FAST the result of up to 100,000 hexadecimal digits for the expression “Pi^Pi^Pi”
(a few seconds)

But when I try to do this in Julia:

setprecision(BigFloat, 100000)
BigFloat(pi^pi^pi)

It doesn’t work as I expect.

Is there a way how can I calculate a really large number of Hexadecimal digits for the expression pi^pi^pi using Julia?

The problem is that pi^pi^pi is computed as a Float64. What you want is

a=BigFloat(pi)
a^a^a

For me, this computation happens in miliseconds

12 Likes

I think you’ll have better luck with

p = BigFloat(pi)
p^p^p
6 Likes

Oh! Thank you so much for such a fast reply!

My goal is much more bizarre)
I want to calculate my expression up to 4 Billion hexadecimal digits! Yes, I want to get the result up to 4,000,000,000 hex digits!

First of all, I want to have the result in Hexadecimal form directly to a text file.
How can I get the result in hex digits for my expression directly into a .txt file without screen output?

4 Billion hex digits, if I’m not mistaken, it means the precision of 4,000,000,000*4 = 16000000000 bits.
I tried to test this:

setprecision(BigFloat, 16000000000)

but got an error:

julia test.jl
ERROR: LoadError: InexactError: trunc(Int32, 16000000000)
Stacktrace:
[1] throw_inexacterror(::Symbol, ::Type{Int32}, ::Int64) at .\boot.jl:558
[2] checked_trunc_sint at .\boot.jl:580 [inlined]

Can I realize my bizarre dream using Julia language? )

The problem here appears to be that julia uses a C library to do it’s extended precision (specifically mpfr), and somewhere in that chain it uses an Int32 to store the number of digits which overflows here. Also note that if you want 4 billion correct digits, you will have to do your computations with more digits so rounding problems don’t break things. I’m not sure whether what you want will be possible with Julia (without a lot of work).

4 Likes

Getting hexadecimal digits for BigFloats is not built-in.
Here is one approach. I print a trailing fractional 0 where it is meaningful at the given precision.

nhexdigits(x::Integer) = iszero(x) ? 1 : 1 + floor(Int,log(16, abs(x)))
hexcharcode = UInt8.(['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']);
hexchar(d)  = @inbounds hexcharcode[d+1]
 
function dec2hex(x::BigFloat)
  ipart = trunc(BigInt, x)
  istr  = dec2hex(ipart)
  fpart = x - ipart
  fstr  = frac2hex(fpart)
  return "hex(" * istr * "." * fstr * ")"
end

function dec2hex(x::BigInt)
  nhex = nhexdigits(x)
  result = fill(zero(UInt8), nhex)
  for i in nhex:-1:1
    x, r = divrem(x, 16)
	result[i] = hexchar(r)
  end
  return String(result)
end

function frac2hex(x::BigFloat)
  nhex =  1+floor(Int, precision(BigFloat) * 0.25)
  result = fill(zero(UInt8), nhex)
  for i in 1:nhex
    x = x * 16
    ipart = trunc(Int, x)
    x = x - ipart
    result[i] = hexchar(ipart)
  end
  str = String(result)
  if str[end-1:end] == "00"
    str = rstrip(str, '0') * "0"
  end
  return isempty(str) ? "0" : str
end

julia> x = big(0.0); print(dec2hex(x))
hex(0.0)
julia> x = big(0.5); print(dec2hex(x))
hex(0.80)
julia> x = big(pi); print(dec2hex(x))
hex(3.243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c880)
julia> x = big(pi)^3; print(dec2hex(x))
hex(1f.019b59389d7c1e019558e5380d6d8733503c4a496cc40e155075c4037d2a5920)
2 Likes

Maybe the better option is to try to find someone who has experience with C and with MPFR library to ask him is it even possible to realize my dream using MPFR or not? because if not I do not know maybe it is needed to write special functions from scratch…
If anyone can help with my dream of calculation an expression like pi^pi^pi up to 4billion of digits please reply.

I did a test with 1,000,000,000 decimal digits using Wolfram Mathematica. It takes about a few days to finish but it did it.
I’m sure it is possible to do with higher speed by creating a special tool for that.
My final goal - I want to calculate 100 billions of hex digits )

That will be very difficult. 100 billion hex digits is 50 GB, so you would almost certainly need to use a computer with at least 150GB of ram. (it would also take forever)

4 Likes

Somehow one man did a program called yCruncher that is able to calculate 100B of hex digits of Pi on a home PC within a very short time like a few days only.
So maybe theoretically it is possible for things like pi^pi^pi.
The problem is that yCruncher doesn’t have “non-integer” power function. So it is not possible to use its built-in custom formula functions for my purpose.
I do not understand what inner algorithms etc are needed to precisely calculate a number like pi^pi^pi up to 100b of digits.
One man told me - you need first calculate Pi till some finite level and after that, you need to do non-integer power a few times.
I’m not so good in math and algorithms theory, I just want to calculate it somehow)

As of 2019, y-cruncher is over half a million lines of code.
from http://www.numberworld.org/y-cruncher/developments.html

Do you really want to be developing something like that?

You can download it http://www.numberworld.org/y-cruncher/

2 Likes

That might actually be a feasible way to get the computation. pi^pi^pi=exp(log(pi)*exp(log(pi)*pi)), which I think y-cruncher should be able to compute.

julia> (pi^pi)^pi
80662.66593855449

julia> pi^(pi^pi)
1.3401641830063398e18

if he wants the first, its exp(pi * (pi * log(pi)))

fyi: afaik yCruncher knows how to handle log(integer) and pow(x, integer) and does not know how to handle log(float) or exp(float). Special purpose constant expansions would need to be derived and encoded as custom formulae.

2 Likes

Here is the full list of custom functions:


Log(x) with precomputed constants

I already asked the author by email and he told me that “non-integer” power function is not implemented and such kind of calculation is not possible without such function.

yCruncher is the absolute best app for home PC in terms of speed but if it doesn’t have an internal function for non-integer power it seems like it cannot be used. Maybe I should, after more investigation, email the author again. Don’t want to bother him without a strong investigation. He suggested me to try to use GMP and MPFR libs, but I’m not a specialist in C and math formulas.

No reason to bother the author again – investigation will lead you back to the same need. Julia’s BigFloats are implemented using MPFR. As are most arbitrary precision floating point libraries.

2 Likes

you could try

# gives you the decimal fraction, not the hex digits
# the conversion to hex digits takes additional time
function pipipi(p)
    pp = p*p
    lp = log(p)
    return exp( pp*lp )
end

# @elapsed returns seconds

setprecision(BigFloat, 100_000)
bpi = BigFloat(pi);
elapsed100thousand = @elapsed pipipi(bpi)

setprecision(BigFloat, 1_000_000)
bpi = BigFloat(pi);
elapsed1million = @elapsed pipipi(bpi)

setprecision(BigFloat, 10_000_000)
bpi = BigFloat(pi);
elapsed10million = @elapsed pipipi(bpi)

# and approximate

elapsed100million = elapsed10million * ceil(elapsed10million/elapsed1million)

elapsed1billion = elapsed100million * ceil(elapsed10million/elapsed1million)

Important: round away the trailing, say, 16 decimal digits before converting to hex. Also note setting the precision sets the number of bits, not the number of digits or hexdigits [both are less than the number of bits, multiply number of bits by 0.30103 (for decimal digits) and 0.25 (for hexdigits) rounding up each one.]

The problem is, as I said above, if I want to calc 4,000,000,000 hex digits ->*4 = 16000000000 bits.
I tried to test this:

setprecision(BigFloat, 16000000000)

but got an error:

julia test.jl
ERROR: LoadError: InexactError: trunc(Int32, 16000000000)

I cannot set precision internally because u have like Int32 limit for precision.
Maybe if you release a new version of Julia without this limit - I can try to do it.
But, if I’m not mistaken, using the current build of Julia - it is not possible to set precision to 16000000000 bits. Correct?

The maximum precision available with BigFloats is the value of typemax(Int32) (2_147_483_647) but that is not really useful because internally, MPFR uses some extra bits when it wants to do so. At any rate, this is an internal limit. 500 million hex digits is the rough limit (~536.87 million).

2 Likes

ahh,
it is possible to remove this limit?

No. As stated, it is an internal limit.

2 Likes