Juliaは汎用のプログラミング言語で、ほとんどのプログラミング作業に使えます。 ただし実際には、主な用途は工学や科学の分野になることが多いです。 高速で多用途、そして高度な数値計算が、設計の中心に置かれています。
整数は、小数点の付かない「丸い」数です。
Basicsのコンセプトでは、型を指定しなくても整数の値を変数に代入できることを見ました。
読みやすさのために、アンダースコアを桁区切りとして使えます。 コンパイラーはこれを無視します。
julia> x = 3
3
julia> typeof(x)
Int64
julia> large_number = 1_234_567_890
1234567890
浮動小数点数には小数点があり、小数点の後ろに小数部があるのは、驚くことではないでしょう。
julia> f = 3.45
3.45
julia> typeof(f)
Float64
もちろん、指数表記にも対応しています。
julia> avogadro = 6.02e23
6.02e23
最大値と最小値には、驚くかもしれません。
julia> typemax(Float64)
Inf
julia> typemin(Float64)
-Inf
無限大も有効な値です!
Basicsのコンセプトで説明したように、算術演算子は、子どもに教える普通の算数とほとんど同じように動きます。
べき乗に使うのは^で、**では_ありません_(どちらも他の言語ではよく使われます)。
2 + 3 # 5 (addition)
2 - 3 # -1 (subtraction)
2 * 3 # 6 (multiplication)
8 / 2 # 4.0 (division)
8 % 3 # 2 (remainder)
2 ^ 3 # 8 (exponentiation)
ただし、Julia特有の細かい点がいくつかあり、説明する価値があります。
julia> x = 4.2
4.2
julia> 2 * x
8.4
julia> 2x
8.4
julia> 2.4x
10.08
これは驚きかもしれません。
ほとんどの他のプログラミング言語と同じように、*を中置演算子として使うこともいつでもできます。
しかしJuliaは、コードができるだけ数式のように見えるべきだと考える人たちによって設計されました。
変数名は文字で始めなければならないので、名前の前に数値(整数または浮動小数点数)を置くと、暗黙の乗算として扱われます。
たとえば球の表面積を求めたいときは、4 * pi * r * rの代わりに、次のように書けます。
julia> surface(r) = 4π * r^2
surface (generic function with 1 method)
julia> surface(3)
113.09733552923255
πは組み込みの定数ですが、(ギリシャ)文字でもあります。
そのためパーサーは、πとrを区切るために明示的な*を1つ必要とします。
/を中置演算子として使うと、整数を入力した場合でも、常に浮動小数点数の結果になります。
整数の除算には、他にもいくつか選択肢があります。
julia> 10 / 3 # floating-point division
3.3333333333333335
julia> div(10, 3) # integer division
3
julia> 10 ÷ 3 # synonym for div()
3
julia> 10 // 3 # rational number (fraction)
10//3
div()関数は整数の除算用で、結果はゼロに向かって切り捨てられます。正の数では下方向、負の数では上方向になります。
同義で、中置演算子÷も使えます。これもより数学らしく見せるためのものです。
Juliaに対応したエディターを使っているなら、\divと入力してから<Tab>キーを押します。
//演算子は、このコンセプトの範囲を超えています。
今のところは、//の結果は「有理数」で、多くの人がこれを_分数_と呼ぶ、と言っておけば十分です。
変換は多くの場合、自動的に行われます。
julia> x = 2 + 3.5
5.5
julia> typeof(x)
Float64
Int64とFloat64を足したら、Float64の結果が得られました。
実際には、足し算の前に、整数が暗黙のうちにFloat64へ変換されています。
浮動小数点数から整数への変換は、どうしてもより複雑です。 小数点以下の部分をどう扱いたいのかを考える必要があります。
round()関数は最も近い整数に丸めます。4.5のようにちょうど中間にあたる場合は、最も近い_偶数_の整数に丸められます。floor()は下方向、ceil()は上方向、trunc()はゼロに向かって丸めます。Int32()で直接キャストしようとすると、InexactErrorで失敗します。ただし、これらの関数は既定では、期待する整数型を返しません。 出力したい型を指定できます。
julia> round(4.5)
4.0
julia> ceil(Int, 4.3)
5
digitsキーワードを使えば、小数点以下の桁数を指定して丸めることもできます。
julia> round(π, digits=10)
3.1415926536
きっとエラーになるだけだと思うかもしれませんが、実際はそう単純ではありません。
÷や//による整数の除算は、予想どおりエラーになります。
/による浮動小数点数の除算は、標準的なコンピューターサイエンスの考え方ではなく、工学寄りの考え方をとります。
julia> 2 / 0
Inf
julia> 0 / 0
NaN
前のセクションで説明したように、Juliaでは無限大も有効な浮動小数点数で、Infで表されます。
分子もゼロの場合、結果は数学的に未定義です。
そのときJuliaはこれを「数値ではないもの」として扱い、NaNで表します。
友人のChandlerは、世界中のエキゾチックな国々を訪れる予定です。残念ながら、Chandlerは数学が得意ではありません。旅先で両替所にだまされないかかなり心配していて、あなたに為替計算機を作ってほしいと思っています。アプリの仕様は次のとおりです。
2つの仮引数を受け取るexchange_money()関数を作成しましょう。
budget:両替する予定の金額。exchange_rate:外国通貨1単位に相当する自国通貨の額。この関数は、両替した通貨の価値を返します。
注意: 自国通貨がUSDで、為替レート1.20でUSDをEURに両替したい場合、1.20 USD == 1 EURとなります。
julia> exchange_money(127.5, 1.2)
106.25
2つの仮引数を受け取るget_change()関数を作成しましょう。
budget:両替前の金額。exchanging_value:両替のために予算から取り出される金額。この関数は、予算から残った金額を返します。
julia> get_change(127.5, 120)
7.5
2つの仮引数を受け取るget_value_of_bills()関数を作成しましょう。
denomination:紙幣1枚の価値。number_of_bills:紙幣の総枚数。この両替所は、決まった単位の現金しか扱いません。受け取る合計金額は、1枚の「紙幣」、つまり単位の価値で割り切れる必要があり、端数や余りが出ることがあります。この関数は、両替所が返す紙幣の合計金額(端数の金額は除く)だけを返します。残念ながら、端数やおつりは両替所がおまけとしてそのまま受け取ります。
julia> get_value_of_bills(5, 128)
640
amountとdenominationを受け取るget_number_of_bills()関数を作成しましょう。
この関数は、指定された_amount_の範囲で受け取れる_紙幣の枚数_を返します。言い換えると、開始金額に_丸ごとの紙幣_が何枚収まるでしょうか? 覚えておきましょう。受け取れるのは_丸ごとの紙幣_だけで、紙幣の端数を受け取ることはできません。そのため、それに合わせて割り算しましょう。実質的には、最も近い紙幣、つまり額面に_切り捨て_ていることになります。
julia> get_number_of_bills(127.5, 5)
25
amountとdenominationを受け取るget_leftover_of_bills()関数を作成しましょう。
この関数は、紙幣の額面が与えられたとき、開始した_amount_から返すことのできない_残りの金額_を返します。両替所がいくらを手元に残せるのかを正確に知っておくことがとても大切です。
julia> get_leftover_of_bills(127.5, 20)
7.5
budget、exchange_rate、spread、denominationを受け取るexchangeable_value()関数を作成しましょう。
仮引数spreadは、両替手数料として取られる割合を整数で表したものです。これは100で割って小数に変換する必要があります。1.00 EUR == 1.20 USDで、spreadが10の場合、実際の為替レートは1.00 EUR == 1.32 USDになります。1.20の10%は0.12で、この追加手数料が為替レートに加算されるからです。
この関数は、為替レートとspreadを計算したうえで、新しい通貨の最大値を返します。通貨の額面は整数で、分割できないことを覚えておきましょう。
注意: 戻り値は整数型にしてください。
julia> exchangeable_value(127.25, 1.20, 10, 20)
80
julia> exchangeable_value(127.25, 1.20, 10, 5)
95