Calculation Pi^Pi^Pi in hexadecimal in High precision

Yes, this is a foible of Windows: long is only 32 bit even on machines with 64-bit words. Unix systems like Linux, macOS and FreeBSD, on the other hand, are properly 64-bit on 64-bit hardware.

6 Likes

Do you know is it possible to remove this 32bits limit in Windows?
I wonder why in Linux they have 64bits for precision and in Windows only 32bits (
I’m a Windows-guy and never tried Linux.

Is that defined by the C specification?
As far as I remember the specification doesn’t link the ISA Bits to the number of bits of the data types.

According to Wikipedia C Data Types it shows:

So Windows is also proper. There is nothing “More Proper” in Linux with that regard.

1 Like

The C spec defines minimum sizes for representations and allows a lot of latitude in implementations, which is why portable C code uses typedefs for specific type sizes that are specialized for each implementation with the preprocessor.

3 Likes

As you can see by my answer I was aware of that.
I was pointing my comment to @StefanKarpinski’s remark about Unix / Posix based OS being proper on that while Windows is not.

While in fact both are in compliance with the C standards.

Yes, sorry, I took your question as literal rather than rhetorical without reading fully. Perhaps Stefan ought to have used a different word, such as intuitive or expected. The library in question ought to have used portability typedefs if it were intended to behave the same on windows.

1 Like

Ehhh, it can both be compliant with C standards (which are really quite loose) and a half-ways 64-bit implementation. But this is quite the digression.

Back to MFPR, they clearly want to support some awful legacy systems as they don’t want to depend upon C99 or limits.h:

154 /* Note: mpfr_prec_t is currently limited to "long". This means that
155 under MS Windows, the precisions are limited to about 2^31; however,
156 these are already huge precisions, probably sufficient in practice
157 on this platform. */

and

165 /* we could use "long long" under Windows 64 here, which can be tested
166 with the macro _WIN64 according to
167 https://sourceforge.net/p/predef/wiki/OperatingSystems/ */

and

174 /* Definition of precision limits without needing <limits.h> */

1 Like

Please forgive my ignorance, but is {\pi^\pi}^\pi a constant with a meaningful application/meaning, or is this just to stress-test bigfloats?

4 Likes

If there is a practical application, it certainly doesn’t need this many digits, so I assume this is just a personal quest.

2 Likes

The only remotely practical application I can imagine might be for crypto key generation

1 Like

Seems that using higher precision Julia packages I’ve discovered that log(gamma( is related to PI ;
per using SpecialFunctions and using Nemo ?

using Julia SpecialFunctions and Nemo seems I’ve discovered that loggamma(-1 + 0i) = Infinity - i*pi (a Complex number) .
Also Wolframalpha answer is incomplete About: loggamma(-1 + 0i) or logΓ(-1 + 0 i)
Try this link loggamma(-1 + 0i) - Wolfram|Alpha
and you’ll see Wolframalpha shows loggamma(-1 + 0i) = Infinity

However it seems I’ve discovered/uncovered that loggamma(-1 + 0i) = Infinity - i*pi (a Complex number) per the following :

## show using SpecialFunctions 
## loggamma(-1 + 0i) = Infinity - i*pi (a Complex number)
julia> loggamma(-1+0im)
Inf - 3.141592653589793im

julia> imag(loggamma(-1+0im))/pi
-1.0

## Showing Effects of error propagation ?
julia> log(gamma(-1+0im))
Inf - 2.356194490192345im

## Reconfirmed suspicion via show using Nemo to 64 Bits / 18 Decimals
using Nemo # for arbitrary precision math calculations 
CC = ComplexField(64)

julia> using Nemo
julia> CC = ComplexField(64)
Complex Field with 64 bits of precision and error bounds

julia> RR = RealField(64)
Real Field with 64 bits of precision and error bounds

julia> Nemo.lgamma(RR("-1") + CC("0"))
nan + i*[-3.141592653589793238 +/- 5.14e-19]
julia> Nemo.const_pi(RR)
         [3.141592653589793239 +/- 5.96e-19]

Also here’s an analytical/symbolic equation question :
Is this the same or a different fact than the Euler Identity ?

Maybe start here Gamma, Beta, Erf > LogGamma[z]

Representations through more general functions >> Logarithm of the gamma function: Representations through more general functions (subsection 26/01)

An answer for the OP’s original question for High Precision calculations ; example code using Nemo providing Definable precision mathematics with error bounds ( ? aka statistical error bars ?)


using Nemo

RR = RealField(64)

julia> Nemo.const_pi(RR)

[3.141592653589793239 +/- 5.96e-19]

**## Part1 answer for the OP’s original question**

**julia> RR = RealField(128)**

**Real Field with 128 bits of precision and error bounds**

julia> Nemo.const_pi(RR)

[3.1415926535897932384626433832795028842 +/- 1.06e-38]

## [3.1415926535897932384626433832795028842 +/- 1.06e-38]

## https://math.tools/numbers/pi/100

## First 100 digits of pi **(Cross-check)**

## [3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679

**## Part2 answer for the OP’s original question**

julia> Nemo.const_pi(RR)^Nemo.const_pi(RR)^Nemo.const_pi(RR)

[1340164183006357435.29744912964013141 +/- 7.44e-18]

## **(Cross-check)** **Exponentiation parsed correctly as right associative**

julia> Nemo.const_pi(RR)^(Nemo.const_pi(RR)^Nemo.const_pi(RR))

[1340164183006357435.29744912964013141 +/- 7.44e-18]

Here’s a solution using IntervalArithmetic.jl:

julia> using IntervalArithmetic

julia> @format midpoint 50;    # output 50 digits, use midpoint representation

julia> @biginterval π ^ π ^ π
1340164183006357435.2974491296401314001461680594635 ± 7.1689136000960352466299617899547031251599704983668e-58

EDIT: Using Float64 gives

julia> @interval π ^ π ^ π
1340164183006362112 ± 90624
10 Likes

Noticed the OP post was for an extremely high number of significant figures,
so pushed Nemo.jl out further to 4096 bits which is over 1000 sig figs base10.

julia> using Nemo

julia>  RR = RealField(4096) ## using Nemo.jl for  Definable precision mathematics with error bars.
Real Field with 4096 bits of precision and error bounds

julia> Nemo.const_pi(RR)
[3.141592653589793238462 ... +/- 5.51e-1233]

julia> Nemo.const_pi(RR)^Nemo.const_pi(RR)^Nemo.const_pi(RR)
[1340164183006357435.297 ... +/- 4.12e-1212]


julia> using BenchmarkTools

julia> @benchmark Nemo.const_pi(RR)^Nemo.const_pi(RR)^Nemo.const_pi(RR)
BenchmarkTools.Trial: 
  memory estimate:  3.92 KiB
  allocs estimate:  12
  --------------
  minimum time:     232.576 μs (0.00% GC)
  median time:      238.957 μs (0.00% GC)
  mean time:        245.541 μs (0.00% GC)
  maximum time:     716.879 μs (0.00% GC)
  --------------
  samples:          10000
  evals/sample:     1

julia> @time Nemo.const_pi(RR)^Nemo.const_pi(RR)^Nemo.const_pi(RR)
  0.000317 seconds (12 allocations: 3.922 KiB)

What was surprising and :sunglasses: was, even using 4096 bit reals, Nemo.jl had very little, almost not noticeable CPU usage and very slight additional memory allocations when it calculated more than 1000 sig figs. So wondering :thinking: if Nemo is exploiting a shortcut or “magic” that might be implicitly hidden in the Nemo features listed here >> Getting Started · Nemo.jl

I don’t think this is that surprising. All the problems Op was talking about were with asking for 100k to 1B digits. 4k and 100k are very different (I should know. I’m a math major :slight_smile: ).

2 Likes

Scales pretty well past that:

julia> using Nemo

julia> foreach(2 .^ (8:17)) do N
           @show N
           RR = RealField(N)
           result = @btime Nemo.const_pi($RR)^Nemo.const_pi($RR)^Nemo.const_pi($RR)
           @show result
           println()
       end 
N = 256
  3.412 μs (12 allocations: 656 bytes)
result = [1340164183006357435.2974491296401314150993749745734992377879275165860340926 +/- 2.20e-56]

N = 512
  5.872 μs (12 allocations: 880 bytes)
result = [1340164183006357435.297449129640131415099374974573499237787927516586034092619094068148269472611301142273437488952597496949098445637468318932074814417133 +/- 1.27e-133]

N = 1024
  16.670 μs (12 allocations: 1.30 KiB)
result = [1340164183006357435.29744912964013141509937497457349923778792751658603409261909406814826947261130114227343748895259749694909844563746831893207481441713296868595665505861832304409260344935722137619083399128209272634779708614451149209064907822294679198447533622596408302511181354428253415769627492356327900821 +/- 7.02e-288]

N = 2048
  56.280 μs (12 allocations: 2.17 KiB)
result = [1340164183006357435.2974491296401314150993749745734992377879275165860340926190940681482694726113011422734374889525974969490984456374683189320748144171329686859566550586183230440926034493572213761908339912820927263477970861445114920906490782229467919844753362259640830251118135442825341576962749235632790082163382354493811048356977004050046461235433245632644834558130591134781891957097416354676228557308050967641819526522537994353891274135380086401090813607445243381831678464008385405226026792226019874421667534912237652417044112558499915127650180612214632249925590671652930224582813662674852983217955536851340666680 +/- 6.63e-596]

N = 4096
  221.058 μs (12 allocations: 3.92 KiB)
result = [1340164183006357435.2974491[...] +/- 4.12e-1212]

N = 8192
  800.201 μs (256 allocations: 42.52 KiB)
result = [1340164183006357435.2974491[...]+/- 4.83e-2445]

N = 16384
  2.697 ms (468 allocations: 94.98 KiB)
result = [1340164183006357435.2974491[...] +/- 4.57e-4911]

N = 32768
  8.819 ms (1570 allocations: 628.26 KiB)
result = [1340164183006357435.2974491[...] +/- 2.81e-9843]

N = 65536
  25.970 ms (3409 allocations: 4.76 MiB)
result = [1340164183006357435.2974491[...] +/- 8.69e-19708]

N = 131072
  76.024 ms (6554 allocations: 13.56 MiB)
result = [1340164183006357435.2974491[...] +/- 7.03e-39436]

(truncated digits so I would meet the maximum character count)

Edit: here’s how far I could go before each iteration was taking enough ram that I no longer wanted it running:

julia> foreach(2 .^ (18:25)) do N
           @show N
           RR = RealField(N)
           result = @btime Nemo.const_pi($RR)^Nemo.const_pi($RR)^Nemo.const_pi($RR)
           println()
       end
N = 262144
  222.262 ms (17277 allocations: 70.47 MiB)

N = 524288
  601.466 ms (42648 allocations: 236.61 MiB)

N = 1048576
  1.485 s (91724 allocations: 677.82 MiB)

N = 2097152
  3.731 s (180055 allocations: 1.59 GiB)

N = 4194304
  8.980 s (344271 allocations: 3.72 GiB)

N = 8388608
  21.636 s (656866 allocations: 8.32 GiB)

So 8,388,608 digits, not bad.

6 Likes

Possibly that’s not a helpful or useful way of trying to understand it. People asked similar questions as every new extension to positive integers was introduced. There were objections to negative numbers, complex numbers etc. “How is it possible to have -5 apples? It’s not possible!” The meaning of what a number is was also extended.

What “is” 1^0 or 0^0? Such things are just defined to be whatever is most compatible with existing formulas, what it is most convenient they should be. Puzzling about it as if it makes no sense according to the previous definitions is needless confusion.

But…if you must, maybe try to understand square roots first! x^(1/2). Playing around with Newton’s generalised binomial formula for non-integer powers might help them make more sense.

4 Likes

using Nemo.jl works to over 157000 Base10 digits in less than 1 second. Definitely wondering :thinking: now if Nemo is exploiting some mathematical shortcut “magic” that might be implicitly hidden in the Nemo features listed here >> Getting Started · Nemo.jl

julia> RR = RealField(524288) ## using Nemo.jl for Definable precision mathematics with error bars.

Real Field with 524288 bits of precision and error bounds

julia> @time Nemo.const_pi(RR)^Nemo.const_pi(RR)^Nemo.const_pi(RR)

0.658621 seconds (42.92 k allocations: 242.657 MiB, 1.31% gc time)

[1340164183006357435.297449 ... +/- 6.47 **e-157806** ]

## Typing aide shortcut below, beware you'll get a screenful lol
using Nemo
RR = RealField(524288) ## using Nemo.jl for Definable precision mathematics with error bars.
@time Nemo.const_pi(RR)^Nemo.const_pi(RR)^Nemo.const_pi(RR)
@time Nemo.const_pi(RR)^Nemo.const_pi(RR)^Nemo.const_pi(RR)

1 Like

@Marc.Cox I believe it’s using Fredrik Johansson’s arb software. He has a nice paper describing how that works.

3 Likes

@dpsanders, this paper?

1 Like