[Golang] 演算子

2021-10-01 hit count image

Golangで使える演算子について説明します。

概要

今回のブログポストではGolangで使える演算子について説明します。このブログポストで紹介するコードは次のリンクで確認できます。

四則演算子

Golangでは次のような四則演算を使うことができます。

  • +: 加算 (整数、実数、文字列)
  • -: 減算 (整数、実数)
  • *: 乗算 (整数、実数)
  • /: 除算 (整数、実数)
  • %: 残り (整数)

main.goファイルを生成して次のようにコードを作成して確認できます。

package main

import "fmt"

func main() {
    a := 6
    b := 5

    fmt.Println("Result:", a+b)
    fmt.Println("Result:", a-b)
    fmt.Println("Result:", a*b)
    fmt.Println("Result:", a/b)
    fmt.Println("Result:", a%b)
}

このように作成したプログラムを実行すると次のような結果が出ます。

Result: 11
Result: 1
Result: 30
Result: 1
Result: 1

ビット演算子

Golangでは次のようにビット演算を使うことができます。

  • &: ANDビット演算 (整数)
  • |: ORビット演算 (整数)
  • ^: XORビット演算 (整数)
  • &^: ビットクリア(整数)

main.goファイルを修正して次のようにコードを作成したら確認できます。

package main

import "fmt"

func main() {
    a := 6
    b := 5

    fmt.Printf("Result: %08b\n", a&b)
    fmt.Printf("Result: %08b\n", a|b)
    fmt.Printf("Result: %08b\n", a^b)
    fmt.Printf("Result: %08b\n", a&^b)
}

このように作成したプログラムを実行すると次のような結果が出ます。

Result: 00000100
Result: 00000111
Result: 00000011
Result: 00000010

シフト演算子

  • <<: レフトシフト (正の整数)
  • >>: ライトシフト (正の整数)

main.goファイルを修正して次のようにコードを作成したら確認できます。

package main

import "fmt"

func main() {
    a := 6

    fmt.Printf("Result: %08b\n", a)
    fmt.Printf("Result: %08b\n", a<<2)
    fmt.Printf("Result: %08b\n", a>>1)
}

このように作成したプログラムを実行すると下記のような結果が出ます。

Result: 00000110
Result: 00011000
Result: 00000011

比較演算子

  • ==: 同じ
  • !=: 違う
  • <: 小さい
  • >: 大きい
  • <=: 小さいか等しい
  • >=: 大きいか等しい

main.goファイルを修正して下記のようにコードを作成したら確認できます。

package main

import "fmt"

func main() {
    a := 6
    b := 5

    fmt.Println("Result:", a == b)
    fmt.Println("Result:", a != b)
    fmt.Println("Result:", a < b)
    fmt.Println("Result:", a > b)
    fmt.Println("Result:", a <= b)
    fmt.Println("Result:", a >= b)
}

このように作成したプログラムを実行すると次のような結果が出ます。

Result: false
Result: true
Result: false
Result: true
Result: false
Result: true

論理演算子

  • &&: AND演算子
  • ||: OR演算子
  • !: NOT演算子

main.goファイルを下記のように修正すると確認できます。

package main

import "fmt"

func main() {
    a := true
    b := false

    fmt.Println("Result:", a && b)
    fmt.Println("Result:", a || b)
    fmt.Println("Result:", !a)
}

このように作成したプログラムを実行すると下記のような結果が出ます。

Result: false
Result: true
Result: false

代入演算子

Golangでは次のような代入演算子を使えます。

a = 1
a, b = 1, 2

代入演算子を次のように使うと、2つの変数の値を交換することができます。

a, b = b, a

複合代入演算子

Golangでは下記のように演算と同時に代入することができます。

  • +=: a += 1 / a = a + 1
  • -=
  • *=
  • /=
  • %=
  • &=
  • |=
  • ^=
  • <<=
  • >>=

増減演算子

  • ++: a ++ / a = a + 1
  • --

増然演算子は値をリターンしません。したがって、次のように使うことができません。

b = a++

演算子の優先順位

Golangの演算子は次のような優先順位を持っています。

優先順位演算子
1*, /, %, <<, >>, &, &^
2+, -, |, ^
3==, !=, <, <=, >, >=
4&&
5||

もちろん、括弧((,))中の式が一番最初実行されます。안에 식이 가장 먼저 실행됩니다.

Nextafter

ビットでは実数を正確表現することができません。したがって、実数を表現する時、実際の数より1ビット大きいくするか、小さく知って近接数で実数を表現します。

package main

import (
    "fmt"
    "math"
)

func main() {
    var a float64 = 0.1
    var b float64 = 0.2
    var c float64 = 0.3

    fmt.Printf("%0.18f\n", c)
    fmt.Printf("%0.18f\n", a+b)
    fmt.Printf("%0.18f == %0.18f (%v)\n", c, a+b, c == a+b)
}

上のようにプログラムを作成して実行すると、次のような結果が出ます。

0.299999999999999989
0.300000000000000044
0.299999999999999989 == 0.300000000000000044 (false)

期待した結果とは違ってfalseが表示されることが確認できます。

これを解決するためには、私たちはmathパッケージのNextafter関数を使う必要があります。

fmt.Printf("%0.18f == %0.18f (%v)\n", c, a+b, c == math.Nextafter(a+b, c))

これを実行して見ると次のような結果が出ます。

0.299999999999999989 == 0.300000000000000044 (true)

Nextafterは渡して貰った2つの数で前の数を後ろの数に向けて1ビット移動した値をリターンします。したがって、正確的に実数の値を比べることができます。

完了

これでGolangで使える演算子について見てみました。他のプログラムとほとんど同じなので、他の言語を勉強した方には簡単に理解できる部分だっと思います。

ただい、実数を比較する時、実数の誤差を考えてNextafterを使えなければ行けないことを覚える必要があります。

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

Posts