はじめに
Cythonを使用してコードを書いていた時、型に関する初歩的なミスに気付くまで少し時間をかけてしまったので自戒を込めて記事を書くことにしました。
内容
Cythonを使用して高速化したいコード中で小数の結果を得たいのにint型の数aと同じくb(ただし$a < b$)の割り算をした時に結果が0になる仕様に気付かずに時間をかけた。
具体的に次のようなb.pyxとbの関数fを呼び出して結果を表示するaがある場合関数f内のa/bはint型の同士の割り算なので結果もint型となります。
a.py
import pyximport; pyximport.install()
import b
print(b.f(2, 3)) # 0
b.pyx
cpdef f(int a, int b):
return a / b # C言語でのint型同士の割り算と同じ
解決策
キャストにより解決できるがCythonでのキャストはキャストしたい変数の前に<型名>を記述する。
a.py
import pyximport; pyximport.install()
import b
print(b.f(2, 3)) # 0.6666666666666666
b.pyx
cpdef f(int a, int b):
print(type(a)) # <class 'int'>
print(type(<double>a)) # <class 'float'>
return <double>a / b # 結果はfloat型になる
おわりに
文法がほとんどPythonと同じなので意識から外れていたけど型指定してC言語に変換してコンパイル、実行してるから考えれば当然だなと思いました。
コードを少し変更するだけで実行速度を速くしてくれるCythonに感謝。