はじめに
Gopher の皆さん、新しい章へようこそ。このセクションでは、数値型について学びます。内容には、一般的に使用される整数型、浮動小数点型、ブール型、そして複素数、およびバージョン 1.13 で導入されたリテラル値の構文が含まれます。
学習ポイント:
- 整数型 (Integer types)
- 浮動小数点型 (Floating-point types)
- ブール型 (Boolean types)
- 複素数 (Complex numbers)
- リテラル値の構文 (Literal value syntax)
整数型 (Integers)
整数 (Integers) は、大きく分けて符号なし整数 (Unsigned integers) と符号付き整数 (Signed integers) の 2 つのカテゴリに分類できます。符号付き整数 (Signed integers) が最も広く使用されています。
符号なし (Unsigned) とは、非負の数 (0 と正の数) のみを表現できることを意味し、符号付き (Signed) の数は、負の数と非負の数の両方を表現できます。
符号なし整数 (Unsigned integers) は、8 ビット、16 ビット、32 ビット、および 64 ビットの 4 つのサイズに分割でき、それぞれ uint8、uint16、uint32、および uint64 で表されます。対応する符号付き整数 (Signed integers) は、int8、int16、int32、および int64 です。次の表は、各型が表現できるさまざまな範囲を示しています。
| 型 (Type) | 説明 (Description) | 範囲 (Range) |
|---|---|---|
| uint8 | 8 ビット符号なし整数 (8-bit unsigned int) | 0 ~ 255 |
| int8 | 8 ビット符号付き整数 (8-bit signed int) | -128 ~ 127 |
| uint16 | 16 ビット符号なし整数 (16-bit unsigned int) | 0 ~ 65535 |
| int16 | 16 ビット符号付き整数 (16-bit signed int) | -32768 ~ 32767 |
| uint32 | 32 ビット符号なし整数 (32-bit unsigned int) | 0 ~ 4294967295 |
| int32 | 32 ビット符号付き整数 (32-bit signed int) | -2147483648 ~ 2147483647 |
| uint64 | 64 ビット符号なし整数 (64-bit unsigned int) | 0 ~ 18446744073709551615 |
| int64 | 64 ビット符号付き整数 (64-bit signed int) | -9223372036854775808 ~ 9223372036854775807 |
uint8 と int8 を例にとってみましょう。これらはどちらも 8 ビット整数 (8-bit integers) であり、256 個の値を表現できます。符号なし整数型 (Unsigned integer type) uint8 では、表現できる範囲は 0 から 255 ですが、符号付き整数型 (Signed integer type) int8 では、表現できる範囲は -128 から 127 です。
上記の 8 つの型に加えて、uint、int、および uintptr の 3 つの特別な整数型 (integer types) があります。uint と int はプラットフォームによって異なる範囲を表す場合があり、uintptr はポインタアドレス (pointer address) を格納するために使用されます。
| 型 (Type) | 範囲 (Range) |
|---|---|
uint |
32 ビットシステムでは uint32、64 ビットシステムでは uint64 |
int |
32 ビットシステムでは int32、64 ビットシステムでは int64 |
uintptr |
ポインタアドレス (pointer address) を格納するために使用される符号なし整数型 (Unsigned integer type)。主に unsafe 操作のような低レベルプログラミングで使用されます |
次に、integer.go という名前のファイルを作成して、整数 (integers) の使用法を示します。
cd ~/project
touch integer.go
package main
import (
"fmt"
"unsafe"
)
func main() {
// View the type of int in the current environment
// Declare a as the type int
var a int
// Use unsafe.Sizeof() to output the memory size occupied by the type
fmt.Printf("The type int in the current environment is %d bits\n", unsafe.Sizeof(a)*8)
var b int8 = 125
// Use the %d placeholder in fmt.Printf to output the value of the integer
// Use the %T placeholder in fmt.Printf to output the type of the variable
fmt.Printf("The value of b is %d, and the type is %T\n", b, b)
// Integer operations
// Declare integers c and d, and calculate their sum
c, d := 2, 3
fmt.Printf("c + d = %d\n", c+d)
// 10 - 5
fmt.Printf("10 - 5 = %d\n", 10-5)
// 8 * 10
fmt.Printf("8 * 10 = %d\n", 8*10)
// Example of uintptr usage - storing an address
var ptr uintptr
x := 42
// Convert the pointer to x to uintptr
ptr = uintptr(unsafe.Pointer(&x))
fmt.Printf("The address of x stored in ptr is: %v\n", ptr)
}
プログラムを実行すると、次の出力が得られます。
go run integer.go
The type int in the current environment is 64 bits
The value of b is 125, and the type is int8
c + d = 5
10 - 5 = 5
8 * 10 = 80
The address of x stored in ptr is: 824634818784
出力の説明:
The type int in the current environment is 64 bits: この行は、コードが実行されているシステムのint型 (type) が 64 ビット (または 8 バイト) であることを示しています。これはint64であることを示しています。unsafe.Sizeof(a)は変数aのサイズをバイト単位で返し、8 を掛けることでビットに変換します。これは、int型 (type) がより大きな整数値 (integer values) を保持できることを意味します。The value of b is 125, and the type is int8: ここでは、int8型 (type) の変数bを宣言し、それに値 125 を割り当てました。出力は、値とデータ型の両方を示すことで、これを確認します。c + d = 5,10 - 5 = 5,8 * 10 = 80: これらの行は、基本的な整数演算 (integer arithmetic operations) (加算、減算、乗算) を示しています。出力は、これらの計算の正しい結果を確認します。The address of x stored in ptr is: 824634818784: これは、uintptrを使用してメモリアドレス (memory address) を格納する方法を示しています。整数変数 (integer variable)xへのポインタ (pointer) をuintptr型 (type) に変換しています。実際のアドレス値 (address value) は、プログラムが実行されるたびに異なります。これは、unsafe 操作やシステムプログラミングで通常見られる高度な使用例です。
このファイルでは、unsafe.Sizeof() 関数を使用して、現在の変数の型 (variable type) が占めるバイト数を取得できます。1 バイト (byte) は 8 ビットに等しいため、unsafe.Sizeof()*8 は、型 (type) が占めるビット数を取得できます。出力から、オンライン環境が 64 ビットであることがわかります。オンライン環境での int の実際の型 (type) は int64 です。
ターミナルで次のコマンドを使用して、現在のシステムアーキテクチャ (system architecture) を確認できます。
dpkg --print-architecture
amd64
浮動小数点数 (Floating-Point Numbers)
浮動小数点数 (Floating-point numbers) は、Go では float32 と float64 の 2 つの型を使用して、小数部を持つ実数を表します。デフォルトの浮動小数点型 (floating-point type) は float64 です。
float32 と float64 は、異なる精度 (precision) を表します。float64 のデフォルトの精度 (precision) は、float32 よりも高くなっています。
IEEE 754 規格 (IEEE 754 standard) は、コンピュータで最も広く使用されている浮動小数点計算規格 (floating-point calculation standard) であり、最新の CPU はすべてこの規格をサポートしています。他のプログラミング言語と同様に、Go も IEEE 754 を使用して浮動小数点数 (floating-point numbers) を格納します。
コンピュータの 1 バイト (byte) が 8 ビット (bits) を格納できることはご存知でしょう。float32 は単精度浮動小数点数 (single-precision floating-point number) であり、4 バイト (bytes) (32 ビット (bits)) を占有します。float64 は倍精度 (double-precision) であり、8 バイト (bytes) (64 ビット (bits)) を占有します。
float32 では、符号ビット (sign bit) が 1 ビット (bit) を占有し、指数部 (exponent) が 8 ビット (bits) を占有し、残りの 23 ビット (bits) が仮数部 (mantissa) を表すために使用されます。
float64 では、符号ビット (sign bit) も 1 ビット (bit) を占有し、指数部 (exponent) が 11 ビット (bits) を占有し、残りの 52 ビット (bits) が仮数部 (mantissa) を表すために使用されます。
float32 が表現できる最大値 (maximum value) は、科学表記法 (scientific notation) で約 3.4e+38 であり、最小値 (minimum value) は 1.4e-45 です。float64 が表現できる最大値 (maximum value) は、約 1.8e+308 であり、最小値 (minimum value) は 4.9e-324 です。浮動小数点値 (floating-point values) の範囲は、非常に小さい値から非常に大きい値まで可能であることがわかります。
定数 math.MaxFloat32 を使用して、float32 の最大値 (maximum value) を表すことができます。定数 math.MaxFloat64 を使用して、float64 の最大値 (maximum value) を表します。
浮動小数点数 (Floating-Point Numbers) の表現
浮動小数点数 (Floating-point numbers) を出力するときは、fmt パッケージ (package) の Printf 関数の %f プレースホルダー (placeholder) を使用できます。次に例を示します。
cd ~/project
touch float.go
package main
import (
"fmt"
"math"
)
func main() {
// Output without exponential form
fmt.Printf("2.333 without exponential form: %f\n", 2.333)
fmt.Printf("Pi without exponential form: %f\n", math.Pi)
// Use %.2f to keep two decimal places for Pi
fmt.Printf("Pi with two decimal places: %.2f\n", math.Pi)
fmt.Printf("The maximum value of float32: %f\n", math.MaxFloat32)
// Exponential form
fmt.Printf("2.333 in exponential form: %e", 2.333)
}
コマンドを実行すると、次の出力が表示されます。
go run float.go
2.333 without exponential form: 2.333000
Pi without exponential form: 3.141593
Pi with two decimal places: 3.14
The maximum value of float32: 340282346638528859811704183484516925440.000000
2.333 in exponential form: 2.333000e+00
出力の説明:
2.333 without exponential form: 2.333000: これは、%fプレースホルダー (placeholder) を使用して出力された数値2.333を示しています。デフォルトでは、%fプレースホルダー (placeholder) は小数点以下 6 桁を表示するため、2.333は2.333000になります。Pi without exponential form: 3.141593: この行は、数学定数 π の近似値である定数math.Piの値を出力します。%fプレースホルダー (placeholder) は、それを完全な精度 (precision) で表示します。Pi with two decimal places: 3.14:%.2fを使用することで、fmt.Printfに小数点以下 2 桁に数値をフォーマットするように指示し、その結果3.14になります。これは、出力に特定の精度 (precision) のみが必要な場合に非常に役立ちます。The maximum value of float32: 340282346638528859811704183484516925440.000000: これは、float32が表現できる最大値 (maximum value) を示しています。非常に大きな数値であり、%fで出力すると、多くの桁で表現されることに注意してください。2.333 in exponential form: 2.333000e+00: この行は、%eプレースホルダー (placeholder) を使用して、浮動小数点数 (floating-point number) を指数 (科学) 表記 (exponential (scientific) notation) で表現する方法を示しています。末尾のe+00は、2.333000に 10 の 0 乗を掛けることを示しており、これは単に2.333です。指数 (exponent) がe+02の場合、数値は10^2(100) 倍され、その結果233.3になります。
ブール型 (Boolean Types)
bool 型 (type) は、true または false の 2 つの値のみを取り、デフォルトは false です。これには、次の特性があります。
- 整数 (integer) をブール値 (boolean) に変換したり、ブール値 (boolean) を整数 (integer) に変換したりするなど、他の型 (type) に変換することはできません。
- 算術演算 (arithmetic operations) に参加することはできません。
ブール型 (Boolean types) は、通常、=、>、< などの関係演算子 (relational operators) と組み合わせて使用されます。bool.go という名前のファイルを作成して、デモンストレーションを見てみましょう。
cd ~/project
touch bool.go
package main
import (
"fmt"
)
func main() {
// Use the %t placeholder in fmt.Printf to represent a boolean value
fmt.Printf("Is 3 equal to 2? %t\n", 3 == 2)
fmt.Printf("Is 2 equal to 2? %t\n", 2 == 2)
// Determine whether a and b are equal
a, b := 1, 2
fmt.Printf("a is %d, b is %d\n", a, b)
if a > b {
fmt.Println("a is greater than b")
} else if a == b {
fmt.Println("a is equal to b")
} else {
fmt.Println("b is greater than a")
}
}
プログラムを実行すると、次の出力が得られます。
go run bool.go
Is 3 equal to 2? false
Is 2 equal to 2? true
a is 1, b is 2
b is greater than a
出力の説明:
Is 3 equal to 2? false: 式3 == 2はfalseと評価され、%tプレースホルダー (placeholder) を使用して出力されます。Is 2 equal to 2? true: 式2 == 2はtrueと評価され、%tプレースホルダー (placeholder) を使用して出力されます。a is 1, b is 2: この行は、整数変数 (integer variables)aとbに割り当てられた値を出力します。b is greater than a:if-else if-else条件文 (conditional statement) はa < bと評価され、これは1 < 2(true) であるため、elseステートメント (statement) が実行され、その結果、プログラムは "b is greater than a" を出力します。
このプログラムでは、最初に fmt.Printf で %t を使用してブール値 (boolean value) を表し、次に if ステートメント (statement) を使用して 2 つの値の関係を判断します。fmt.Printf では、%d プレースホルダー (placeholder) を使用して整数 (integer) を表し、%f プレースホルダー (placeholder) を使用して浮動小数点数 (floating-point number) を表し、%t プレースホルダー (placeholder) を使用してブール値 (boolean value) を表すことができます。
複素数 (Complex Numbers)
Go には、組み込みの複素数型 (complex number types) もあり、complex64 型 (type) と complex128 型 (type) に分けられます。complex64 では、実部 (real part) と虚部 (imaginary part) の両方が 32 ビット (bits) であるのに対し、complex128 では、実部 (real part) と虚部 (imaginary part) の両方が 64 ビット (bits) です。Go では、複素数演算 (complex number operations) を簡単に行うことができます。
complex.go という名前のファイルを作成し、次のコードを入力します。
cd ~/project
touch complex.go
package main
import (
"fmt"
)
func main() {
// Initialize complex numbers in different ways
c1 := complex(3, 1)
c2 := 4 + 5i
// Complex number operations
c3 := c1 + c2
c4 := c1 * c2
// Use the real() function to obtain the real part of a complex number, and the imag() function to obtain the imaginary part of a complex number
fmt.Printf("The real part of c1 is %v, the imaginary part is %v\n", real(c1), imag(c1))
// %v in fmt.Printf can be used to represent complex numbers
fmt.Printf("c1 + c2 is %v\n", c3)
fmt.Printf("c1 * c2 is %v\n", c4)
}
プログラムを実行すると、次の出力が得られます。
go run complex.go
The real part of c1 is 3, the imaginary part is 1
c1 + c2 is (7+6i)
c1 * c2 is (7+19i)
出力の説明:
The real part of c1 is 3, the imaginary part is 1: 関数real(c1)は、複素数 (complex number)c1の実部 (real part) である3を抽出し、imag(c1)は、c1の虚部 (imaginary part) である1を抽出します。これらの値は、%vプレースホルダー (placeholder) を使用して出力されます。c1 + c2 is (7+6i): この行は、複素数 (complex numbers)c1とc2を加算した結果を示しています。c1は3 + 1iとして定義され、c2は4 + 5iとして定義されています。実部 (real part) と虚部 (imaginary part) を別々に追加すると、(3 + 4) + (1 + 5)i、つまり7 + 6iになります。c1 * c2 is (7+19i): この行は、複素数 (complex numbers)c1とc2を乗算した結果を示しています。(3 + 1i) * (4 + 5i)は、(3*4 - 1*5) + (3*5 + 1*4)iとして計算され、これは(12-5) + (15+4)iに簡略化され、最終的に7+19iになります。
このプログラムでは、complex 関数 (function) と + および * 演算子 (operators) を使用して、複素数 (complex numbers) を初期化し、演算を実行する方法を示しました。real() と imag() は、それぞれ複素数 (complex number) の実部 (real part) と虚部 (imaginary part) を抽出するために使用されます。fmt.Printf の %v 動詞 (verb) は、複素数 (complex numbers) を表示するための一般的なプレースホルダー (placeholder) として使用されます。
リテラル値の構文 (Literal Value Syntax)
Go のバージョン 1.13 では、数値リテラル構文 (Numeric Literal Syntax) が導入されました。これは、異なる数値システム (number systems) での数の表現を定義します。そのルールを見てみましょう。
- 2 進数 (Binary): 整数の前に
0bを追加します。たとえば、0b101は 10 進数 (decimal) の5に相当します。 - 8 進数 (Octal): 整数の前に
0oまたは0Oを追加します。たとえば、0o11は 10 進数 (decimal) の9に相当します。 - 16 進数 (Hexadecimal): 整数の前に
0xまたは0Xを追加します。たとえば、0x1bは 10 進数 (decimal) の27に相当します。 - 整数内の桁を区切るために
_を使用します。たとえば、0b1000_0100_0010_0001は0b1000010000100001と同じです。これにより、可読性 (readability) が向上します。
詳細にデモンストレーションしてみましょう。
cd ~/project
touch literals.go
package main
import "fmt"
func main() {
// Binary, add 0b at the beginning
var a int = 0b101
fmt.Printf("Binary a is %b, decimal is %d\n", a, a)
// Octal, add 0o or 0O at the beginning
var b int = 0o11
fmt.Printf("Octal b is %o, decimal is %d\n", b, b)
// Hexadecimal, add 0x or 0X at the beginning
var c int = 0x1b
fmt.Printf("Hexadecimal c is %x, decimal is %d\n", c, c)
// Use separators
d := 0b1000_0100_0010_0001
e := 0b1000010000100001
if d == e {
fmt.Println("d is equal to e")
}
}
プログラムを実行すると、次の出力が得られます。
go run literals.go
Binary a is 101, decimal is 5
Octal b is 11, decimal is 9
Hexadecimal c is 1b, decimal is 27
d is equal to e
出力の説明:
Binary a is 101, decimal is 5: この行は、0b101の 2 進数表現 (binary representation) である101と、その 10 進数 (decimal) に相当する5を示しています。%bプレースホルダー (placeholder) はaの 2 進数 (binary) の値を表示し、%dは 10 進数表現 (decimal representation) を表示します。Octal b is 11, decimal is 9: 8 進数 (octal number)0o11は、10 進数 (decimal) で1*8^1 + 1*8^0 = 8 + 1 = 9に相当します。%oプレースホルダー (placeholder) はbの 8 進数表現 (octal representation) を表示し、%dはその 10 進数 (decimal) の値を表示します。Hexadecimal c is 1b, decimal is 27: 16 進数 (hexadecimal number)0x1bは、10 進数 (decimal) で1*16^1 + 11*16^0 = 16 + 11 = 27に相当します。%xプレースホルダー (placeholder) はcの 16 進数表現 (hexadecimal representation) を表示し、%dはその 10 進数 (decimal) の値を表示します。d is equal to e: これは、2 進数リテラル (binary literal)0b1000_0100_0010_0001が値として0b1000010000100001と等しいことを示しています。アンダースコア (underscores) は純粋に可読性 (readability) のためのものであり、数値の値を変更しません。if条件 (condition) は正しくtrueと評価されます。
このプログラムでは、異なる数値システム (number systems) の宣言と出力、および区切り文字 (separators) の使用法を示しました。fmt.Printf では、異なる数値システム (number systems) を表すために異なるプレースホルダー (placeholders) を使用しました。たとえば、%b は 2 進数 (binary) を表し、%x は 16 進数 (hexadecimal) を表します。それらを習得すると、プログラミング効率 (programming efficiency) が向上します。
まとめ
このセクションで学んだことを復習しましょう。
- 整数 (Integers) は、符号付き整数 (signed integers) と符号なし整数 (unsigned integers) に分けられます。
- デフォルトの整数型 (integer types) である
intとuintは、プラットフォーム (platform) に依存する範囲 (range) を持ちます。 - 浮動小数点数 (floating-point numbers) の表現 (representation)
- 複素数 (complex numbers) の使い方
- リテラル値構文 (literal value syntax) の紹介
- さまざまなプレースホルダー (placeholders) の使い方
このセクションでは、一般的な整数型 (integer types)、浮動小数点型 (floating-point types)、およびブール型 (boolean types) について説明し、デモンストレーションしました。それらのサイズ (size)、範囲 (range)、および使用法 (usage) について説明しました。また、複素数 (complex numbers) とリテラル定数 (literal constants) についても紹介しました。数値型 (numerical types) は Go プログラム (program) の基礎であり、学習者はそれらをよく学ぶことが重要です。



