Monthly Archives: January 2015

Handling large numbers with C/C++

I will tell you what this is about. I saw a simple looking problem on HackerEarth about finding factorial of given numbers. It looks easy, but another look at the constraints (1<=N<=100) changes everything. Well, not everything, especially if you are going to write it in languages like Python (“dynamically typed”) which has built-in capabilities to handle big numbers, but it is really a trouble to do it in C or any such statically typed language.

So first of all, what exactly is the difference between statically and dynamically typed languages. Dynamically typed languages require their interpreters to detect the type of the variable from the value that is assigned to it. On the other hand, in statically typed languages, the type of the variables must be known at compile time.

Some believe the latter has advantages over the former. As we explicitly state the type, run time errors are reduced and run time performance increases. We won’t get into that discussion here.

So our problem

Before getting into it, I will first write the Python code that worked flawlessly and gave answers to factorials of over 100.

As you can see, it doesn’t get any easier for anybody, no matter how novice he is with programming. But how does one solve the same problem with languages with no native support for big (of order >10^100) numbers? Simple. We make use of algorithms. The first thing that pops in one’s mind when dealing with numbers this large is the use of arrays. Yes, that is the right way to go, or at least the one that worked for me.

So here is the plan. We create an array of integers which will hold a digit in each index, starting with the least significant bit. For example, if we were to store the number 12345 in the array, we would do it like this:

54321

That is, array[0] stores ‘5’, array[1] stores ‘4’ and so on. We have reversed the number for a specific reason. For knowing that reason, you have to go back to your 2nd grade class where you were taught to multiply two two-digit numbers. How did you do that?

4
2
37
x63
111
2220
2331

Got the memory back? Although it may seem a trivial thing now, notice that you never do a multiplication whose result is more than 81, that is, 9×9 which is the product of largest two single digit numbers. So can you somehow make the computer follow the same method to calculate the factorial, such that it never does a >81 digit addition in the entire process, which is well inside the size of the shortest numeric data type in C (unsigned short: 65,535)? Yes, of course. We are coders, right? 😉

To start off, we will need variables. We will use num to accept the input number whose factorial is to be found out. cur stores the result of the calculation i * arr[j] + temp. The least significant digit from cur (for example 3, in case of 123) goes into arr[j] while the remaining digits get stored in the temp variable. Follow the above step till the end of the array which we initially denote by pos variable. pos is initialized and assigned 1, as we initialize our arr[] with arr[0]=1 (since we will be using this value to multiply subsequent 2,3,4…num, we don’t want our answer to evaluate to 0).

After this loop, we will need to empty out the carry forward integer in our temp variable. It will be done in the reverse order as well, but here, we will increment pos to make it always point to the number of digits in arr[].

Finally you can print our the arr[] in the reverse order to get the expected answer and this should not surprise you since we have been doing storing of the numbers in reverse order in our arr[]. Here is the C++ code that I wrote. I didn’t cross check the results for larger values of num, so take care with that.

So that was it for this short article. I am reading more on GMP (GNU Multiple Precision Arithmetic Library) that is written exactly for this purpose. Nevertheless, it is always good to know how to do it by hand. Thank you.

What is GNU/Linux

The following is a piece from my previous blog. I had written it in one of my diaries and since that blog of mine is no more, I would like to publish it here. My views on Linux/GNU and why it is one of the most amazing thing you will ever learn. Here it goes…

What is Linux?

 

In the early 1990s, Finnish computer science student Linus Torvalds began hacking on Minix, a small Unix-like operating system for PC then used in college OS courses. He decided to improve the main software component underlying Minix, called the kernel, by writing his own.
In late 1991, Torvalds published the first version of this kernel on the Internet and called it Linux, a mix of his own name and Minix.
When Torvalds published Linux, he used the GNU’s General Public License which made the software free to use, copy and modify by anyone provided that the copies and any variations are kept equally free. Torvalds also invited contributions from other programmers. Though these contributions came slowly at first, as Internet evolved, thousands of hackers and programmers from around the globe contributed to his free software project.
The Linux software developed so quickly that today, Linux is a complete modern OS, which can be used by programmers and non-programmers alike.

What makes Linux so special?

 

