blob: 08f150019807ff25278e6f98d5e675040b3104f7 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package groovy.operator
import groovy.test.GroovyTestCase
/**
* Test Bitwise Operations
*/
class BitwiseOperatorsTest extends GroovyTestCase {
void testBitwiseShift() {
def a = 4
def b = -4
assert a << 1 == 8
assert a << 2 == 16
assert a >> 1 == 2
assert a >> 2 == 1
assert a >>> 1 == 2
assert a >>> 2 == 1
assert b << 1 == -8
assert b << 2 == -16
assert b >> 1 == -2
assert b >> 2 == -1
assert b >>> 1 == 0x7FFFFFFE
assert b >>> 2 == 0x3FFFFFFF
}
void testBitwiseShiftEQUAL() {
def a = 4
a <<= 1
assert a == 8
a <<= 2
assert a == 32
a >>= 1
assert a == 16
a >>= 2
assert a == 4
def b = -4
b <<= 1
assert b == -8
b <<= 2
assert b == -32
b >>= 1
assert b == -16
b >>= 2
assert b == -4
b = -4
b >>>= 1
assert b == 0x7FFFFFFE
b = -8
b >>>= 2
assert b == 0x3FFFFFFE
}
void testBitwiseAnd() {
def a = 13
assert (a & 3) == 1 // 0x0000000D & 0x00000003
assert (a & 7) == 5 // 0x0000000D & 0x00000007
def b = -13
assert (b & 3) == 3 // 0xFFFFFFF3 & 0x00000003
assert (b & 7) == 3 // 0xFFFFFFF3 & 0x00000007
}
void testBitwiseAndOperatorPrecedence() {
def a = 13
assert (a & 3) == 1 // 0x0000000D & 0x00000003
assert (a & 7) == 5 // 0x0000000D & 0x00000007
def b = -13
assert (b & 3) == 3 // 0xFFFFFFF3 & 0x00000003
assert (b & 7) == 3 // 0xFFFFFFF3 & 0x00000007
}
void testBitwiseAndEqual() {
def a = 13
a &= 3
assert a == 1 // 0x0000000D & 0x00000003
a &= 4
assert a == 0 // 0x00000001 & 0x00000004
def b = -13
b &= 3
assert b == 3 // 0xFFFFFFF3 & 0x00000003
b &= 7
assert b == 3 // 0x00000003 & 0x00000007
}
void testBitwiseOr() {
def a = 13
assert (a | 8) == 13 // 0x0000000D | 0x00000008
assert (a | 16) == 29 // 0x0000000D | 0x00000010
def b = -13
assert (b | 8) == -5 // 0xFFFFFFF3 | 0x00000008
assert (b | 16) == -13 // 0xFFFFFFF3 | 0x00000010
}
void testBitwiseOrOperatorPrecedence() {
def a = 13
assert (a | 8) == 13 // 0x0000000D | 0x00000008
assert (a | 16) == 29 // 0x0000000D | 0x00000010
def b = -13
assert (b | 8) == -5 // 0xFFFFFFF3 | 0x00000008
assert (b | 16) == -13 // 0xFFFFFFF3 | 0x00000010
}
void testBitwiseOrEqual() {
def a = 13
a |= 2
assert a == 15 // 0x0000000D | 0x00000002
a |= 16
assert a == 31 // 0x0000000F | 0x0000001F
def b = -13
b |= 8
assert b == -5 // 0xFFFFFFF3 | 0x00000008
b |= 1
assert b == -5 // 0xFFFFFFFB | 0x00000001
}
void testBitwiseXor() {
def a = 13
assert (a ^ 10) == 7 // 0x0000000D ^ 0x0000000A = 0x000000007
assert (a ^ 15) == 2 // 0x0000000D ^ 0x0000000F = 0x000000002
def b = -13
assert (b ^ 10) == -7 // 0xFFFFFFF3 ^ 0x0000000A = 0xFFFFFFF9
assert (b ^ 15) == -4 // 0xFFFFFFF3 ^ 0x0000000F = 0xFFFFFFFC
}
void testBitwiseXorOperatorPrecedence() {
def a = 13
assert (a ^ 10) == 7 // 0x0000000D ^ 0x0000000A = 0x000000007
assert (a ^ 15) == 2 // 0x0000000D ^ 0x0000000F = 0x000000002
def b = -13
assert (b ^ 10) == -7 // 0xFFFFFFF3 ^ 0x0000000A = 0xFFFFFFF9
assert (b ^ 15) == -4 // 0xFFFFFFF3 ^ 0x0000000F = 0xFFFFFFFC
}
void testBitwiseXorEqual() {
def a = 13
a ^= 8
assert a == 5 // 0x0000000D ^ 0x00000008 = 0x000000005
a ^= 16
assert a == 21 // 0x00000005 ^ 0x00000010 = 0x000000015
def b = -13
b ^= 8
assert b == -5 // 0xFFFFFFF3 ^ 0x00000008 = 0xFFFFFFFB
b ^= 16
assert b == -21 // 0xFFFFFFFB ^ 0x00000010 = 0xFFFFFFEB
}
void testBitwiseOrInClosure() {
def c1 = { x, y -> return x | y }
assert c1(14, 5) == 15 // 0x0000000E | 0x00000005 = 0x0000000F
assert c1(0x0D, 0xFE) == 255 // 0x0000000D | 0x000000FE = 0x000000FF
def c2 = { x, y -> return x | y }
assert c2(14, 5) == 15 // 0x0000000E | 0x00000005 = 0x0000000F
assert c2(0x0D, 0xFE) == 255 // 0x0000000D | 0x000000FE = 0x000000FF
}
void testAmbiguityOfBitwiseOr() {
def c1 = { x, y -> return x | y }
assert c1(14, 5) == 15 // 0x0000000E | 0x00000005 = 0x0000000F
assert c1(0x0D, 0xFE) == 255 // 0x0000000D | 0x000000FE = 0x000000FF
def c2 = { x, y -> return x | y }
assert c2(14, 5) == 15 // 0x0000000E | 0x00000005 = 0x0000000F
assert c2(0x0D, 0xFE) == 255 // 0x0000000D | 0x000000FE = 0x000000FF
def x = 3
def y = 5
c1 = { xx -> return y } // -> is a closure delimiter
c2 = { return x & y } // & is a bitAnd
def c3 = { return x ^ y } // & is a bitXor
def c11 = {
xx -> return y // -> is a closure delimiter
}
def c12 = {
return (x | y) // | is a bitOr
}
def c13 = { xx -> return y // -> is a closure delimiter
}
def c14 = { -> return x | y // last | is a bitOr
}
assert c1(null) == 5
assert c2() == 1
assert c3() == 6
assert c11(null) == 5
assert c12() == 7
assert c13(null) == 5
assert c14() == 7
x = 0x03
def d1 = { xx -> return xx } // -> is a closure delimiter
def d2 = { return x & x } // & is a bitAnd
def d3 = { return x ^ x } // & is a bitXor
def d11 = {
xx -> return xx // -> is a closure delimiter
}
def d12 = {
return (x | x) // | is a bitOr
}
def d13 = { xx -> return xx // -> is a closure delimiter
}
def d14 = { -> return x | x // last | is a bitOr
}
assert d1(0xF0) == 0xF0
assert d2(0xF0) == 0x03
assert d3(0xF0) == 0
assert d11(0xF0) == 0xF0
assert d12(0xF0) == 0x03
assert d13(0xF0) == 0xF0
assert d14() == 0x03
}
void testBitwiseNegation() {
assert ~1 == -2 // ~0x00000001 = 0xFFFFFFFE
assert ~-1 == 0 // ~0xFFFFFFFF = 0x00000000
assert ~~5 == 5 // ~~0x00000005 = ~0xFFFFFFFA = 0xFFFFFFF5
def a = 13
assert ~a == -14 // ~0x0000000D = 0xFFFFFFF2
assert ~~a == 13 // ~~0x0000000D = ~0xFFFFFFF2 = 0x0000000D
assert -~a == 14 // -~0x0000000D = -0xFFFFFFF2 = 0x0000000E
}
void testBitwiseNegationType() {
def x = ~7
assert x.class == java.lang.Integer
def y = ~"foo"
assert y.class == java.util.regex.Pattern
def z = ~"${x}"
assert z.class == java.util.regex.Pattern
}
void testBitwiseNegationTypeCallFunction() {
// integer test
assert neg(2).class == java.lang.Integer
assert neg(2) instanceof java.lang.Integer
assert neg(2) == ~2
// long test
assert neg(2L).class == java.lang.Long
assert neg(2L) instanceof java.lang.Long
assert neg(2L) == ~2
// BigInteger test
assert neg(new java.math.BigInteger("2")).class == java.math.BigInteger
assert neg(new java.math.BigInteger("2")) instanceof java.math.BigInteger
assert neg(new java.math.BigInteger("2")) == ~2
// BigInteger test
assert neg(2G).class == java.math.BigInteger
assert neg(2G) instanceof java.math.BigInteger
assert neg(2G) == ~2
assert neg("foo").class == java.util.regex.Pattern
assert neg("foo") instanceof java.util.regex.Pattern
}
void testCorrectAutoboxing() {
// test that the first parameter is boxed correctly, if not then this test
// will possibly produce a verify error
assert (!true | false) == false
assert (true | false) == true
assert (!true & false) == false
assert (true & false) == false
assert (true & !false) == true
}
Object neg(n) {
if (n instanceof java.lang.Integer) {
return ~n
}
if (n instanceof java.lang.Long) {
return ~n
}
if (n instanceof java.math.BigInteger) {
return ~n
}
return ~n.toString()
}
}