Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I'm doing some Project Euler problems and most of the time, the computations involve large numbers beyond int, float, double etc.
Firstly, I know that I should be looking for more efficient ways of calculation so as to avoid the large number problem. I've heard of the Bignum libraries.
But, for academics interests, I'd like to know how to code my own solution to this problem.
Can any expert please help me out? (My language is C)
You need to store the big numbers in a base that your computer can easily handle with its native types, and then store the digits in a variable length array. I'd suggest that for simplicity you start by storing the numbers in base 10 just to get the hang of how to do this. It will make debugging a lot easier.
Once you have a class that can store the numbers in this form, it's just a matter of implementing the operations add, subtract, multiply, etc. on this class. Each operation will have to iterate over digits of its operands and combine them, being careful to carry correctly so that your digits are never larger than the base. Addition and subtraction are simple. Multiplication requires a bit more work as the naive algorithm requires nested loops. Then once you have that working, you can try implementing exponentiation in an efficient manner (e.g. repeated squaring).
If you are planning to write a serious bignum implementation, base 10 won't cut it. It's wasteful of memory and it will be slow. You should choose a base that is natural for the computer, such as 256 or the word size (2**32). However this will make simple operations more difficult as you will get overflows if you naively add two digits, so you will need to handle that very carefully.
C is not a good choice for Project Euler. The benefits of C are raw speed, machine portability (to an extent, with standard C), language interoperability (if some language communicates with another, C is a popular first choice), sticking close to a specific library or platform's API (because C is common, e.g. OS API), and a stable language & stdlib. None of these benefits apply to solving Project Euler problems. Not even raw speed, because most of the problems aren't about raw computation, but understanding the algorithm required, and you can sit there all day and wait before submission.
If you are attempting Project Euler problems to broaden your experience with C, that's perfectly fine, just realize this experience doesn't necessarily apply to long-lived and real-world C projects you may work on.
For this kind of short, one-off problem those languages commonly described as "scripting languages" will work better, faster (in dev time), and easier. Try Python, it stays close to C in many ways, including a C API, and out of the various popular "scripting languages" is possibly the one for which you will find the most use in conjunction with C projects.
This may become an unpopular answer, but it isn't a rant—plus I really like C and use C/C++ often—and there is an explicit answer here to your problem: "don't use C", with your final large number solution depending on which alternative you choose. Again picking on Python, integers do not have an upper bound (note below), and I use this to naturally code answers to Project Euler problems, where in other languages I have to use a painful-by-comparison alternative number library.
(Python integers: There are two integer types in 2.x, 'int' and 'long' (which have been completely unified in 3.x). The conversion between them is practically seamless, and 'long' allows arbitrarily large values, instead of just being a bigger 'int' type as C's long is.)
A popular bignum library for C/C++ is the GNU MP Bignum Library. I've used it for several Project Euler problems, but fact remains that C isn't a very suitable language for Euler-problems. If performance was more important C would have more to give, but now you're much better off using a language which built in bignum support, such as Ruby (there are lots of others).
A simple way is to think of the number as its string representation in base b. Suppose b=10, simple arithmetic operation like addition on two such strings can be done using the same method we use when adding numbers by pen and paper. The same goes for other simple operations. For better results, you can take a larger base.
A simple bignum implementation like that should be enough for most Project Euler problems (probably all, but I haven't solved much at Euler so can't be sure), but there are ways of using much faster algorithms for operations such as multiplication and division/mod.
Although I recommend writing your own bignum for practice, if you are really stuck you can take ideas from the code of already implemented bigint libraries. For a serious implementation something like gmp is the obvious choice. But you cana also find small bigints coded by other people when solving similar practice problem online (e.g. Abednego's bigint.cpp).
Here's a nice and simple bignum module for C. You can learn from it for ideas. The C code isn't the highest quality, but the algorithm is well implemented and quite common.
For more advanced stuff, look up GMP.
If you want a nice C++ version (I know, you said C, but this is really interesting code), take a look at the internals of CGAL: http://www.cgal.org/
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I’m looking for a good arbitrary precision math library in C or C++. Could you please give me some advices or suggestions?
The primary requirements:
It must handle arbitrarily big integers—my primary interest is on integers. In case that you don’t know what the word arbitrarily big means, imagine something like 100000! (the factorial of 100000).
The precision must not need to be specified during library initialization or object creation. The precision should only be constrained by the available resources of the system.
It should utilize the full power of the platform, and should handle “small” numbers natively. That means on a 64-bit platform, calculating (2^33 + 2^32) should use the available 64-bit CPU instructions. The library should not calculate this in the same way as it does with (2^66 + 2^65) on the same platform.
It must efficiently handle addition (+), subtraction (-), multiplication (*), integer division (/), remainder (%), power (**), increment (++), decrement (--), GCD, factorial, and other common integer arithmetic calculations. The ability to handle functions like square root and logarithm that do not produce integer results is a plus. The ability to handle symbolic computations is even better.
Here are what I found so far:
Java's BigInteger and BigDecimal class: I have been using these so far. I have read the source code, but I don’t understand the math underneath. It may be based on theories and algorithms that I have never learnt.
The built-in integer type or in core libraries of bc, Python, Ruby, Haskell, Lisp, Erlang, OCaml, PHP, some other languages: I have used some of these, but I have no idea which library they are using, or which kind of implementation they are using.
What I have already known:
Using char for decimal digits and char* for decimal strings, and do calculations on the digits using a for-loop.
Using int (or long int, or long long) as a basic “unit” and an array of that type as an arbitrary long integer, and do calculations on the elements using a for-loop.
Using an integer type to store a decimal digit (or a few digits) as BCD (Binary-coded decimal).
Booth’s multiplication algorithm.
What I don’t know:
Printing the binary array mentioned above in decimal without using naive methods. An example of a naive method: (1) add the bits from the lowest to the highest: 1, 2, 4, 8, 16, 32, … (2) use a char*-string mentioned above to store the intermediate decimal results).
What I appreciate:
Good comparisons on GMP, MPFR, decNumber (or other libraries that are good in your opinion).
Good suggestions on books and articles that I should read. For example, an illustration with figures on how a non-naive binary-to-decimal conversion algorithm works would be good. The article “Binary to Decimal Conversion in Limited Precision” by Douglas W. Jones is an example of a good article.
Any help in general.
Please do not answer this question if you think that using double (or long double, or long long double) can solve this problem easily. If you do think so, you don’t understand the issue in question.
GMP is the popular choice. Squeak Smalltalk has a very nice library, but it's written in Smalltalk.
You asked for relevant books or articles. The tricky part of bignums is long division. I recommend Per Brinch Hansen's paper Multiple-Length Division Revisited: A Tour of the Minefield.
Overall, he fastest general purpose arbitrary precision library is GMP. If you want to work with floating point values, look at the the MPFR library. MPFR is based on GMP.
Regarding native arbitrary precision support in other languages, Python uses its own implementation because of license, code size, and code portability reasons. The GMPY module lets Python access the GMP library.
See TTMath, a small templated header-only library free for personal and commercial use.
I've not compared arbitrary precision arithmetic libraries to each other myself, but people who do seem to have more or less uniformly settled on GMP. For what it's worth, the arbitrary precision integers in GHC Haskell and GNU Guile Scheme are both implemented using GMP, and the fastest implementation of the pidigits benchmark on the language shootout is based on GMP.
What about Pari? It’s built on top GMP and provides all the other goodies about number theory operations you’ll ever need (and many symbolic computation stuff).
I am developing an algorithm for an audio application for mobile platforms. It appears to me that currently the float point calculation support on many mobile processors is not ubiquitous and developing in fixed point would be a safer bet.
I have written FFT routines in float point form for some time now to a degree of success, however writing one in fixed point turned out to be rather difficult. Namely, I would be happy to improve the precision, as well as to find a way to handle potential overflows. The problem is, unlike float point FFTs, descriptions of fixed point FFT algorithms are hard to come by on the Internet.
Has anyone had some experience developing such algorithms?
Your first choice should probably be to use a native-optimized FFT. There are processing requirement for fixed point FFTs that are difficult to express efficiently in portable C (or any language probably): saturation arithmetic is probably the biggest obstacle. Assembly libraries will tend to take advantage of processor-specific instructions for these .
If you still want a portable ANSI C fixed point FFT, I only know of one choice: kissfft. (Disclaimer : I wrote it)
I have read great things about http://anthonix.com/ffts/index.html - this works well on mobile platforms - The site contains benchmarks
I have been working on an automated tool that converts floating-point C code to fixed-point, with a variety of options for tradeoffs between accuracy and execution time. I have had good results with a number of algorithms, including a 2D 8x8 discrete cosine transform. My target platform is typically an ARM Cortex-M processor but similar results should be achievable on other platforms. Would you be interested in letting me take a crack at your FFT?
I want to code a genetic algorithm in C for optimizing a function of 10 variables (x1 to x10). However I am not able to figure out which encoding I should use. I have mostly seen binary encoding being used in example but the variables in my case can take real values. Also, is value encoding a good option for these types of problems?
For real valued problems I would suggest to try CMA-ES or another ES variant. CMA-ES certainly is the current state of the art for real-valued problems. It is designed to find good solutions in multidimensional problems quickly. There are implementations available on Hansen's page. There's also a C# implementation in the work for HeuristicLab. Evolution strategies are algorithms that were specifically designed for real-valued optimization problems. They are very similar to genetic algorithms (both were invented around the same time, but in different places). The main distinction is that for ES the main driver is mutation and it features a clever adaption of the mutation strength. Without this adaption the (local) optimum cannot be located in time. CMA-ES is easy to configure, all it needs is the initial standard deviation and optionally the population size (otherwise there's a formula that estimates this given the problem size).
Genetic algorithms can of course also be applied, but you have to use some specific operators which are able to mutate variables only with very small degree. For example there's the Breeder Genetic Algorithm from Mühlenbein. In general however genetic algorithms are more suited for problems that need a right combination of things. E.g. which items to include in a knapsack problem or which functions and terminals to combine to a formula (genetic programming). Less for problems, where you need to find the right value for something. Although of course there are variants of the genetic algorithm to solve these, look for Real coded Genetic Algorithm (RCGA or RGA).
Another algorithm suited for real-valued problems is Particle Swarm Optimization, but in my opinion it is harder to configure. I'd start with SPSO-2011 the 2011 standard PSO.
If your problem contains integer variables choices become more difficult. Evolution strategies do not perform so well when variables are discrete, because the adaptation schemes for integer variables are different. A genetic algorithm becomes an interesting first-choice algorithm again.
A genetic algorithm is best used when two answers that are pretty close to optimal will make something else pretty close to optimal when combined. The problem with a pure binary encoding is that if you don't check your crossover you end up getting two answers which may not have all that much to do with the original answers.
That said, this is only really an issue if your number of variables is very small and the amount of data in your variables is large. As far as picking an encoding, it's more of an art than a science and it depends on your problem. I would suggest going with an encoding that fits the amount of precision you want. With 10 variables you won't got that far wrong however you encode it, an 8-bit ASCII encoder would probably work fine.
Hope that helps.
I have a number of very large length may be upto 50 digits. I am taking that as string input. However, I need to perform operations on it. So, I need to convert them to a proper base, lets say, 256.
What will be the best algorithm to do so?
Multiple-precision arithmetic (a.k.a. bignums) is a difficult subject, and the good algorithms are non intuitive (there are books about that).
There exist several libraries handling bignums, like e.g. the GMP library (and there are other ones). And most of them take profit from some hardware instructions (e.g. add with carry) with carefully tuned small chunks of assembler code. So they perform better than what you would be able to code in a couple of months.
I strongly recommend using existing bignum libraries. Writing your own would take you years of work, if you want it to be competitive.
See also answers to this question.
What would be the best programming language for very large arrays and very large numbers?
With arrays over 30,000 indexes
And numbers over 100 digits
Also it needs to be efficient, or easy to make efficient.
Thanks.
Almost any programming language worth its salt should have these characteristics, and frankly I don't think I'd want to use any language that can't handle arrays of 30,000 elements. I'll list a few that have good support for very large numbers:
python. Python 3 has automatic support for large numbers as the default number type grows as necessary, and has some really awesome math libraries. Other languages may be ever so slightly faster, but unless for some reason you know for sure that python won't be good enough I'd start there.
C#. This will mostly bind you to windows, but its very popular, fast, and meets your requirements.
Java. Cross platform, mature support with BigInteger.
Haskell. Pretty seamless conversions to large numbers and powerful math support. If you have a strong mathematics background Haskell will feel pretty natural. If you already know functional programming or don't mind devoting a fascinating few hours to learning it, this is a good choice.
C/C++. Very fast, but a little more complex to develop in. You'll probably get better results in large number support with something else. I'd only look into C++ if you've tried optimizing code in another languages and its still not fast enough, unless you have a specific reason to not use an intermediately compiled language.
The truth of the matter is that its hard to find a programming language that doesn't support these things, and if you could I probably wouldn't use it for anything because its probably not that mature. Do you have any other requirements that would help us narrow it down further for you? :D
The array is not the issue. Numbers consisting of 100 numerals (digits) is a huge issue. I don't have a good answer to the question (out of date as it is) but as this comes up readily in Google I'll mention that most languages only support between 32 to 64 bit numbers.
(I know that the C family of languages, PHP, as3 and Java don't support massive numbers.)
For example a 32 bit number would allow a range of 0 to 4,294,967,295 (2^32-1) which is only 10 numerals (Actually more like 9 because the limit is by size, not numerals), a whole order of magnitude less than the required 100 digits the questioner was after.
That said I know that there are cases of people implementing support for large numbers in C and AS3...
Python with NumPy is probably what you want.
I always found Fortran to be quite nice when dealing with arrays, esp. with multi-dimensional ones. If you are dealing with very large numbers, you will probably need to define your own data type or live with a loss of precision, though. Or use this: http://www.fortran.com/big_integer_module.f95 .
But it depends a bit on what you want to do. Fortran is nice for numerical computations, and not so nice for about everything else.