0%

Go_Fundamental_Learning_Operators

Defination

An Operator in a programming language is a symbol that tell the compiler to perform specific mathematical, relation or logical operation and got the result.

Binary Operator || Unary Operator

A binary operator operation takes two operands and a unary operator operation takes only one operand.

Operators Precedence In Go

The following is the operator precedence in Go.

1
2
3
4
5
*   /   %   <<  >>  &   &^  // first
+ - | ^ // second
== != < <= > >= // third
&& // fourth
|| // fifth

Top ones have higher precedence. The operators in the same line have the same precedence. Of course () is used to promote precedence.

Operators in Go

Operators feature

Type Operator Name Feature
Arithmetic_Binary_Basic + addition Two Operands must be both values of the same numeric type.
Arithmetic_Binary_Basic - subtraction Same with above one
Arithmetic_Binary_Basic * multiplication Same with above one
Arithmetic_Binary_Basic / division Same with above one
Arithmetic_Binary_Basic % remainder Two Operands must be both values of the same integer type.
Arithmetic_Binary_Bitwise & bitwise and Same with above one
Arithmetic_Binary_Bitwise | bitwise or Same with above one
Arithmetic_Binary_Bitwise ^ bitwise xor Same with above one
Arithmetic_Binary_Bitwise &^ bitwise clear Same with above one
Arithmetic_Binary_Bitwise << bitwise left shift The left operand must be an integer and the right operand must be also an integer
Arithmetic_Binary_Bitwise >> bitwise right shift Same with above one
Arithmetic_Unary + positive +n is equivalent to 0 + n.
Arithmetic_Unary - negative -n is equivalent to 0 - n.
Arithmetic_Unary ^ bitwise complement ^n is equivalent to m ^ n, where m is a value all of which bits are 1. For example, if the type of n is int8, then m is -1, and if the type of n is uint8, then m is 0xFF.
String_Binary + string concatenation The two operands must be both values of the same string type.
Boolean_Binary && boolean and The two operands must be both values of the same boolean type.
Boolean_Binary || boolean or Same with above one
Boolean_Unary ! boolean not The type of the only operand must be a boolean type.
Comparsion_Binary == equal to Generally, the types of its two operands must be the same
Comparsion_Binary != not qeual to Same with above one
Comparsion_Binary < less thann The two operands must be both values of the same integer type, floating-point type or string type.
Comparsion_Binary <= less than or equal to Same with above one
Comparsion_Binary > larger than Same with above one
Comparsion_Binary >= larger than or equal to Same with above one

Arithmetic Operators Tips

There is some tips about arithmetic operators.

About OverFlows

Overflows are not allowed for typed constants but are allowed for non-constant and untyped constant, ether the values are intermediate or final results;

  • Allowed:
    • Untyped constant: the value wil not be truncated
    • Non constant: the vlue will be truncated;
  • Not Allowed:
    • Typed constant
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import "fmt"

func main() {
// 1.Results are non-constant, the result are allow with overflow condition
var a, b uint8 = 255, 1
var c = a + b
var d = a << 1
fmt.Printf("Over flow with non constant, the result with be truncated %v \n", c)
fmt.Printf("Over flow with non constant, the result with be truncated %v \n", d)

// 2.Results are untyped constant, the result are allow with overflow condition
const X = 0x1FFFFFFF * 0x1FFFFFFF // overflow int, complie ok
const R = 'a' * 0x1FFFFFFF // overflow rune, complie ok
fmt.Printf("Over flow with untyped constant, the result with be wrapped %v \n", X)
// fmt.Printf("Over flow with untyped constant, the result with be wrapped %v \n", R)
// const R untyped rune = 52076478367
//overflow rune cannot use R (untyped rune constant 52076478367) as rune value in argument to fmt.Printf (overflows)

// 3.Results are typed constant, the result are not allow with overflow condition
const Y = 128 - int8(1) // error: 128 overflows int8
const Z = uint8(255) + 1 // error: 256 overflow uint8
}

About the results of arithmetic operator operations

Except bitwise shift operations, the result of a binary arithmetic operator operation

  • is a typed value of the same type of the two operands if the two operands are both typed values of the same type.

  • is a typed value of the same type of the typed operand if only one of the two operands is a typed value.

    1
    In the computation, the other (untyped) value will be deduced as a value of the type of the typed operand. In other words, the untyped operand will be implicitly converted to the type of the typed operand.
  • is still an untyped value if both of the two operands are untyped. The default type of the result value is one of the two default types and it is the one appears latter in this list: int, rune, float64, complex128. For example, if the default type of one untyped operand is int, and the other one is rune, then the default type of the result untyped value is rune.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import "fmt"

func main() {
// Three untyped values
// There default types are : int rune(int32) complex
const X, Y, Z = 6, 'A', 31i
fmt.Printf("Default types are %T, %T, %T \n", X, Y, Z)
// Default types are int, int32, complex128

// Two typed values
var a, b int = X, Y

// Precendence: int< rune< flloat64< complex128
// type d is the default type rune
d := X + Y
// type e is the variable type int
e := Y - a
// type f it the variable type a and b , int
f := a * b
// type g is the default type complex
g := Z * Y
fmt.Printf("Types are %T, %T, %T, %T \n", d, e, f, g)
}

// Default types are int, int32, complex128
// Types are int32, int, int, complex128

About integer division and remainder operations

Assume x, y are two operands with the same integer type, the quotient q, x/y and the remainder r , x % y satisfy x = q * y + r, where |r| < |y|;

  • the sign of r is always the same with x;
  • the result of q it toword to zero.
1
2
3
4
5
6
7
8
9
package main

func main() {
println(5/3, 5%3) // 1, 2
println(-5/3, -5%3) // -1, -2
println(5/-3, 5%-3) // -1, 2
println(-5/-3, -5%-3) // 1, -2
}

Using op= for binary arithmetic operators

For a binary arithmetic operator op, x = x op y can be shortened to x op= y. In the short form, x will be only evaluated once.

1
2
3
4
5
6
7
8
9
10
11
var a, b int8 = 3, 5
a += b
println(a) // 8
a *= a
println(a) // 64
a /= b
println(a) // 12
a %= b
println(a) // 2
b <<= uint(a)
println(b) // 20