(Not tested with the absolutely latest Pike)
The Gmp-functions don't have a correct behaviour:
pow(2, pow(2, pow(2, pow(2, pow(2,pow(2,2))))));
Compiler Error: 1:Error evaluating constant. Compiler Exception: Too many argumentsUnknown program: pow(HilfeCompileHandler,-1,-1)
There are only two arguments there! And there should be some sort of space in "argumentsUnknown"
pow(2, 65536423423423423);
(7) Result: 65536423423423423
8->pow(34534534534534534534534534545);
Gmp.mpz->pow: Non int exponent. /usr/local/pike/7.3.43/lib/modules/Gmp.so.bignum: pow(34534534534534534534534534545) HilfeInput:1: ___HilfeWrapper()
Seems OK, but "Non int exponent." could be changed to "Exponent bigger than a non-bignum integer.".
8->pow(34534534);
Segmentation fault
Not good! I think this is an out of memory problem, so you have to change 34534534 to something that works on your computer.
Uh, you need too upgrade your pike. I fixed those weeks ago:
Pike v7.3 release 60 running Hilfe v3.5 (Incremental Pike Frontend)
pow(2, pow(2, pow(2, pow(2, pow(2,pow(2,2))))));
Gmp.mpz->pow: Exponent too large. /pike/sw/pike/7.3.60/lib/modules/Gmp.so.bignum: pow(,,,0) HilfeInput:1: ___HilfeWrapper()
pow(2, 65536423423423423);
Gmp.mpz->pow: Exponent too large. /pike/sw/pike/7.3.60/lib/modules/Gmp.so.bignum: pow(65536423423423423) HilfeInput:1: ___HilfeWrapper()
8->pow(34534534534534534534534534545);
Gmp.mpz->pow: Exponent too large. /pike/sw/pike/7.3.60/lib/modules/Gmp.so.bignum: pow(34534534534534534534534534545) HilfeInput:1: ___HilfeWrapper()
The 8->pow(34534534); call still segfaults, but it's hard to do anything about it without fixing Gmp itself.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2002-11-20 15:02: Subject: Gmp
(Not tested with the absolutely latest Pike)
The Gmp-functions don't have a correct behaviour:
pow(2, pow(2, pow(2, pow(2, pow(2,pow(2,2))))));
Compiler Error: 1:Error evaluating constant. Compiler Exception: Too many argumentsUnknown program: pow(HilfeCompileHandler,-1,-1)
There are only two arguments there! And there should be some sort of space in "argumentsUnknown"
pow(2, 65536423423423423);
(7) Result: 65536423423423423
8->pow(34534534534534534534534534545);
Gmp.mpz->pow: Non int exponent. /usr/local/pike/7.3.43/lib/modules/Gmp.so.bignum: pow(34534534534534534534534534545) HilfeInput:1: ___HilfeWrapper()
Seems OK, but "Non int exponent." could be changed to "Exponent bigger than a non-bignum integer.".
8->pow(34534534);
Segmentation fault
Not good! I think this is an out of memory problem, so you have to change 34534534 to something that works on your computer.
/ Hedda (www.elftown.com)
As you say, the out-of-memory problem is a little hard to fix without changing GMP. One "solution" that has been proposed on the gmp list:
1. Register your own memory allocation functions with gmp. Put a jmp-buffer somewhere that the memory allocation function will longjmp to on failure.
2. Around each call to a gmp function, first put some mark into the memory allocation structure.
3. Then call setjmp.
4. If the memory allocation function longjmps out, you know that you're out of memory. In this case, check for the mark you installed in step 2, so that you can free any temporary storage that was allocated before the failure.
5. For a threaded program, both the marking and the jmp buffer has to be in thread-local storage.
Not particularly pretty...
A different way is to stop using the mpz_* functions, and use only the lower level mpn_* functions instead. But then you lose functionality, complex algorithms, e.g. powm, isn't available in the mpn interface.
/ Niels Möller ()
Previous text:
2002-11-20 15:18: Subject: Gmp
Uh, you need too upgrade your pike. I fixed those weeks ago:
Pike v7.3 release 60 running Hilfe v3.5 (Incremental Pike Frontend)
pow(2, pow(2, pow(2, pow(2, pow(2,pow(2,2))))));
Gmp.mpz->pow: Exponent too large. /pike/sw/pike/7.3.60/lib/modules/Gmp.so.bignum: pow(,,,0) HilfeInput:1: ___HilfeWrapper()
pow(2, 65536423423423423);
Gmp.mpz->pow: Exponent too large. /pike/sw/pike/7.3.60/lib/modules/Gmp.so.bignum: pow(65536423423423423) HilfeInput:1: ___HilfeWrapper()
8->pow(34534534534534534534534534545);
Gmp.mpz->pow: Exponent too large. /pike/sw/pike/7.3.60/lib/modules/Gmp.so.bignum: pow(34534534534534534534534534545) HilfeInput:1: ___HilfeWrapper()
The 8->pow(34534534); call still segfaults, but it's hard to do anything about it without fixing Gmp itself.
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
A different way is to stop using the mpz_* functions, and use only the lower level mpn_* functions instead. But then you lose functionality, complex algorithms, e.g. powm, isn't available in the mpn interface.
What does mpn_pow do if it runs out of memory, and why doesn't mpz_pow do the same?
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
Previous text:
2002-11-20 15:40: Subject: Gmp
As you say, the out-of-memory problem is a little hard to fix without changing GMP. One "solution" that has been proposed on the gmp list:
- Register your own memory allocation functions with gmp. Put a
jmp-buffer somewhere that the memory allocation function will longjmp to on failure.
- Around each call to a gmp function, first put some mark into the
memory allocation structure.
Then call setjmp.
If the memory allocation function longjmps out, you know that
you're out of memory. In this case, check for the mark you installed in step 2, so that you can free any temporary storage that was allocated before the failure.
- For a threaded program, both the marking and the jmp buffer has to
be in thread-local storage.
Not particularly pretty...
A different way is to stop using the mpz_* functions, and use only the lower level mpn_* functions instead. But then you lose functionality, complex algorithms, e.g. powm, isn't available in the mpn interface.
/ Niels Möller ()
The mpn_* generally don't do memory allocation, they require the caller to allocate memory for the result and temporaries.
So there should be no big problem changing pike's pow function to use mpn_pow instead of mpz_pow. But pow*m* will be harder (and it also allocates a lot more temporary storage).
/ Niels Möller ()
Previous text:
2002-11-20 15:43: Subject: Gmp
A different way is to stop using the mpz_* functions, and use only the lower level mpn_* functions instead. But then you lose functionality, complex algorithms, e.g. powm, isn't available in the mpn interface.
What does mpn_pow do if it runs out of memory, and why doesn't mpz_pow do the same?
/ Marcus Comstedt (ACROSS) (Hail Ilpalazzo!)
pike-devel@lists.lysator.liu.se