digitalmars.D.bugs - [Issue 5765] New: ^^ and << with BigInts
- d-bugmail puremagic.com (28/28) Mar 21 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5765
- d-bugmail puremagic.com (17/17) Mar 22 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5765
- d-bugmail puremagic.com (52/52) Mar 22 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5765
- d-bugmail puremagic.com (25/28) Mar 23 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5765
- d-bugmail puremagic.com (24/35) Mar 23 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5765
- d-bugmail puremagic.com (18/45) Mar 23 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5765
- d-bugmail puremagic.com (20/22) Mar 23 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5765
- d-bugmail puremagic.com (15/32) Mar 23 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5765
- d-bugmail puremagic.com (27/30) Mar 23 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5765
- d-bugmail puremagic.com (7/7) May 09 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5765
- Stian Pedersen (3/3) May 03 2012 Hi
- bearophile (5/7) May 03 2012 Better to ask such questions in D.learn.
http://d.puremagic.com/issues/show_bug.cgi?id=5765 Summary: ^^ and << with BigInts Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: Phobos AssignedTo: nobody puremagic.com ReportedBy: bearophile_hugs eml.cc If I try to perform a 2^^10 with bigints I find some troubles (dmd 2.052): import std.bigint; void main() { BigInt p1 = BigInt(2) ^^ 10; // OK BigInt p2 = BigInt(1) << 10; // OK BigInt p3 = BigInt(2) ^^ BigInt(10); // Error BigInt p4 = 2 ^^ BigInt(10); // Error BigInt p5 = BigInt(1) << BigInt(10); // Error BigInt p6 = 1 << BigInt(10); // Error } I'd like those six lines to work, if possible. (I remember an enhancement request related to this, but I can't find it). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 21 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5765 Don <clugdbug yahoo.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |clugdbug yahoo.com.au Those operations could easily be allowed. But it's not an accident that they're not currently implemented. The question is, is it a good idea? anything ^^ BigInt and anything << BigInt will ALWAYS overflow, if the BigInt doesn't actually fit into an int. So except for a few toy cases, such as the example here, such operations are always bugs in the user's code. Do we really want to allow such a bug-prone operation which provides no useful functionality? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 22 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5765 Here n needs to be a BigInt, because of the second recursive call. So instead of writing 2^^n you need to write BigInt(2)^^n.toInt() that's not natural (this code will probably work in DMD 2.053 thanks to a -0 bug you have fixed): import std.stdio, std.bigint; /// Optimized Ackermann function BigInt ackermann(int m, BigInt n) { if (m == 0) return n + 1; if (m == 1) return n + 2; if (m == 2) return 3 + n * 2; //if (m == 3) return 5 + 8 * (2 ^^ n - 1); if (m == 3) return 5 + 8 * (BigInt(2) ^^ n.toInt() - 1); if (n == 0) return ackermann(m - 1, BigInt(1)); else return ackermann(m - 1, ackermann(m, n - 1)); } void main() { writeln(ackermann(4, BigInt(2))); } Equivalent Python2.6 code that works: def ackermann(m, n): """Optimized Ackermann function""" if m == 0: return n + 1 if m == 1: return n + 2 if m == 2: return 3 + n * 2 if m == 3: return 5 + 8 * (2 ** n - 1) if n == 0: return ackermann(m - 1, 1) else: return ackermann(m - 1, ackermann(m, n - 1)) assert len(str(ackermann(4, 2))) == 19729 -------------- Two little about BigInt (maybe it's wrong to put those in this bug report): How do I perform the equivalent of str(ackermann(4, 2)) with BigInt? The bottom of this page shows a duplication to me: http://www.digitalmars.com/d/2.0/phobos/std_bigint.html The output format is controlled via formatString: The output format is controlled via formatString: "d" Decimal "x" Hexadecimal, lower case "X" Hexadecimal, upper case "s" Default formatting (same as "d") null Default formatting (same as "d") "d" Decimal "x" Hexadecimal, lower case "X" Hexadecimal, upper case "s" Default formatting (same as "d") null Default formatting (same as "d") -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 22 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5765 OK, although I don't think that the case with Ackermann code is so bad. It's basically giving you a compile-time warning that the function blows up very, very easily. Having seen this, it becomes obvious that the m=4 case will blow up for n>2, and therefore that the m=5 will blow up for n>0, and the m>=6 will blow up for any n. Since this only leaves a total of 4 cases, A(4,0) = 13, A(4,1) = A(5,0) = 65533, and A(4,2), why not continue the optimization, and eliminate the recursion entirely? So I think it encourages you to write better quality code. I think it's quite bizarre to stop at m=3, so I don't find this example convincing. The thing I'm really worried about is this: BigInt a, b, c; a = (a ^^ b) % c; This is an attempt to do modular exponentiation, which comes up frequently in cryptography. The code is mathematically correct, but completely wrong in practice. So I would rather give an informative static assert for the BigInt ^^ BigInt case. (Definitely, it shouldn't just fail the way it does now).How do I perform the equivalent of str(ackermann(4, 2)) with BigInt?format("%d", ackermann(4,2))The bottom of this page shows a duplication to me: http://www.digitalmars.com/d/2.0/phobos/std_bigint.htmlYou're right. A new ddoc bug. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 23 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5765The thing I'm really worried about is this: BigInt a, b, c; a = (a ^^ b) % c; This is an attempt to do modular exponentiation, which comes up frequently in cryptography. The code is mathematically correct, but completely wrong in practice.In Python 2.6 the built-in pow function has a third optional argument, that's the modulus, that uses a more efficient algorithm to perform the powermod (note the second 6 that's not a multi-precision value):6L(20 ** 125) % 76 I suggest to add a similar function to std.math or std.bigint. Also the D compiler may recognize the (x^^y)%z pattern and replace it with a power mod function call.pow(20, 125, 7)So I would rather give an informative static assert for the BigInt ^^ BigInt case.Python allows you to use the power/shift with multi-precision numbers too, if you want. The multi-precision numbers can be used transparently, syntax-wise. If you have D templated code that you want to use with both BigInt and int you will have to use a static if to change the code from x^^y to BigInt(x)^^y.toInt() (or call a little pow template function that does the same, losing infix operator syntax again), this isn't good. BitInt are meant to work as integers, mostly. I'd like a D program to work with as few changes as possible if I replace int with BigInts or BigInts with ints (in some situations I may write the code with BigInts, see the results and then try to write the same with ints/longs, to spot the overflows). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 23 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5765The thing I'm really worried about is this: BigInt a, b, c; a = (a ^^ b) % c; This is an attempt to do modular exponentiation, which comes up frequently in cryptography. The code is mathematically correct, but completely wrong in practice.I suggest to add a similar function to std.math or std.bigint.Of course, that's what I was implying. Note that it is a totally different operation to ^^.Also the D compiler may recognize the (x^^y)%z pattern and replace it with a power mod function call.I think that's asking too much. Also note that it doesn't cover the two step pattern where someone does: x = x ^^ y ; x %= z;BigIntSo I would rather give an informative static assert for the BigInt ^^That's a false consistency. T ^^ int is the common operation, not T ^^ T. Really. BigInt ^^ BigInt isn't a BigInt. It's too big to be representable.case.Python allows you to use the power/shift with multi-precision numbers too, if you want. The multi-precision numbers can be used transparently, syntax-wise. If you have D templated code that you want to use with both BigInt and int you will have to use a static if to change the code from x^^y to BigInt(x)^^y.toInt() (or call a little pow template function that does the same, losing infix operator syntax again), this isn't good.BitInt are meant to work as integers, mostly. I'd like a D program to work with as few changes as possible if I replace int with BigInts or BigInts with ints (in some situations I may write the code with BigInts, see the results and then try to write the same with ints/longs, to spot the overflows).So? These ones which currently don't compile, will definitely cause problems with ints/longs as well. You're just getting the error message at compile time rather than at run time. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 23 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5765That's a false consistency. T ^^ int is the common operation, not T ^^ T. Really. BigInt ^^ BigInt isn't a BigInt. It's too big to be representable.Python3 (and Lisp-family languages, and others) use multi-precision integers on default, but most people don't store large numbers in them, most times they store little numbers, and most people doesn't use them for cryptography. I am not going to use D BigInts for cryptography. 99.9% times inside BigInts I'll keep numbers less than 63 bit long. I'd like to use BigInt as in Python to avoid the problems caused by int, because currently in D there are no integer overflow tests, because Walter doesn't want them. The first and by a wide margin most important purpose of multi-precision integers is not to represent huge numbers or to do cryptography, but to free the mind of the programmer from being forced to think all the time about possible overflows breaking the code he/she is writing, freeing that part of attention, and allowing him/her to focus more on the algorithm instead. This is one of the causes that explain why Python is good to write prototypes, allowing to implement algorithms faster than most other languages (D included). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 23 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5765They are not system languages. The comparison is irrelevant.That's a false consistency. T ^^ int is the common operation, not T ^^ T. Really. BigInt ^^ BigInt isn't a BigInt. It's too big to be representable.Python3 (and Lisp-family languages, and others) use multi-precision integers on default, but most people don't store large numbers in them, most times they store little numbers, and most people doesn't use them for cryptography.I am not going to use D BigInts for cryptography. 99.9% times inside BigInts I'll keep numbers less than 63 bit long. I'd like to use BigInt as in Python to avoid the problems caused by int, because currently in D there are no integer overflow tests, because Walter doesn't want them.OK, now the truth comes out. You shouldn't be using BigInt for that. That's a very simple task.The first and by a wide margin most important purpose of multi-precision integers is not to represent huge numbers or to do cryptography, but to free the mind of the programmer from being forced to think all the time about possible overflows breaking the code he/she is writing, freeing that part of attention, and allowing him/her to focus more on the algorithm instead.Sorry, the viewpoint that BigInt is a workaround for your personal hobby horse (integer overflow) has ABSOLUTELY ZERO support from me. BigInt is for arithemetic on big integers. It is not for "freeing the programmers mind" of overflow. A type that you can be used as a drop-in replacement for integers but will warn of overflow, is 100 times simpler than BigInt. Why don't you just write it? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 23 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5765They are not system languages. The comparison is irrelevant.Well, Lisp was used plenty as a system language. D wants to be a multi-purpose language, and it already has a multi-precision library, and I see no harm in using this library for purposes not anticipated by the BigInt author.A type that you can be used as a drop-in replacement for integers but will warn of overflow, is 100 times simpler than BigInt. Why don't you just write it?Often I don't just want to watch for overflows, I'd also like the program to give a correct answer if for mistake one intermediate computation needs 70 bits long integers (and I don't know it). In the Project Euler (http://projecteuler.net/ ) there are usually ways to avoid multi-precision numbers, but if you are not careful it's not hard to have larger intermediate values. In this case 64 bit values give wrong results, while the small programs in Python give the correct result. ShedSkin is a Python-->C++ compiler, recently it has added support for 64 bit integers too, this has allowed it to compile 131 out of 204 Python Euler solutions: http://shed-skin.blogspot.com/2010/05/shedskin-versus-psyco-for-131-project.html Most of the solutions that can't be compiled with ShedSkin require multi-precision numbers. Often the final result is a 32 bit number, but intermediate values are larger than 64 bit, and ShedSkin gives a wrong result on them. This is an example why multi-precision computations are useful, to produce correct results. The point here is that overflow errors are not enough. Thank you for your answers Don, and sorry for my insistent nature :-) Feel free to close this bug report when you see it fit. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 23 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5765 See a working version, and the workarounds used: http://rosettacode.org/wiki/Ackermann_function#D -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
May 09 2011
Hi Whats the status on a BigInt implementation of modular exponentiation?
May 03 2012
Stian Pedersen:Whats the status on a BigInt implementation of modular exponentiation?Better to ask such questions in D.learn. The answer: I think there is no code yet to perform powmod efficiently in Phobos. Bye, bearophile
May 03 2012