0

I wrote a haskell function to produce prime factorizations for numbers until a certain threshould – made of some prime factors. A minimal working code can be found here: http://lpaste.net/117263

The problem: It works very good for "threshould <= 10^9" on my computer. But beginning with "threshould = 10^10" the method don't produce any results on my computer – I never see (even not) the first list element on my screen. The name of the critical function is "exponentSets". For every prime in the list 'factors', it computes the possible exponents (with respect to already chosen exponents for other primes). Further commends are in the code. If 10^10 works good on your machine, try it with an higher exponent (10^11 ...).

My question: what is responsible for that? How can I improve the quality of the function "exponentSets"? (I'm still not very experienced in Haskell so someone more experienced might have an Idea)

user2292040
  • 305
  • 1
  • 7
  • 1
    `10^10` overflows a 32 bit integer. Check that this is not the issue by adding `print threshould` in your main and confirming you are using 64 bits integers. – chi Dec 26 '14 at 13:08
  • Thank you for your comment! Yes I checked it and it uses 64-bit ints. – user2292040 Dec 26 '14 at 13:12
  • Well the exact value on which this occurs is ``2 ^ 32 + 1`` on my machine. Is this true for yours too? **NOTE:** Yes I checked, I am using 64-bit integers. – ThreeFx Dec 26 '14 at 13:34
  • For me it's also 2^32 + 1 +RTS -K1G -kc64K doesn't change anything. – user2292040 Dec 26 '14 at 13:40

1 Answers1

4

Even though you are using 64-bit integers, you still do not have enough capacity to store a temporary integer which is created in intLog:

intLog base num =
    let searchExtend lower@(e, n) =
        let upper@(e', n') = (2 * e, n^2) -- this line is what causes the problems
    -- some code
    in (some if) searchExtend (1, base)

rawLists is defined like this:

rawLists = recCall 1 threshould

Which in turn sets remaining_threshould in recCall to

threshould `quot` 1 -- same as threshould

Now intLog gets called by recCall like this:

intLog p remaining_threshould

which is the same as

intLog p threshould

Now comes the interesing part: Since num p is smaller than your base threshold, you call searchExtend (1, base), which then in turn does this:

searchExtend (e, n) = 
      let (e', n') = (2 * e, n ^ 2)

Since n is remaining_threshould, which is the same as threshould, you essentially square 2^32 + 1 and store this in an Int, which overflows and causes rawLists to give bogus results.

(2 ^ 32 + 1) ^ 2 :: Int is 8589934593
(2 ^ 32 + 1) ^ 2 :: Integer is 18446744082299486209
ThreeFx
  • 7,250
  • 1
  • 27
  • 51