0

What I think is a "long" type variable is behaving like an "int" type variable. I feel this is the case because as the variable gets larger and larger, it actual flips over into the negative when it tries to go above 2147483647, which is the maximum value for an "int" type. The maximum value for a "long" type is much more accommodating, obviously.

I guess I should paste my code here. Please don't harsh on the code, it has not been refactored at all. Also, you will see many lame attempts to force the code to treat my variable in question as a "long" type, but the totality of those efforts are not successful.

Note, this code deals with "N choose X" or combinations. The inputs are the number of combinations and the N. The code loops through possible values of X until it either finds a match or until it blows past the possibility of being a match (or until the calculated combinations "goes negative".)

Thanks in advance for the help.

public class primativeLongPractice {

    private static long fctrl (long num) {
          long ans = 1L;
          for (long i=num; i>0; i--) ans = ans * i;
          return ans;
        }

    private static long nchoosex (long n, long x) {
          long y = n - x;
          if (y>x) {
            long temp = y;
            y=x;
            x=temp;
          }
          long ans = 1L;
          for (long i=n; i>x; i--) ans = ans * i;
          return ans/fctrl(y);
        }

    public static long checkchoose(long m, int n) {
          long N = (long)n;
          long combos = 0L;
          long x = 1L; // starting out at 1 and going up
            // compute "n choose x" call it combos
            combos = nchoosex(N,x);
            System.out.println(n + " choose " + x + " equals " + combos + "; m equals " + m);
            if (combos==m) return x;
            while ((combos>1)&&(combos<m)) {
              x = x + 1;
              combos = nchoosex(N,x);
              System.out.println(n + " choose " + x + " equals " + combos + "; m equals " + m);
              if (combos==m) return x;
            }
          System.out.println("Didn't find anything");
          return -1L;
        }

    public static void main(String[] args) {
        long p = 155117520L;
        int q = 30;
        long r = checkchoose(p,q);
        System.out.println("For inputs " + q + " and " + p + " the function returned " + r);
    }
}
3
  • Your long gets temporarily casted to an int in this function because of it's signature: checkchoose(long m, int n) Commented Dec 10, 2015 at 13:51
  • Prior to posting, I tried changing the signature such that n was a long, also changing the type of the variable used to call checkchoose...and this trial did not change the behavior of the program, unfortunately. I then changed it back because it did not shed light on the situation and also the signature of the method is mandated by someone other than me. Commented Dec 10, 2015 at 13:55
  • Regardless, the only likely explanation for this behavior is that the value of your variable is cast to an int at some point. Commented Dec 10, 2015 at 13:58

2 Answers 2

2

I quickly debugged it.

For n = 30, x = 14 your value ans has a long overflow and results in value

ans = -5769043765476591616

and

fctrl(y) = 87178291200

Which makes it seem like the result had rolled due to integer overflow.

Sign up to request clarification or add additional context in comments.

2 Comments

Yes great observation
I really appreciate this assistance. I will run with it and get it fixed within the constraints of the real problem space.
0

A long is indeed more accomodating than an int but it still can overflow.

I have added some extra printing to your code to show the problem:

private static long fctrl(long num) {
    long ans = 1L;
    for (long i = num; i > 0; i--) {
        // Are we going tyo overflow?
        if (ans * i < 0) {
            System.out.println("fctrl overflow!!! " + ans + " at " + i);
        }
        ans = ans * i;
    }
    return ans;
}

private static long nchoosex(long n, long x) {
    long y = n - x;
    if (y > x) {
        long temp = y;
        y = x;
        x = temp;
    }
    long ans = 1L;
    for (long i = n; i > x; i--) {
        if (ans * i < 0) {
            System.out.println("nchoosex overflow!!! " + ans + " at " + i);
        }
        ans = ans * i;
    }
    return ans / fctrl(y);
}

public static long checkchoose(long m, int n) {
    long ln = (long) n;
    long combos = 0L;
    long x = 1L; // starting out at 1 and going up
    // compute "n choose x" call it combos
    combos = nchoosex(ln, x);
    System.out.println(n + " choose " + x + " equals " + combos + "; m equals " + m);
    if (combos == m) {
        return x;
    }
    while ((combos > 1) && (combos < m)) {
        x = x + 1;
        combos = nchoosex(ln, x);
        System.out.println(n + " choose " + x + " equals " + combos + "; m equals " + m);
        if (combos == m) {
            return x;
        }
    }
    System.out.println("Didn't find anything");
    return -1L;
}

public void test() {
    System.out.println("Hello");
    long p = 155117520L;
    int q = 30;
    long r = checkchoose(p, q);
    System.out.println("For inputs " + q + " and " + p + " the function returned " + r);
}

it prints

nchoosex overflow!!! 745747076954880000 at 17

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.