Tags

, , , ,

This time, i was playing with product on N numbers (1 to N) factorial with python, scala and obviously the equivalent java code to say functional programming is awesome.

Python:

 res = reduce(lambda x,y: x*y, range(1,101)) 

Scala:

(1 to 100).product

But this time i realised one of the values (i guess there should be a lot!) of (python). I expected the scala code to return the right value (i don’t even know how much is 100! and i thought it’ll give me the right one), but it returned 0! (WOW!!!)

But python on the other hand returned me

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000L

Ok lets keep it simple, 20! python returned 121645100408832000, but scala returned 0, Nice, because it considers it as Int. and it exceeded the maximum value of Int. which is

Int.MaxValue
Int = 2147483647

Then i thought i would move to BigInt and it finally gave me the right value.
Scala:

print (BigInt(1) to BigInt(100)).product

The amazing Java code to do the same task:

import java.math.BigInteger;
import java.util.Arrays;

public class Calculator {
    public static void main(String[] args) {
        int[] array = Calculator.getArray(1, 100);
        System.out.println(Arrays.toString(array));
        System.out.println(Calculator.getProduct(array));
    }

    private static BigInteger getProduct(int[] array) {
        BigInteger result = BigInteger.ONE;
        for (int number : array) {
            result = result.multiply(BigInteger.valueOf(number));
        }
        return result;
    }

    private static int[] getArray(int start, int end) {
        int[] array = new int[end - (start - 1)];
        int index = 0;
        while (start <= end)
            array[index++] = start++;
        return array;
    }
}

Then in scala, I printed the factorials of the numbers (trying to find out where it’ll break)

def printVals(arg:Int) = {
	def facts(n:Int, acc:Int):Int = {
		if(n > arg) acc
		else {
			var value = acc * n
			println(n+": "+value)
			facts(n+1, value)
		}
	}
	facts(1,1)
}

printVals(20) gives me the following output,

1: 1
2: 2
3: 6
4: 24
5: 120
6: 720
7: 5040
8: 40320
9: 362880
10: 3628800
11: 39916800
12: 479001600
13: 1932053504
14: 1278945280
15: 2004310016
16: 2004189184
17: -288522240
18: -898433024
19: 109641728
20: -2102132736

Broke at 17 itself. It can only calculate unto 16! after that it overflows.
If i want to add more i need to change the type of acc and function to return Double and it’ll work. for me it felt like i should not care about this.

Python didn’t expect the datatype and it amazingly handled my requests, i tried for 100,1000,100000 it worked, No overflows, it amazingly used dynamic typing and it helped me a lot.

def printFacts(end):
	acc = 1
	for i in range(1,end):
		acc *= i
		print acc

Which ran for most of the inputs.

In static typed languages, i had to think of how far this application can go and i should really design based on the need, (i should not design system with BigInt for numbers ranging less and also i should not use a datatype which results in overflow)

[ I’m using Python 2.7.5 and  Scala 2.11.1 ]

Links:
http://stackoverflow.com/questions/125367/dynamic-type-languages-versus-static-type-languages
https://wiki.python.org/moin/Why%20is%20Python%20a%20dynamic%20language%20and%20also%20a%20strongly%20typed%20language

Question i got:
How far can python handle it? (i tried running it for a while my system got hanged!!!)

if anyone have more to add, or objection please leave a comment.

A gem is not polished without rubbing, nor a man perfected without trials.

Advertisements