# Vergleich von Integers

# I_I_comp(x,y) vergleicht zwei Integers x und y.
# Ergebnis: 0 falls x=y, +1 falls x>y, -1 falls x<y.
  global signean I_I_comp (object x, object y)
  {
    # Methode:
    # x und y haben verschiedenes Vorzeichen ->
    #    x < 0 -> x < y
    #    x >= 0 -> x > y
    # x und y haben gleiches Vorzeichen ->
    # x Fixnum ->
    #    y Fixnum -> direkt vergleichen.
    #    y Bignum ->
    #       y > 0 -> x < y
    #       y < 0 -> x > y
    # x Bignum ->
    #    y Fixnum ->
    #       x < 0 -> x < y
    #       x > 0 -> x > y
    #    y Bignum ->
    #       falls beide gleich lang -> wortweise vergleichen
    #       x kürzer als y -> bei x,y > 0 : x < y, bei x,y < 0 : x > y
    #       y kürzer als x -> bei x,y > 0 : x > y, bei x,y > 0 : x < y
    var uintC xlen;
    var uintC ylen;
    if (!(R_minusp(x)))
      # x>=0
      if (!(R_minusp(y)))
        # x>=0, y>=0
        if (I_fixnump(x))
          # x Fixnum >=0, y>=0
          if (I_fixnump(y)) {
            # x Fixnum >=0, y Fixnum >=0
            if (as_oint(x) == as_oint(y))
              return signean_null;
            else if (as_oint(x) > as_oint(y))
              return signean_plus;
            else
              return signean_minus;
          } else
            # x Fixnum >=0, y Bignum >0
            return signean_minus; # x<y
        else
          # x Bignum >0, y>=0
          if (I_fixnump(y))
            # x Bignum >0, y Fixnum >=0
            return signean_plus; # x>y
          else
            # x und y Bignums >0
            if (eq(x,y))
              return signean_null; # gleiche Pointer -> selbe Zahl
            else {
              xlen = Bignum_length(x);
              ylen = Bignum_length(y);
              if (xlen==ylen)
               samelength:
                # gleiche Länge -> digitweise vergleichen
                return compare_loop_up(&TheBignum(x)->data[0],&TheBignum(y)->data[0],xlen);
              else
                return (xlen > ylen ? signean_plus : signean_minus);
            }
      else
        # x>=0, y<0
        return signean_plus; # x>y
    else
      # x<0
      if (!(R_minusp(y)))
        # x<0, y>=0
        return signean_minus; # x<y
      else
        # x<0, y<0
        if (I_fixnump(x))
          # x Fixnum <0, y<0
          if (I_fixnump(y)) {
            # x Fixnum <0, y Fixnum <0
            if (as_oint(x) == as_oint(y))
              return signean_null;
            else if (as_oint(x) > as_oint(y))
              return signean_plus;
            else
              return signean_minus;
          } else
            # x Fixnum <0, y Bignum <0
            return signean_plus; # x>y
        else
          # x Bignum <0, y<0
          if (I_fixnump(y))
            # x Bignum <0, y Fixnum <0
            return signean_minus; # x<y
          else
            # x und y Bignums <0
            if (eq(x,y))
              return signean_null; # gleiche Pointer -> selbe Zahl
            else {
              xlen = Bignum_length(x);
              ylen = Bignum_length(y);
              if (xlen==ylen)
                # gleiche Länge -> wortweise vergleichen
                goto samelength; # wie oben
              else
                return (xlen > ylen ? signean_minus : signean_plus);
            }
  }

