算術型

PyFIE では FIE(C 言語) で使用される算術型(UCHARINT など)に対応する PyFIE データ型が用意されています。 これを PyFIE 算術型と呼ぶことにします。

PyFIE 算術型には pyfie.UCHARpyfie.INT など FIE(C 言語) の各算術型に対応した型と、 C 言語の列挙型 (enum) に対応した型 pyfie.enum が含まれます。 これら( PyFIE 算術型に含まれる算術型種別 )を PyFIE 算術型の数値種別と呼ぶことにします。


PyFIE 算術型が必要となる背景

まず PyFIE 算術型が必要となる背景について説明します。

Python での変数(厳密には "名前" または "識別子")は全てオブジェクトへの参照であり 算術型(に相当するクラス)は不変型(immutable)です。 つまり Python において例えば "1" という数値が代入された変数は、 (どこかに存在している) "1" という数値を表現した 不変のオブジェクトへの参照が格納されていることになります。 オブジェクト自体がデータ(ここでは数値)の入れ物ではないので、 データを変更するために(データ格納先の)ポインタを取得するといったことが基本的にできません。

これに対し PyFIE 算術型のインスタンスは C 言語互換データを格納するためのメモリブロックを内部にもっており、 そこに数値を格納します。 つまり C 言語の算術型変数のようにデータの入れ物として使用することができ、 データ格納先のポインタを取得することが可能となっています。 (ポインタについての詳細は ポインタ を参照してください。)

PyFIE 関数は FIE(C 言語) 互換インターフェースとなっているため、 その引数に変数のポインタを要求するものがあります。 このような引数に対しては PyFIE 算術型を使用し、 そのポインタを渡すことができます。

このように PyFIE 算術型は 基本的に PyFIE 関数の引数へ変数のポインタを渡す(参照渡しする)際に必要となるものであり、 それ以外の場合で必要となることはあまりないでしょう。

以下では PyFIE 算術型の使用方法について解説していきます。


PyFIE 算術型の使用方法

まず、 PyFIE 算術型はそのコンストラクタによりインスタンス化します。 これは C 言語における算術型変数の宣言に相当します。

C 言語
INT i = 0;
DOUBLE d = 0.0;
Python
i = pyfie.INT()
d = pyfie.DOUBLE()

上記のようにコンストラクタの引数に何も指定しなかった場合、 インスタンスの値は 0 で初期化されます。 初期値を与えてインスタンス化する場合には、 コンストラクタの引数で初期値を指定します。

C 言語
INT i = 3;
Python
i = pyfie.INT(3)

インスタンス化された算術型に格納されている値を変更する場合は下記のように属性 value を使用します。

C 言語
INT i;
i = 3;
Python
i = pyfie.INT()
i.value = 3

注釈

ここで下記のような代入を行った場合、 当然 i は Python 組み込み型 int に上書きされてしまうことに注意してください。

i = pyfie.INT()   # i は PyFIE 算術型 INT のインスタンス.
i = 3             # i は Python 組み込み型.

注釈

PyFIE 算術型の属性 value による値の代入では、 その算術型に変換可能なオブジェクトを使用することができます。

詳しくは PyFIE 算術型のオブジェクト変換 を参照してください。

属性 value を参照すると Python 組み込み型として値が取得されます。

Python
i = pyfie.INT(3)
j = i.value        # j は Python 組み込み型 (int)

PyFIE データ型を変数に代入する際の C 言語との挙動の違い

ここで C 言語との直感的な挙動の違いについて補足します。

Python での変数は常にオブジェクトへの参照となります。 そのため PyFIE データ型インスタンスを他の変数に直接代入した場合、 2 つの変数は同じインスタンスを参照することになります。

つまり下記のサンプルコードは C 言語と Python とで異なる挙動を示していることになります。

C 言語
INT i = 3;
INT j = i;
// i と j は別な実態である.

j = 10;
// j の値に 10 を設定しても
// 当然 i の値は 3 のままである.
Python
i = pyfie.INT(3)
j = i
# ここで j と i は同じ実態を参照することに注意.

j.value = 10
# j の値に 10 を設定することにより
# 同じ実態である i の値も 10 となる.

注釈

この挙動は C 言語と Python の言語仕様の違いによるものであり、 PyFIE 算術型に限らず他の PyFIE データ型に対しても同様のことが当てはまります。


異なる PyFIE 算術型インスタンス間で値の代入を行う場合は、 下記のように属性 value を使用します。

C 言語
INT i = 3;
INT j;

j = i;
Python
i = pyfie.INT(3)
j = pyfie.INT()

j.value = i

PyFIE 算術型の型変換

PyFIE 算術型のコンストラクタには、 他の数値種別の PyFIE 算術型インスタンスを渡すことができます。 このとき新しく作成される PyFIE 算術型インスタンスの値は、 引数に渡されたインスタンスの値と同じになります。

