package TestCase::Subtract {
  #
  # Spec tests
  #
  
  sub subtract_byte_byte : int () {
    my $total = (byte)126 - (byte)127;
    
    unless ($total == -1) {
      return 0;
    }
    
    unless ($total isa int) {
      return 0;
    }
    
    return 1;
  }

  sub subtract_short_short : int () {
    my $total = (short)32766 - (short)32767;
    
    unless ($total == -1) {
      return 0;
    }
    
    unless ($total isa int) {
      return 0;
    }
    
    return 1;
  }

  sub subtract_int_byte : int () {
    my $total = 1 - (byte)3;
    
    unless ($total == -2) {
      return 0;
    }
    
    unless ($total isa int) {
      return 0;
    }
    
    return 1;
  }

  sub subtract_int_short : int () {
    my $total = 1 - (short)3;
    
    unless ($total == -2) {
      return 0;
    }
    
    unless ($total isa int) {
      return 0;
    }
    
    return 1;
  }

  sub subtract_byte_int : int () {
    my $total = (byte)3 - 1;
    
    unless ($total == 2) {
      return 0;
    }
    
    unless ($total isa int) {
      return 0;
    }
    
    return 1;
  }

  sub subtract_short_int : int () {
    my $total = (short)3 - 1;
    
    unless ($total == 2) {
      return 0;
    }
    
    unless ($total isa int) {
      return 0;
    }
    
    return 1;
  }

  sub subtract_int_int : int () {
    my $total1 = 2147483646 - 1;
    
    unless ($total1 == 2147483645) {
      return 0;
    }
    
    unless ($total1 isa int) {
      return 0;
    }

    return 1;
  }

  sub subtract_long_long : int () {
    my $total1 = 9223372036854775807L - 1L;
    
    unless ($total1 == 9223372036854775806L) {
      return 0;
    }
    
    unless ($total1 isa long) {
      return 0;
    }

    my $total2 = -9223372036854775807L - 1L;

    unless ($total2 == -9223372036854775808L) {
      return 0;
    }
    
    return 1;
  }

  sub subtract_int_float : int () {
    my $total = 1 - 0.25f;
    
    unless ($total == 0.75f) {
      return 0;
    }
    
    unless ($total isa float) {
      return 0;
    }
    
    return 1;
  }

  sub subtract_int_double : int () {
    my $total = 1 - 0.25;
    
    unless ($total == 0.75) {
      return 0;
    }
    
    unless ($total isa double) {
      return 0;
    }
    
    return 1;
  }

  sub subtract_minus : int ()  {
    my $total1 = 12 - 3;
    my $total2 = 12 + (-3);

    unless ($total1 == $total2) {
      return 0;
    }
    
    return 1;
  }

  sub subtract_zero_minus : int ()  {
    my $total1 = 0 - 3;
    my $total2 = -3;

    unless ($total1 == $total2) {
      return 0;
    }
    
    return 1;
  }

  sub subtract_float_float : int () {
    my $total = 0.75f - 0.25f;
    
    unless ($total == 0.5f) {
      return 0;
    }
    
    unless ($total isa float) {
      return 0;
    }
    
    return 1;
  }
  sub subtract_double_double : int () {
    my $total = 0.75 - 0.25;
    
    unless ($total == 0.5) {
      return 0;
    }
    
    unless ($total isa double) {
      return 0;
    }
    
    return 1;
  }

  sub subtract_double_double_big : int () {
    my $total = 2147483647.5 - 0.25;
    
    unless ($total == 2147483647.25) {
      return 0;
    }
    
    unless ($total isa double) {
      return 0;
    }
    
    return 1;
  }


  #
  # Optional tests
  #
  sub subtract : int () {
    my $value1 : int = 1 - 2;
    my $value2 : int = (byte)1 - 3;
    my $value3 : int = 1 - (byte)4;
    my $value4 : int = (short)1 - 5;
    my $value5 : int = 1 - (short)6;
    my $value6 : int = (byte)1 - (byte)7;
    my $value7 : int = (short)1 - (short)8;
    my $value8 : int = (byte)1 - (short)9;

    if ($value1 == -1) {
      if ($value2 == -2) {
        if ($value3 == -3) {
          if ($value4 == -4) {
            if ($value5 == -5) {
              if ($value6 == -6) {
                if ($value7 == -7) {
                  if ($value8 == -8) {
                    return 1;
                  }
                }
              }
            }
          }
        }
      }
    }

    return 0;
  }
  sub subtract_int_max : int () {
    return (int)2147483647 - (int)1;
  }
  sub subtract_int_min : int () {
    return (int)-2147483647 - (int)1;
  }
  sub subtract_int_underflow : int () {
    return (int)-2147483648 - (int)1;
  }
  sub subtract_long_max : long () {
    return (long)9223372036854775807L - (long)1;
  }
  sub subtract_long_min : long () {
    return (long)-9223372036854775807L - (long)1;
  }
}
