Julia データ型
プログラミング言語には、基本的な数学演算や科学計算があり、それらでよく使われるデータ型は、整数と浮動小数点数です。さらに、「リテラル」という用語があります。リテラル(literal)は、ソースコード内の固定値を表す表記法(notation)で、整数、浮動小数点数、文字列などはすべてリテラルです。
例:
a=1 // a は変数、1 は整数リテラル b=1.0 // b は変数、1.0 は浮動小数点リテラルJulia は非常に豊富なプリミティブ数値型を提供し、それらに基づいて一連の算術演算を定義しています。さらに、ビット演算子や標準的な数学関数も提供しています。
整数型
次の表に、Julia がサポートする整数型を示します:
| 型 | 符号付き? | ビット数 | 最小値 | 最大値 |
|---|---|---|---|---|
| Int8 | ✓ | 8 | -2^7 | 2^7 – 1 |
| UInt8 | 8 | 0 | 2^8 – 1 | |
| Int16 | ✓ | 16 | -2^15 | 2^15 – 1 |
| UInt16 | 16 | 0 | 2^16 – 1 | |
| Int32 | ✓ | 32 | -2^31 | 2^31 – 1 |
| UInt32 | 32 | 0 | 2^32 – 1 | |
| Int64 | ✓ | 64 | -2^63 | 2^63 – 1 |
| UInt64 | 64 | 0 | 2^64 – 1 | |
| Int128 | ✓ | 128 | -2^127 | 2^127 – 1 |
| UInt128 | 128 | 0 | 2^128 – 1 | |
| Bool | N/A | 8 | false (0) | true (1) |
整数リテラルの形式:
例
1
julia> 1234
1234
整数リテラルのデフォルト型は、対象システムが32ビットか64ビットのどちらのアーキテクチャであるかに依存します(現在のほとんどのシステムは64ビットです):
例
julia> typeof(1)
Int32
# 64ビットシステム:
julia> typeof(1)
Int64
Julia の組み込み変数Sys.WORD_SIZEは、対象システムが32ビットか64ビットのどちらのアーキテクチャであるかを示します:
例
julia> Sys.WORD_SIZE
32
# 64ビットシステム:
julia> Sys.WORD_SIZE
64
Julia はまた、Int 型と UInt 型を定義しています。これらはそれぞれ、システムの符号付きおよび符号なしのネイティブ整数型のエイリアスです。
例
julia> Int
Int32
julia> UInt
UInt32
# 64ビットシステム:
julia> Int
Int64
julia> UInt
UInt64
オーバーフロー動作
Julia では、型が表現できる最大値を超えると、ラップアラウンド(wraparound)動作が発生します:
例
9223372036854775807
julia> x + 1
-9223372036854775808
julia> x + 1 == typemin(Int64)
true
したがって、Julia の整数演算は実際にはモジュラー演算の一種であり、現代のコンピュータが低レベル演算を実装する方法を反映しています。オーバーフローが発生する可能性のあるプログラムでは、最大値・最小値の境界での循環を明示的にチェックすることが必要です。そうでない場合は、任意精度演算の BigInt 型を代替として使用することをお勧めします。
以下は、オーバーフロー動作の例と、その対処方法です:
例
-8446744073709551616
julia> big(10)^19
10000000000000000000
除算エラー
次の2つの例外の場合、整数除算は DivideError エラーを発生させます:- ゼロによる除算
- 最小の負数による除算
rem剰余関数とmodモジュロ関数は、ゼロ除算時に DivideError エラーをスローします。以下に例を示します:
例
ERROR: DivideError: integer division error
Stacktrace:
[1] div at .\int.jl:260 [inlined]
[2] div at .\div.jl:217 [inlined]
[3] div at .\div.jl:262 [inlined]
[4] fld at .\div.jl:228 [inlined]
[5] mod(::Int64, ::Int64) at .\int.jl:252
[6] top-level scope at REPL[52]:1
julia> rem(1, 0)
ERROR: DivideError: integer division error
Stacktrace:
[1] rem(::Int64, ::Int64) at .\int.jl:261
[2] top-level scope at REPL[54]:1
浮動小数点型
次の表に、Julia がサポートする浮動小数点型を示します:
| 型 | 精度 | ビット数 |
|---|---|---|
| Float16 | 半精度 | 16 |
| Float32 | 単精度 | 32 |
| Float64 | 倍精度 | 64 |
さらに、複素数と有理数に対する完全なサポートは、これらのプリミティブデータ型の上に構築されています。
浮動小数点リテラルの形式は次のように表されます。必要に応じて、Eを使用して表すことができます。
例
1.0
julia> 1.
1.0
julia> 0.5
0.5
julia> .5
0.5
julia> -1.23
-1.23
julia> 1e10
1.0e10
julia> 2.5e-4
0.00025
注:
科学表記法では、式を簡潔にするために、Eの形式で表すことができます。例えば、1.03×10の8乗は、「1.03E+08」のように簡潔に書けます。ここで「E」は exponent(指数)の略です。
上記の結果はすべて Float64 型の値です。e の代わりに f を使用すると、Float32 型のリテラルが得られます:
例
0.5f0
julia> typeof(x)
Float32
julia> 2.5f-4
0.00025f0
数値は簡単にFloat32型に変換できます:
julia> x = Float32(-1.5)
-1.5f0
julia> typeof(x)
Float32
十六進数の浮動小数点リテラルも存在しますが、Float64 型の値にのみ適用されます。通常は p 接頭辞と2を底とする指数を使用して表します:
例
1.0
julia> 0x1.8p3
12.0
julia> x = 0x.4p-1
0.125
julia> typeof(x)
Float64
Julia は半精度浮動小数点数(Float16)もサポートしていますが、これらはFloat32ソフトウェアシミュレーションによって実装されています。
julia> sizeof(Float16(4.))
2
julia> 2*Float16(4.)
Float16(8.0)
アンダースコア_数字の区切り文字として使用できます:
例
(10000, 5.0e-9, 0xdeadbeef, 0xb2)
浮動小数点数におけるゼロ
浮動小数点数には2つのゼロ、正のゼロと負のゼロがあります。これらは互いに等しいですが、異なるバイナリ表現を持ちます。bitstring 関数を使って確認できます:
例
true
julia> bitstring(0.0)
"0000000000000000000000000000000000000000000000000000000000000000"
julia> bitstring(-0.0)
"1000000000000000000000000000000000000000000000000000000000000000"
特別な浮動小数点値
実数軸上のどの点にも対応しない、3つの特定の標準浮動小数点値があります:
| Float16 | Float32 | Float64 | 名前 | 説明 |
|---|---|---|---|---|
| Inf16 | Inf32 | Inf | 正の無限大 | すべての有限浮動小数点数より大きい数 |
| -Inf16 | -Inf32 | -Inf | 負の無限大 | すべての有限浮動小数点数より小さい数 |
| NaN16 | NaN32 | NaN | 非数 | どの浮動小数点値(自分自身も含む)とも等しくない(==)値 |
以下に、浮動小数点数の演算の例をいくつか示します:
例
0.0
julia> 1/0
Inf
julia> -5/0
-Inf
julia> 0.000001/0
Inf
julia> 0/0
NaN
julia> 500 + Inf
Inf
julia> 500 - Inf
-Inf
julia> Inf + Inf
Inf
julia> Inf - Inf
NaN
julia> Inf * Inf
Inf
julia> Inf / Inf
NaN
julia> 0 * Inf
NaN
julia> NaN == NaN
false
julia> NaN != NaN
true
julia> NaN < NaN
false
julia> NaN > NaN
false
さらに、typemin 関数と typemax 関数を使用することもできます:
例
(-Inf16, Inf16)
julia> (typemin(Float32),typemax(Float32))
(-Inf32, Inf32)
julia> (typemin(Float64),typemax(Float64))
(-Inf, Inf)
マシンイプシロン
ほとんどの実数は浮動小数点数で正確に表現できないため、隣接する表現可能な浮動小数点数の間の距離を知ることが必要です。これは通常、マシンイプシロンと呼ばれます。
Julia はeps関数を提供します。これは 1.0 と、Julia が表現できる次の浮動小数点数との差を返します:
例
1.1920929f-7
julia> eps(Float64)
2.220446049250313e-16
julia> eps() # eps(Float64) と同じ
2.220446049250313e-16
これらの値は、それぞれ Float32 では 2.0^-23、Float64 では 2.0^-52 です。eps 関数は浮動小数点値を引数として受け取ることもでき、その値と次に表現可能な浮動小数点値との絶対差を返します。つまり、eps(x) は x と同じ型の値を生成し、x + eps(x) は x よりちょうど1つ大きい、次に表現可能な浮動小数点値になります:
例
2.220446049250313e-16
julia> eps(1000.)
1.1368683772161603e-13
julia> eps(1e-27)
1.793662034335766e-43
julia> eps(0.0)
5.0e-324
隣接する表現可能な浮動小数点数の間の距離は一定ではありません。値が小さいほど間隔は小さく、値が大きいほど間隔は大きくなります。言い換えると、表現可能な浮動小数点数は実数軸上のゼロ付近で最も密であり、ゼロから遠ざかるにつれて指数関数的に疎になっていきます。定義により、eps(1.0) は eps(Float64) と等しくなります。なぜなら、1.0 は64ビット浮動小数点値だからです。
Julia はまた、引数に基づいて次に大きい、または次に小さい表現可能な浮動小数点数をそれぞれ返す nextfloat と prevfloat の2つの関数を提供しています:
例
1.25f0
julia> nextfloat(x)
1.2500001f0
julia> prevfloat(x)
1.2499999f0
julia> bitstring(prevfloat(x))
"00111111100111111111111111111111"
julia> bitstring(x)
"00111111101000000000000000000000"
julia> bitstring(nextfloat(x))
"00111111101000000000000000000001"
この例は、隣接する表現可能な浮動小数点数が隣接するバイナリ整数表現も持つという一般原則を示しています。
丸めモード
正確な浮動小数点表現を持たない数は、適切な表現可能な値に丸められなければなりません。
Julia が使用するデフォルトモードは常にRoundNearestであり、最も近い表現可能な値に丸めることを指します。この丸められた値は、可能な限り少ない有効桁数を使用します。
例
1.5
julia> BigFloat("1.550564889",2,RoundNearest)
1.5
julia> BigFloat("1.560564889",2,RoundNearest)
1.5
0 と 1 のリテラル
Julia は、0 と 1 のリテラル関数を提供しています。これは、特定の型または与えられた変数の型に基づいてリテラルを返します。
| 関数 | 説明 |
|---|---|
| zero(x) | x 型、または変数 x の型に対するゼロのリテラル |
| one(x) | x 型、または変数 x の型に対する1のリテラル |
これらの関数は、数値比較において、不要な型変換によるオーバーヘッドを避けるために使用できます。
例:
例
0.0f0
julia> zero(1.0)
0.0
julia> one(Int32)
1
julia> one(BigFloat)
1.0
型変換
型変換とは、変数をある型から別のデータ型に変換することです。例えば、float 型の値を単純な整数型に格納したい場合、float 型を int 型に強制変換する必要があります。キャスト演算子を使用すると、値をある型から別の型へ明示的に変換できます。次に例を示します:
Julia は3種類の数値変換をサポートしており、それらは不正確な変換の処理方法が異なります。1つ目:
T(x) 或 convert(T,x)
上記はすべて x を T 型に変換します。
- T が浮動小数点型の場合、変換結果は最も近い表現可能な値になり、正または負の無限大になる可能性があります。
- T が整数型の場合、x が T 型で表現できないときは InexactError がスローされます。
2つ目:
x % T整数 x を整数型 T に変換することもできます。これは x を 2^n で割った余りと一致します。ここで n は T のビット数です。
3つ目:
丸め関数は T 型のオプション引数を受け取ります。例えば、round(Int,x) はInt(round(x))の省略形です。
例
127
julia> Int8(128)
ERROR: InexactError: trunc(Int8, 128)
Stacktrace:
[...]
julia> Int8(127.0)
127
julia> Int8(3.14)
ERROR: InexactError: Int8(3.14)
Stacktrace:
[...]
julia> Int8(128.0)
ERROR: InexactError: Int8(128.0)
Stacktrace:
[...]
julia> 127 % Int8
127
julia> 128 % Int8
-128
julia> round(Int8,127.4)
127
julia> round(Int8,127.6)
ERROR: InexactError: trunc(Int8, 128.0)
Stacktrace:
[...]