C 言語
DOUBLE d = 3.7;
INT i = (INT)d;
Python
d = pyfie.DOUBLE(3.7)
i = pyfie.INT(d)
# i は値 3 をもつ pyfie.INT 型となる.

また Python 組み込み型である int や float のコンストラクタにも、 同様に PyFIE 算術型インスタンスを渡すことが可能です。

Python
i = pyfie.INT(3)
j = int(i)         # j は Python 組み込み型 int.   (値は 3)
k = float(i)       # k は Python 組み込み型 float. (値は 3.0)

PyFIE 算術型のポインタ

PyFIE 算術型インスタンスのポインタは属性 ref により取得できます。

C 言語
INT i;
&i;
Python
i = pyfie.INT()
i.ref

ポインタについての詳細は ポインタ の章を参照してください。


PyFIE 算術型の演算

PyFIE 算術型は下記のような演算子をサポートしています。

二項演算子

+ - * / // % ** << >> & | ^

単項演算子

+ -

代入演算子

+= -= *= /= //= %= **= <<= >>= &= |= ^=

比較演算子

< <= > >= == !=

二項演算子は PyFIE 算術型を含む( または PyFIE 算術型どうしの )演算に使用することができます。 この場合、 演算結果は常に Python の組み込み型となります。

Python
a = pyfie.INT(12)
b = pyfie.DOUBLE(34.5)
c = 67

d = a + b   # PyFIE 算術型どうしの演算. 結果は Python 組み込み型となる.
e = b + c   # PyFIE 算術型と Python 組み込み型の演算. 結果は Python 組み込み型となる.

PyFIE 算術型に対する単項演算子の結果も同様に、 Python の組み込み型となります。

Python
a = pyfie.INT(12)
b = +a   # b は値  12 をもつ Python 組み込み型となる.
c = -a   # c は値 -12 をもつ Python 組み込み型となる.

PyFIE 算術型に対する代入演算子による累算代入文は、 インスタンスが保持する値そのものを更新します。

Python
a = pyfie.INT(12)
a += 100   # a のもつ値(value)は 112 となる.

PyFIE 算術型に対する比較演算子 <<=>>===!= は、 PyFIE 算術型どうしまたは Python 組み込み型等他の型との比較に使用できます。

注釈

Python 組み込み型と同様に、浮動小数点数を表す PyFIE 算術型 ( pyfie.DOUBLE など)に対して演算子 << >> & | ^ <<= >>= &= |= ^= を用いたビット演算を行うことはできません。


PyFIE 算術型のフォーマット化

PyFIE 算術型は Python 組み込み型と同様に、フォーマット化された文字列表現を取得できます。

Python
i = pyfie.INT(3)
d = pyfie.DOUBLE(3.7)

print("{:04d}, {:.2f}".format(i, d)) # "0003, 3.70"と表示される

PyFIE 算術型のオブジェクト変換

PyFIE 算術型は特定の状況において、 下記オブジェクトからの変換が可能となります。

  • 異なる数値種別の PyFIE 算術型

  • Python 組み込みの数値型

  • Python 組み込みの文字列型 ( str

  • Python 組み込みのブール型 ( bool

数値を表現した文字列を使用した場合は、 文字列から数値へ変換されます。 (この変換は Python により行われますので、 その変換仕様も Python に準じます)

また PyFIE 定数の名前を文字列として使用した場合は、 対応する定数値へ変換されます。


これらの変換は、 下記状況において行うことができます。

  • PyFIE 算術型の属性 value に対する代入時

  • PyFIE 算術型ポインタの属性 deref に対する代入時

  • PyFIE 算術型配列の各要素に対する代入時

  • PyFIE 構造体の算術型メンバに対する代入時

  • PyFIE 関数の算術型引数に対する指定時

以下に例を示します。

C 言語
UCHAR c;
c = UC8_MAX;
Python
c = pyfie.UCHAR()
c.value = "UC8_MAX"
C 言語
INT i;
INT * p = &i;

*p = 123.45;
Python
i = pyfie.INT()
p = i.ref   # PyFIE 算術型 i のポインタ取得

# PyFIE 算術型の属性 deref に対して
# 異なる数値型の PyFIE 算術型を設定する例.
# (i の値は 123 となる)
p.deref = pyfie.DOUBLE(123.45)
C 言語
DOUBLE ary[3];

ary[0] = 123.45;
Python
ary = pyfie.DOUBLE.ARRAY(3)

# PyFIE 算術型配列の要素に対して
# 数値を表現する文字列を設定する例.
ary[0] = "123.45"
C 言語
PNT_T pnt;

pnt.x = UC8_MAX;
pnt.y = UC8_MAX;
Python
pnt = pyfie.PNT_T()

# 構造体の PyFIE 算術型メンバに対して
# PyFIE 定数名を文字列として設定する例.
pnt.x = "UC8_MAX"

# 当然 PyFIE 定数を使用することも可能.
pnt.y = pyfie.UC8_MAX