🍴

Printf.jlチートシート

2022/03/20に公開
1

sprintf()などはJulia以外の言語でも文字列を成型したり, 数字の桁数を変えたりしたい時に使いますよね. JuliaではPrintf.jlのマクロとして@printf()@sprintf()が用意されています. ここでは使用例を列挙します.

パッケージ

# パッケージ
using Printf

文字列

入力 出力 説明
@sprintf("%s", "Hello") "Hello"
@sprintf("%10s", "Hello") "     Hello" 幅を指定
@sprintf("%-10s", "Hello") "Hello     " 左詰

正の整数

入力 出力 説明
@sprintf("%d", 1234) "1234"
@sprintf("%10d", 1234) "      1234" 幅を指定
@sprintf("%-10d", 1234) "1234      " 左詰
@sprintf("%010d", 1234) "0000001234" ゼロ詰

負の整数

入力 出力 説明
@sprintf("%d", -1234) "-1234"
@sprintf("%10d", -1234) "     -1234" 幅を指定
@sprintf("%-10d", -1234) "-1234     " 左詰
@sprintf("%010d", -1234) "-000001234" ゼロ詰

浮動小数点数

入力 出力 説明
@sprintf("%f", 123.456) "123.456000"
@sprintf("%10f", 123.456) "123.456000" 全体の桁数を指定
@sprintf("%-10f", 123.456) "123.456000" 左詰(上と同じ)
@sprintf("%0.5f", 123.456) "123.45600" 小数点以下の桁数を指定
@sprintf("%0.2f", 123.456) "123.46" 同上
@sprintf("%15.5f", 123.456) "      123.45600" 全体の桁数と小数点以下の桁数を指定
@sprintf("%15.2f", 123.456) "         123.46" 同上
@sprintf("%-15.2f", 123.456) "123.46         " 左詰
@sprintf("%015.2f", 123.456) "000000000123.46" ゼロ詰
@sprintf("%+15f",  123.456) "    +123.456000" 符号を表示
@sprintf("%+15f", -123.456) "    -123.456000" 符号を表示

使用例1

println()を使った場合, 以下のようにきれいに表示できない場合があります.

println()の場合
for i in 0:10
    println("t = ", i*0.05)
end

t = 0.0
t = 0.05
t = 0.1
t = 0.15000000000000002
t = 0.2
t = 0.25
t = 0.30000000000000004
t = 0.35000000000000003
t = 0.4
t = 0.45
t = 0.5

@printf()では以下のように桁数を決めて表示できます.

使用例1
for i in 0:10
    @printf("t = %0.2f\n", i*0.05)
end

t = 0.00
t = 0.05
t = 0.10
t = 0.15
t = 0.20
t = 0.25
t = 0.30
t = 0.35
t = 0.40
t = 0.45
t = 0.50

使用例2

LaTeXStrings.jlを使うと, 以下のようにLaTeX表示させることもできます.

使用例2
# using Pkg
# Pkg.add("LaTeXStrings")
using LaTeXStrings

for i in 0:10
    latexstring(@sprintf("t = %0.2f", i*0.05)) |> display
end

t = 0.00
t = 0.05
t = 0.10
t = 0.15
t = 0.20
t = 0.25
t = 0.30
t = 0.35
t = 0.40
t = 0.45
t = 0.50

使用例3

Plots.jlの使い方に関しては こちらの記事 を参考にしてください. 以下では拡散方程式

\frac{\partial u(x,t)}{\partial t} = D\frac{\partial^2 u(x,t)}{{\partial x}^2}

の初期条件u(x,0)=\delta(x-x_0)と境界条件u(\pm\infty,t)=0に対応する解

u(x,t) = \frac{1}{\sqrt{4\pi Dt}} \exp \left( -\frac{(x-x_0)^2}{4Dt} \right)

を描写します.

使用例3
# using Pkg
# Pkg.add("LaTeXStrings")
# Pkg.add("Plots")
using LaTeXStrings
using Plots

f(x,t;D=1,x0=0) = exp(-(x-x0)^2/(4*D*t)) / sqrt(4*D*pi*t)

plt = plot(layout=(3,3), size=(800,600))
for i in 1:9
    t = i*0.05
    plot!(plt, -2:0.01:2, x->f(x,t), label="", yrange=(0,1), xlabel=L"x", ylabel=L"f(x,t)", titlefontsize=12, title=latexstring(@sprintf("t=%0.2f", t)), subplot=i)
end
display(plt)

参考文献

他の言語と比較しても動作に問題はないようです.
https://alvinalexander.com/programming/printf-format-cheat-sheet/

公式ドキュメントはこちら.
https://docs.julialang.org/en/v1/stdlib/Printf/

この記事は簡単なメタプログラミングを用いて作成しました.
https://gist.github.com/ohno/f560726b0435aed72ecc506499017639

Discussion

ultimatileultimatile

formatterに変数を使う

formatterを変数で管理しようとすると苦戦したのでcommentします.

何を言っているのかというと, 他の言語でも同じだと思いますが

format = "2.2f"
@printf "%$(format)" 1.0

としても通りません.
formatterは書いてある文字列がそのまま解釈されます.
つまり%$(format)という文字列そのものがformatterとして指定されたことになり, printfは何を言ってるんだこいつ?となるわけです.

解決方法として, この記事の作成方法として言及されていますが, 以下のようにmetaprogramming的なcode展開をしてやれば良いです.

format = "2.2f"
eval(Meta.parse("@printf \"%$(format)\" 1.0"))

これで実際のcodeは@printf %2.2f 1.0が実行されることになります.

2023/09/29追記: fileに書き込む場合はこの方法だとerrorは出ませんが何も書き込まれません.
原因はよく分かりませんが代わりに

format = "2.2f"
open("output.dat", "w") do fp
    Printf.format(fp, Printf.Format("%$(format)"), 1.0)
end

とするとこの場合も出力されます.
詳しくは実践Julia入門 3-2-1を参照してください.