The building blocks of Linux OS are the ‘tools’. If you ask for a rough definition, ‘A tool is a small piece of code that is designed to perform one and only one task with great precision’.That’s it.
The entire Linux concept is based on thiese little pieces of code. Most operating systems (like Microsoft Windows) have large utilities called applications. These applications can perform a large number of functions or tasks, for example word processors, presentation designers or a web browser. Along with their main tasks, this applications also perform some side tasks like search, replace, spelling checks often found in all applications. The source code for these applications is stored separately (or each binary has a separate set of these instructions) for each application, hence taking up more space on disk as well in memory.
These applications are often closed source, meaning it will do your job like magic, but you will never understand what is happening in the background (like what methods are implemented to search, can it be revised to make it more efficient and such). Hence programmers can never learn, use or build anything from it. The end result of this approach is that the same functions inside all these different applications must be built by programmers from scratch, separately and independently each time – a set back to the progress of the society as a whole and waste of countless man hours and energy that programmers use to code the same thing again and again.
This is where Linux is special. Most of the tools (or all, for that matter) are open sourced, programmers can integrate them straight away without much effort to build something that takes the community as a whole ahead at a faster pace. Also, you don’t have to spend any time debugging the tools most of the time because it is almost always that someone has used it in production before and rectified the bugs, as they are always there. Saves a lot of time for us, as developers.
There is also this interesting functionality called ‘pipes’. Pipes behave as one would expect from the name. It ‘pipes’ the output of one tool to the input of another. If you didn’t think about it already, you can create powerful tool chains that do multiple tasks in co-ordination giving the expected result, and using individual tools in sequence would have. Just as the tensile strength of steel is greater than the added strengths of its components nickel, cadmium and iron – multiple tools could be combined to some unpredictable results than that of the individual tools, called as the concept of synergy, basic philosophy of all GNU/Linux tools.
These basic tools which have been improved over these decades are crafted to do a particular task to perfection, and even if it doesn’t fit your requirement, you can always grab the source, edit it accordingly and use it. If you want to keep up with the open source spirit, post it online so it will save some time of someone with the same problem. These small tools can be a power weapon in the hands of a Linux expert, or Wizard as we call them.
Note that when I use the term ‘Linux, I mean GNU/Linux. The entire thing wouldn’t be possible with either one. Linux is the kernel and rest of the OS is GNU. More information here: https://www.gnu.org/gnu/linux-and-gnu.html

Jumping over multiple programming languages

I just happened to take a look at my own blog. Starting with some posts about python, I went to C, then PHP-MySQL and then Javascript. All of this in around 3 months. Now, it is great to know multiple languages, but the thing I feel is, you must ‘know’ them. Knowing in the sense, the underlying philosophy, best practices and such. I have started with at least 10 languages this year. I can code little bits in all of them, namely C, Java, Python, PHP, Javascript and some other like database, HTML/CSS which are not-so-much-programming languages. Problem is, I cannot code fluently in any of the above listed languages. I just tend to get bored by doing a language after some time and then jump to something else. Something needs to be done, right?

Actually, I didn’t notice this myself. Friends, with whom I hangout, told me that I needed to concentrate on one thing, until I master it, before moving to something else. I couldn’t agree more, but also couldn’t decide what needs to be done. So kept trying different things till I get something that would keep me distracted for long enough.

I started with web development. I hate PHP, although I also tend to code in it the most because it is efficient for quick dirty works. Python happens to be one of my favorite languages, because of the neatness and power. But at the same time, coming from C, I don’t feel the depth in other languages that I got in C.

Web programming is great for some quick compliments. LOL. Just after a week, I could write great pieces of code that would amaze everyone. But deep down somewhere, I didn’t feel good about myself. Its like, choosing the easy path rather than the challenging one. So I thought again, about some other stream. Yes, software programming is pretty good.

So I started with Java. I did learn all the basics and some intermediate stuff. Java is great, but still, I missed C. I needed something close to the OS. I needed a language that I could use to interact with my Arduino. I needed something like C. So why not C again, perfecting it?

Yes, I felt, getting back to C seemed to be the best way to go.

Then, out of nowhere, I got to attend Bjarne Stroustrup‘s lecture at IIT-Bombay. Although I never got to get into the actual seminar, his mere presence was enough to push me into C++. I read about it, and even watch some online videos about C++ and opinion from experts about it. Seemed perfect. The control and power of C, the flexibility of Java and the usability of (almost) Python.

I have now been doing C++ for about 2 weeks. Not much really, basic syntax and stuff. Important thing is, I am enjoying it. I really hope I stick to it for some time now till I master it. I don’t want to be an example of

jack of all trades and master of none

Let’s hope my next post here has some serious C++ in it.