May I use it in Free Pascal?Pascal defines that all arithmetic operations (http://www.pascal-central.com/iso7185.html#6.7.2.2%20Arithmetic%20operators) in the range -maxInt..maxInt work correctly. Beyond that there is no assurance of correctness.
[…] What should I write, for the variable x to run over all possible integers whose absolute value is not bigger than: 2 to the n-th power (minus 1), n being a constant?The drawback of that kind of approach is that such a simple task as yours becomes quite complicated:
GMP is much easier with interfaces:Where’s that documented? That’s indeed less cluttered. And it’s a blessing if I don’t have to mind the proper …_clear.
As handy as it is, this won’t make use of MPZ_cmpAbs though, right? It’ll create two temporary copies, take the absolute value of each of them, and then compare their values. And finally release memory. This isn’t very efficient, you know.
while z_abs(x) <= z_abs(limit) do // […]
So I would say that actually it doesn't really get that complicated, but it gets slowYeah, I think the slowdown is exacerbated if you are using GMP via those interfaces. My code did a plain
Pascal defines that all arithmetic operations in the range -maxInt..maxInt work correctly. Beyond that there is no assurance of correctness.FPC must work correctly with Int64 vars too, no?
It's kind of documented in the "Extensions bindings & types" section of the wiki article, but the operator section is completely missing.Indeed. And I always advocate for the security principle: “Don’t use functionality that is not documented.” And if it’s not documented, it might be gone in the next release without further notice.
Not really the best documentation.
With the cmpAbs that is true, I tried to write the code as "natural" as possible, but you can use every gmp function with the interfaces, so you could use z_cmpAbs with the interfaces. […]Alright, I tried it. That’s neat.
Even more, each interface also adds it's own overhead, so when you create a GMP object you only need one allocation for the GMP memory, with the interfaces you need 2, one for the interfaced object and one for the gmp object.I daresay that’s negligible though if you’re doing calculations in the zillions.
It must at least work correctly in the range -maxInt..maxInt. Consider the following program:QuotePascal defines that all arithmetic operations in the range -maxInt..maxInt work correctly. Beyond that there is no assurance of correctness.FPC must work correctly with Int64 vars too, no?
Maybe you can improve or alter your algorithm so it doesn’t exceed the bounds of -maxInt..maxInt? Do you really need to iterate over all integers in (−2n, 2n)? Also (possibly to the detriment of precision) you can use ln/exp and logarithmic rules (https://en.wikipedia.org/wiki/List_of_logarithmic_identities#Using_simpler_operations).
For example, I would like to write something like:
const c = 2 ** 63 -1; var x: int64; begin x:=c*c*c end.
Let's assume that the range of x is not expected to exceed the value of 2 to the n-th power (minus 1), n being a constant.
How do I write that?
Indeed. And I always advocate for the security principle: “Don’t use functionality that is not documented.” And if it’s not documented, it might be gone in the next release without further notice.Well this principle doesn't hold up very well with many fpc/fcl/lcl units and libraries simply because most of the documentation is missing, outdated or simply wrong.
Well this principle doesn't hold up very well with many fpc/fcl/lcl units and libraries simply because most of the documentation is missing, outdated or simply wrong.
for example using GMP:
... const c = High(QWord); var x: MPInteger; begin x := c.ToString; //need SysUtils in uses clause x := x*x*x; WriteLn(string(x)); // prints 6277101735386680762814942322444851025767571854389858533375 end;
IIRC, the size of GMP' mpz_t (and hence MPInteger) is limited only by the available computer memory.
...
Additionally, except for writing:
{$mode objFPC} uses GMP; SysUtils;
Should anything else be written before the "begin"?
...
"There are no practical limits to the precision except the ones implied by the available memory (operands may be of up to 232−1 bits on 32-bit machines and 237 bits on 64-bit machines)."
https://en.wikipedia.org/wiki/GNU_Multiple_Precision_Arithmetic_Library
MarkMLl
IIRC, the size of GMP' mpz_t (and hence MPInteger) is limited only by the available computer memory.
"There are no practical limits to the precision except the ones implied by the available memory (operands may be of up to 232−1 bits on 32-bit machines and 237 bits on 64-bit machines)."
https://en.wikipedia.org/wiki/GNU_Multiple_Precision_Arithmetic_Library
MarkMLl
avk's result, printing the factorial of 1000, has more than 2500 digits, a way beyond the 237 bits you have mentioned.
I cannot find the gmp units in 3.2.2 64 bit pascal??
but they are in the 32 bit version.
Here is the .dll and the example by avk compared to another method.
I also have to say that when I was looking at some of the Python API documentation I was extremely impressed by its thoroughness. Shame I have such a low opinion of the language itself.What I have seen with many python docs is that they use a very interesting approach, basically the docs are also in a git repository, and whenever a release of the main software is made, the doc git gets the version tag.
What I actually need is, to assign a "huge" integer to a variable. The "huge" integer is a product of some non-negative integers, each of which is of int64 type.This smells like cryptography or similar task. If you just wanna store your value, put your integer factorization into an array. It’s that simple. Then the entire array together represents a value, or at least a way to calculate it, you know. You don’t need to calculate the product, just store its factors. Use (a sorted array of) primes if you want a unique way to store a product (https://en.wikipedia.org/wiki/Fundamental_theorem_of_arithmetic).
lib gmp is blazingly fast, it is used by many compilers, […] However for smaller big numbers you can roll out your own methods […]Don’t program what’s already been programmed for you. It’s certainly fun to implement it, but I wouldn’t recommend that to Eli unless he intends to and is capable of maintaining it. Otherwise you’ll suffer from the not invented here (https://en.wikipedia.org/wiki/Not_invented_here) syndrome. ;D
you can compile the gmp unit from source fpcbuild-3.2.2\fpcsrc\packages\gmp\src to 64-bit and then place the files in FPC\3.2.2\units\x86_64-win64\gmp
I cannot find the gmp units in 3.2.2 64 bit pascal??
but they are in the 32 bit version.
......
uses Velthuis.BigIntegers; ...
This smells like cryptography or similar task. If you just wanna store your value, put your integer factorization into an array. It’s that simple. Then the entire array together represents a value, or at least a way to calculate it, you know. You don’t need to calculate the product, just store its factors. Use (a sorted array of) primes if you want a unique way to store a product (https://en.wikipedia.org/wiki/Fundamental_theorem_of_arithmetic).
...
Oh, I did need to calculate the product, and I used the library gmp (you'd suggested me here) for calculating that.
Actually, I wanted to see if the equation |3^x - 2^y| = 1, had any natural solutions, besides the three obvious solutions:
3^1 - 2^1 = 1.
2^2 - 3^1 = 1.
3^2 - 2 ^3 = 1.
My conjecture is that this equation has no other natural solutions. Thanks to the library you had suggested me here, my conjecture turned out to be true - for all natural exponentials not larger than 1000. However. for larger natural exponentials, the calculation becomes too slow, so I didn't check out any larger natural exponentials.
...
He explains it at the bottom of this page (http://rvelthuis.de/programs/bigintegers.html).Rudy is sadly missing from this planet, but indeed. By now, {$mode delphi}+removing the scoping is sufficient to make it work, even the assembler stuff for 32 bit.
Correct. I've just noticed this is Catalan's conjecture, that has already been proven....
Oh, I did need to calculate the product, and I used the library gmp (you'd suggested me here) for calculating that.
Actually, I wanted to see if the equation |3^x - 2^y| = 1, had any natural solutions, besides the three obvious ones:
3^1 - 2^1 = 1.
2^2 - 3^1 = 1.
3^2 - 2^3 = 1.
My conjecture is that this equation has no other natural solutions. Thanks to the library you had suggested me here, my conjecture turned out to be true - for all natural exponentials not larger than 10,000. However. for larger natural exponentials, the calculation becomes too slow, so I didn't check out any larger natural exponentials.
...
Hello eli - if the above is what you want to do, why not look for some already existing mathematical treatise of the subject. Iirc this - and the more general a^n - b^k = 1 - have been solved in context of number theory.
Cheers,
MathMan
>>>import sympy as syFriendly, J.P
>>>x, y = sy.symbols("x y")
>>>f=sy.Eq(3**x - 2**y,1)
>>>sy.solve((f),(x,y))
Result (x,y) --> [(log(2**y + 1)/log(3), y)]
hello,
python with the module sympy can solve this type of equation :Quote>>>import sympy as syFriendly, J.P
>>>x, y = sy.symbols("x y")
>>>f=sy.Eq(3**x - 2**y,1)
>>>sy.solve((f),(x,y))
Result (x,y) --> [(log(2**y + 1)/log(3), y)]
Correct. I've just noticed this is Catalan's conjecture, that has already been proven....
Oh, I did need to calculate the product, and I used the library gmp (you'd suggested me here) for calculating that.
Actually, I wanted to see if the equation |3^x - 2^y| = 1, had any natural solutions, besides the three obvious ones:
3^1 - 2^1 = 1.
2^2 - 3^1 = 1.
3^2 - 2^3 = 1.
My conjecture is that this equation has no other natural solutions. Thanks to the library you had suggested me here, my conjecture turned out to be true - for all natural exponentials not larger than 10,000. However. for larger natural exponentials, the calculation becomes too slow, so I didn't check out any larger natural exponentials.
...
Hello eli - if the above is what you want to do, why not look for some already existing mathematical treatise of the subject. Iirc this - and the more general a^n - b^k = 1 - have been solved in context of number theory.
Cheers,
MathMan