Fortran 95 区間演算プログラミングリファレンス ホーム目次前ページへ次ページへ索引


第 2 章

f95 区間リファレンス

この章は、Sun WorkShop 6 の Fortran 95 に実装された組み込みの INTERVAL 型の構文と意味論のリファレンスになっています。各節は任意の順序で読むことができます。

別途明示的な記述がない限り、INTERVAL データ型は他の組み込みの数値型と同じ特性を持っています。この章では REAL 型とINTERVAL 型の相違点に焦点をあてます。

コード例の中には完全でないプログラムも存在します。これらの例は、-xia コマンド行オプションを使ってコンパイルすることが暗黙に想定されています。

Fortran 拡張

INTERVAL データ型は Fortran に対する非標準の拡張です。しかし、実現可能な箇所では、実装構文と意味論は Fortran 形式に準拠しています。

文字セットの表記

Fortran 文字セットには、区間文字定数を区切るため、左右の角括弧「[...]」が追加されています。

このマニュアルの全体を通じて、別途明示的な記述がない限り、INTEGER、REAL、INTERVAL の各定数は文字定数を意味します。定数式と名前付き定数 (PARAMETERS) は常に明示的に区別されます。

表 2-1 はコードと算術に用いられる文字セットの表記を示しています。

表 2-1   書体の変換
文字セット 表記
Fortran コード
INTERVAL :: X=[0.1,0.2]
プログラムとコマンドへの入力
Enter X: ? [2.3,2.4]
コード内部の定数用の可変部分
[a,b]
スカラー演算 x(a + b) = xa + xb
区間演算 X(A + B) XA + XB



注 - フォントの使用にはよく注意してください。異なるフォントは区間の正確な外部数学値と区間のマシン表現可能な内部的な近似値を表します。

区間定数

f95 では、区間定数は、単一の整数または角括弧で囲んだ実 10 進数 [3.5] のいずれか、あるいは、一対の整数またはコンマで区切り角括弧で囲んだ実 10 進数
[3.5 E-10, 3.6 E-10] のいずれかです。縮退した区間がマシンで表現できない場合、正確な算術値は指定された丸めを使って、内部的な制約を満たすことが明らかな内部的なマシン表現可能な区間に丸められます。

デフォルトINTEGER、デフォルト REAL または REAL(8) の両終了点を持つ 区間定数はデフォルト型区間を持ちます。

終了点の型がデフォルト INTEGER、デフォルト REAL または REAL(8) である場合、その終了点は内部的に REAL(8) 型の値へと変換されます。

終了点の型が INTEGER(8) である場合、その終了点は内部的に REAL(16) 型の値へと変換されます。

終了点の型がINTEGER(4)である場合、その終了点は内部的に REAL(8)型の値へと変換されます。

終了点の型が INTEGER(1) または INTEGER(2) である場合、その終了点は内部的に REAL(4) 型の値へと変換されます。

両方の終了点が REAL型であり、異なる KTPV を持つ場合、それらはより大きい小数点精度を持つ終了点の近似値手法を用いて内部的に表現されます。

区間定数の KTPV は、最大小数点精度を持つ部分の KTPV です。

コード例 2-1 は、さまざまな 区間定数の KTPV を示しています。

コード例 2-1   区間定数の KTPV

math% cat ce2-1.f95
IF(KIND([9_8, 9.0])      == 16 .AND. &
   KIND([9_8, 9_8])      == 16 .AND. & 
   KIND([9_4, 9_4])      == 8  .AND. & 
   KIND([9_2, 9_2])      == 4  .AND. &
   KIND([9, 9.0_16])     == 16 .AND. & 
   KIND([9, 9.0])        == 8  .AND. & 
   KIND([9, 9])          == 8  .AND. & 
   KIND([9.0_4, 9.0_4])  == 4  .AND. & 
   KIND([1.0Q0, 1.0_16]) == 16 .AND. & 
   KIND([1.0_8, 1.0_4])  == 8  .AND. & 
   KIND([1.0E0, 1.0Q0])  == 16 .AND. & 
   KIND([1.0E0, 1])      == 8  .AND. & 
   KIND([1.0Q0, 1])      == 16 ) PRINT *, 'Check'
END
math% f95 -xia ce2-1.f95

0.1 または [0.1,0.2] のような Fortran 定数は、定数が表す外部値と内部的な近似値の 2 つの値に関連付けられます。Fortran では、定数の値はその内部的な近似値です。定数の外部値と定数の内部的な近似値とを区別する必要はありません。区間ではこれを区別する必要があります。Fortran 定数の外部値を表すには、次の表記が用いられます。

ev(0.1) = 0.1、または、ev([0.1,0.2])= [0.1, 0.2]

ev の表記は外部値を表します。

Fortran 規格に従えば、区間定数の数値は、その内部的な近似値となります。区間定数の外部値は常に明示的にそのように標識付けられます。

たとえば、区間定数 [1, 2] とその外部値 ev ([1, 2]) は、数学値 [1, 2] と同じです。しかし、ev ( [0.1, 0.2] ) = [0.1, 0.2] ですが、数 0.1 と 0.2 はマシンで表現できないので、[0.1, 0.2] は単なるマシンの内部的な近似値にすぎません。このため、区間定数の値 [0.1, 0.2] は、マシン内部の近似値なのです。この外部値は ev
( [0.1, 0.2] ) で表されます。

厳密区間式処理のもとでは、他の Fortran 数値定数の場合と同様に、区間定数の内部的な近似値は固定されます。REAL 定数の値はその内部的な近似値です。同様に、区間定数の内部的な近似値の値は定数の値として参照されます。定数の外部値 (標準 Fortran の定義概念ではありません) は、その内部的な近似値と異なることもあります。最大幅要求式処理のもとでは、区間定数の値は文脈に依存します。しかしその場合でも、strict と最大幅要求式処理の両方で、区間定数の内部的な近似値はその外部値を含まなければなりません。

任意の数学定数と同様に、区間定数の外部値は不変です。名前付き区間定数 (PARAMETER) の外部値は 1 つのプログラム単位の中では変更できません。しかし、任意の名前付き定数の場合と同様に、異なるプログラム単位間では同じ名前付き定数に異なる値を関係付けることができます。

区間は不透明ですから、区間を内部的に表現するのに必要な情報を格納する言語要件は存在しません。区間の最大下限と最小上限にアクセスするために組み込み関数が提供されています。しかし、区間定数は順位付けられた 1 対の REAL または区間定数により定義されます。定数はカンマにより区切られ、1 対の情報は角括弧で囲まれます。第 1 定数は最大下限 (infimum) であり、第 2 定数は最小上限 (supremum) です。

角括弧の中に 1 つの定数が現れる場合に限り、表現される区間は縮退して、同じ最大下限と最小上限を持つようになります。この場合、単一の小数文字定数の外部値を含むことが保証された区間の内部的な近似値が構築されます。

有効な区間は、最小上限より小さいかまたは等しい 1 つの最大下限を持たなければなりません。同様に、区間定数もまた、その最小上限より小さいかまたは等しい 1 つの最大下限を持たなければなりません。たとえば、次の部分コードは true と評価されなければなりません。

INF([0.1]) .LE. SUP([0.1])

コード例 2-2 は、有効な区間定数と無効な区間定数を含んでいます。

区間定数に関する追加情報については、「参考文献」で引用している捕捉 [4] を参照してください。

コード例 2-2   有効な区間定数と無効な区間定数

X=[2,3]
X=[0.1] 	 ! 2 行目: 小数 1/10 を含む区間
X=[2, ] 	 ! 3 行目: 無効 - 最小上限がない
X=[3_2,2_2] 	 ! 4 行目: 無効 - 最大下限 > 最小上限
X=[2_8,3_8]
X=[2,3_8]
X=[0.1E0_8]
X=[2_16,3_16]
X=[2,3_16]
X=[0.1E0_16]

内部的な近似値

REAL 定数の内部的な近似値は定数の外部値と同じであるとは限りません。たとえば、10 進小数 0.1 は 2 進の浮動小数点数集合のメンバーではないので、この値は 0.1 に近い 2 進の浮動小数点数によって近似されます。REAL データ項目について、Fortran 規格では近似の正確性は指定されていません。区間データ項目については、区間定数を記号的に表現するのに使われる 10 進小数を使用して定義された 1 組の数学値を含むことで知られた、一対の浮動小数点数値が用いられます。たとえば、数学区間 [0.1, 0.2] は、区間定数 [0.1,0.2] の外部値です。

Fortran 言語に REAL 定数の正確な近似値を求める要件が存在しないのと同様に、狭い幅の区間定数を使って区間の外部値の近似値を求める言語要件も存在しません。区間定数にはその外部値を含むという要件があります。

ev(INF([0.1,0.2])) inf(ev([0.1,0.2])) = inf([0.1, 0.2])

および、

sup([0.1, 0.2]) = sup(ev([0.1,0.2])) ev(SUP([0.1,0.2]))

です。

f95 の区間定数は鋭い値です。これは、実装品質の特性です。

区間文

区間宣言文は、f95 の Fortran 言語に追加された唯一の区間固有の文です。区間データ項目との対話を行う 区間宣言文と標準 Fortran 文の詳細な解説については、「INTERVAL」を参照してください。

データ型とデータ項目

f95 のコマンド行に、-xia、または、-xinterval オプションが入力されるか、あるいは、これらのオプションが widestweed とstrict のいずれかに設定されると、INTERVAL データ型は f95 の組み込みの数値データ型として認識されます。f95 のコマンド行にいずれのオプションも入力されないか、あるいは、使用しないと設定されると、INTERVAL データ型は組み込みのデータ型とは認識されません。区間のコマンド行オプションの詳細については、「区間のコマンド行オプション」を参照してください。

名前:INTERVAL

6 個の組み込みの Fortran データ型に、組み込み型の INTERVAL が追加されています。INTERVAL 型は、区間データ項目の内部形式が明記されていないという意味で不透明です。しかし、区間データ項目の外部形式は、区間データ項目と同じ種別型パラメータ値 (KTPV) を持つ一対の REAL データ項目です。

種別型パラメータ値 (KTPV)

区間データ項目は、最大下限と最小上限で構成される算術区間の近似値です。区間データ項目は他の数値データ項目のすべての特性を持っています。

デフォルト区間データ項目の KTPV は 8 です。KTPV の指定のないデフォルト区間データ項目のサイズは 16 バイトです。f95 のデフォルト区間データ項目のサイズは、-xtypemap、または、-r8const コマンド行オプションを使って変更することはできません。より詳細な情報については、「-xtypemap と -r8const コマンド行オプション」を参照してください。このため、-xtypemap を使ってデフォルトの REAL と INTEGER データ項目のサイズが変更されなければ、次のようになります。

KIND([0])= 2*KIND(0) = KIND(0.0_8) = 8

サイズと境界整列のまとめ

INTERVAL 型のサイズと境界整列は、f95 コンパイラオプションの影響を受けません。表 2-2 は、INTERVAL のサイズと境界整列を含んでいます。

表 2-2   INTERVAL のサイズと整列
データ型 バイトサイズ 境界整列
INTERVAL
INTERVAL(4)
INTERVAL(8)
INTERVAL(16)
16
8
16
32
8
4
8
16



注 - 区間配列は要素と同じ並びになります。

区間配列

区間配列は、異なる数値型のすべての配列特性を持っています。区間配列の宣言については、コード例 2-25 を参照してください。

次の配列組み込み関数については、区間バージョンがサポートされています。

ALLOCATED()、ASSOCIATED()、CSHIFT()、DOT_PRODUCT()、EOSHIFT()、KIND()、LBOUND()、MATMUL()、MAXVAL()、MERGE()、MINVAL()、NULL()、PACK()、PRODUCT()、RESHAPE()、SHAPE()、SIZE()、SPREAD()、SUM()、TRANSPOSE()、UBOUND()、UNPACK()

MINVAL と MAXVAL 組み込み関数が区間配列に適用されると、配列の要素により処理されない区間値を返す可能性があるので、区間配列用の MINLOC() と MAXLOC() 組み込み関数は定義されていません。MAX と MIN 組み込み関数の解説については、下記の節を参照してください。

例:MINVAL((/[1,2],[3,4]/)) = [1,3]

MAXVAL(/[1,2],[3,4]/) = [2,4]

次の組み込み区間個別関数については、配列バージョンがサポートされています。

ABS()、INF()、INT()、MAG()、MAX()、MID()、MIG()、MIN()、NDIGITS()、SUP()、WID()

次の組み込み区間算術関数については、配列バージョンがサポートされています。

ACOS()、AINT()、ANINT()、ASIN()、ATAN()、ATAN2()、CEILING()、COS()、COSH()、EXP()、FLOOR()、LOG()、LOG10()、MOD()、SIGN()、SIN()、SINH()、SQRT()、TAN()、TANH()

次の区間構成子については、配列バージョンがサポートされています。

INTERVAL()、DINTERVAL()、SINTERVAL()、QINTERVAL()

区間演算式

区間算術式は、他の数値データ型と同じ算術演算子から構築されます。区間式と非区間式間の基本的な相違点は、任意の可能な区間式の結果が区間演算の包合の制約を満たす有効な区間であるということです。これと対照的に、非区間式の結果は任意の近似値であってもかまいません。

混合モードの区間式

混合モード (区間の点) 式は包含を保証するために、最大幅要求式処理が必要となります。-xia コマンド行マクロ、または、-xinterval コマンド行オプションを使用して区間サポートが呼び出された場合の式処理は、デフォルトで最大幅要求となります。最大幅要求の評価が好ましくない場合は、-xia=strict、または、-xinterval=strict のオプションを使って厳密式処理を呼び出してください。厳密式処理のもとでは、混合モードの区間式はコンパイル時エラーとなります。区間とCOMPLEX オペランド間の混合モード演算はサポートされていません。

最大幅要求式処理を使うと、区間式中のすべてのオペランドの KTPV は、全体を通じて最大の区間 KTPVである KTPVmaxへと昇格されます。


注 - KTPV 昇格は式の評価前に実行されます。

最大幅要求式評価の保証:

次の例では最大幅要求式処理の動作と効果を示しています。各例には、次の 3 つのコードブロックが存在します。

例は、次の 3 つのメッセージを伝えるように設計されています。

値の代入

区間の代入文は、区間のスカラー、配列要素または配列式の値を区間変数、配列要素または配列に代入します。この構文は次のとおりです。

V = expr

expr は区間演算または配列式の可変部分であり、V は区間変数、配列要素または配列です。

区間の代入を実行すると、最大幅要求または厳密式処理を使用して式が評価されます。この後で、結果の値が V に代入されます。最大幅要求式処理を用いた式の評価では次の手順が発生します。

1. すべての点 (非区間) データ項目の区間 KTPV が計算されます。

点項目が整数であれば、結果としての区間の KTPV は整数の KTPV の 2 倍となります。その他の場合、区間の KTPV は点項目の KTPV と同じです。

2. 代入文の左側を含む式が走査され、KTPVmax で表される最大区間 KTPV が求められます。

3. 式の評価に先立ち、区間式の中のすべての点と区間データ項目が式の評価に先立ち、KTPVmax へと昇格されます。

4. KIND(V) < KTPVmax であれば、式の結果は KTPV = KIND(V) を持つ区間を含むものへと変換され、その結果としての値が V に代入されます。

コード例 2-3   KIND (左側) に依存するKTPVmax

math% cat ce2-3.f95
INTERVAL(4)  :: X1, Y1
INTERVAL     :: X2, Y2          ! INTERVAL (8) :: X2, Y2 と同じ 
INTERVAL(16) :: X3, Y3

 
! 最大幅要求コード
 X1 = 0.1                                            
 X2 = 0.1                                
 X3 = 0.1

 
! 同等の厳密コード
Y1 = [0.1_4]
Y2 = [0.1_8]
Y3 = [0.1_16]

 
IF(X1 .SEQ. Y1)  PRINT *, "Check 1"
IF(X2 .SEQ. Y2)  PRINT *, "Check 2"
IF(X3 .SEQ. Y3)  PRINT *, "Check 3"
END 
 
math% f95 -xia ce2-3.f95
math% a.out
 Check 1
 Check 2
 Check 3


注 - 最大幅要求のもとでは、代入先変数 (左側) の KTPV は、区間文のすべての項目が昇格されることになる、KTPVmax 値の決定要素に含まれます。

コード例 2-4   混合モードの代入文

math% cat ce2-4.f95
INTERVAL(4) :: X1, Y1
INTERVAL(8) :: X2, Y2
REAL(8)     :: R = 0.1

 
! 最大幅要求コード
 X1 = R*R 	 ! 4行目
 X2 = X1*R 	 ! 5行目

 
! 厳密と等価なコード
 Y1 = INTERVAL((INTERVAL(R, KIND=8)*INTERVAL(R, KIND=8)), KIND=4	 )! 6行目
 Y2 = INTERVAL(X1, KIND=8)*INTERVAL(R, KIND=8) 	 ! 7行目

 
IF((X1 == Y1)) PRINT *, "Check 1" 	 ! 8行目
IF((X2 == Y2)) PRINT *, "Check 2" 	 ! 9行目
END
 
math% f95 -xia ce2-4.f95
math% a.out
 Check 1
 Check 2

コード例 2-4 注記:

区間のコマンド行オプション

f95 コンパイラでの区間機能は次のコマンド行オプションにより起動されます。

コマンド行処理の末尾に、xinterval=(widestneed|strict) が設定され、さらに -fsimple または -fns が -fsimple=0、-fns=no 以外の値に設定されると致命的なエラーになります。

コマンド行オプションの使用時:

INTERVAL 型を認識するよう起動した場合:

-xtypemap と -r8const コマンド行オプション

区間キーワードだけを使って宣言されたデフォルト区間変数のサイズは、-xtypemap と -r8const のコマンド行オプションを使って変更することはできません。

これらのコマンド行オプションはデフォルトの INTERVAL 型には影響を与えませんが、コード例 2-5 で示しているように、混合モードの区間式の結果を変更することができます。

コード例 2-5   混合モードの式

math% cat ce2-5.f95
REAL     :: R 
INTERVAL :: X
R = 1.0E0 - 1.0E-15
PRINT *, 'R = ', R
X = 1.0E0 - R
PRINT *, 'X = ', X
IF (  0.0 .IN. X  ) THEN 
    PRINT *, 'X contains zero'
ELSE 
    PRINT *, 'X does not contain zero'
ENDIF    
PRINT *, 'WID(X) = ', WID(X)
END
math% f95 -xia ce2-5.f95
math% a.out
 R =  1.0
 X =  [0.0E+0,0.0E+0]
 X contains zero
 WID(X) =  0.0E+0
math% f95 -xia -xtypemap=real:64,double:64,integer:64 ce2-5.f95 
math% a.out
 R =  0.999999999999999
 X =  [9.9920072216264088E-16,9.9920072216264089E-16]
 X does not contain zero
 WID(X) =  0.0E+0


注 - -xtypemap は X の KTPV に影響を及ぼしませんが、X の値には影響を与えることができます。

定数式

区間の定数式は、任意の点定数式構成要素だけでなく、区間のリテラルと名前付き定数を含む場合があります。このため、各オペランドまたは引数はそれ自体が、他の定数式、定数、名前付き定数、あるいは、定数引数を使って呼び出された組み込み関数です。

コード例 2-6   定数式

math% cat ce2-6.f95
INTERVAL :: P, Q
! 最大幅要求コード
P = SIN([1.23])+[3.45]/[9, 11.12]

 
! 等価な厳密コード
Q = SIN([1.23_8])+[3.45_8]/[9.0_8, 11.12_8]
IF(P .SEQ. Q) PRINT *, 'Check'
END
math% f95 -xia ce2-6.f95
math% a.out
 Check


注 - 最大幅要求式のもとでは、区間定数の KTPV は区間の文脈に基づき決定されます。より詳細な情報については、「デフォルトの種別型パラメータ値 (KTPV)」を参照してください。

区間定数の使用が許可される場合は、常に区間定数式が使用できます。

組み込み演算子

表 2-3 は、区間演算で使用できる組み込み演算子を一覧にしたものです。表 2-3 では、X と Y は区間を表します。

表 2-3   組み込み演算子
演算子 演算 式 意味
** べき乗 X**Y X をINTERVAL Y 乗する


X**N X をINTEGER N 乗する (注記1を参照)
* 乗算 X*Y X と Y を乗ずる
/ 除算 X/Y X を Y で除する
+ 加算 X+Y X と Y を加算する
+ 同一 +X (符号なし) X と同じ
- 減算 X-Y X から Y を減ずる
- 数値否定 -X X を否定する
.IH. INTERVAL包 X.IH.Y X と Y の区間包
.IX. 積集合 X.IX.Y X と Y の積集合
(1) N が整数式であればオーバーフローにより包含のエラー修正が発生する可能性があります。これは f95 の区間サポートの最初のリリースではエラー修正できない既知のエラーです。このエラーが修正されるまでは、ユーザーの責任で整数のオーバーフローを防止してください。さらに詳細な情報については、「整数オーバーフロー」を参照してください。


演算子の優先順位:

区間 ** 演算子と整数指数を別にすれば、区間演算子は同じ KIND 型のパラメータ値を持つ 2 つの区間オペランドにだけ適用することができます。このため、区間演算子の結果の型と KTPV はそのオペランドの型 KTPV と同じです。

区間 ** 演算子の第 2 オペランドが整数であれば、第 1 オペランドは任意の区間 KTPV となることができます。この場合、結果は第 1 オペランドの型と KTPV を持ちます。

いくつかの区間個別演算子は点 (非区間) 用演算子がありません。表 2-4 で示すように、これらの演算子は「set」、「certainly」、「possibly」の 3 つのグループにまとめることができます。いくつかの固有の集合演算子は「certainly」または「possibly」の相当する演算子がありません。

表 2-4   組み込み区間関係演算子
set 関係演算子
.SP.
.PSP
.SB.
.PSB.
.IN.
.DJ.

.EQ.
(== と同様)
.NEQ.
(/= と同様)





.SEQ.
.SNE.
.SLT.
.SLE.
.SGT.
.SGE.
certainly 関係演算子
.CEQ.
.CNE.
.CLT.
.CLE.
.CGT.
.CGE.
possibly 関係演算子
.PEQ.
.PNE.
.PLT.
.PLE.
.PGT.
.PGE.


組み込み区間関係演算子の先行オペランドは REAL 関係演算子の場合と同じです。

.IN. 演算子を除き、組み込み区間関係演算子は、同じ KTPV を持つ 2 つの区間オペランドにだけ適用することができます。

.IN. 演算子の第 1 オペランドは任意の INTEGER 型または REAL 型です。第 2 オペランドには任意の区間 KTPV を持つことができます。

区間関係式の結果はデフォルトの LOGICAL 種類型のパラメータを持ちます。

算術演算子 +、-、*、/

有限の REAL 区間に関する区間演算の終了点の計算公式は、すべての可能性のある点結果の集合を含むことが保証された最も狭い区間を生成する必要性からもたらされました。Ramon Moore は、これらの公式をより重要な意味で独自に開発し、また区間演算への適用に必要な分析をはじめて開発しました。より詳細な情報については、R. Moore 著『Interval Analysis』、Prentice-Hall (1966年) を参照してください。

すべての可能な値の集合は、オペランド区間の任意の要素に関する演算課題を実行することにより独自に定義されています。このため、 を持つ所与の有限区間 [a,b] と [c,d] は、ゼロによる除算を除外すれば、次のようになります。

この公式または論理的に同じものは以下のようになります。

生成される区間にすべての可能な値の集合が含まれることを保証するために、有限精度の算術を使った計算では有向の丸めが用いられます。

任意の区間の結果が含まなければならない値の集合は、結果を生成する演算または式の包含集合と呼ばれます。

包含集合は、(無限の終了点を持つ) 拡張区間とゼロによる除算を含むために、実値に関する算術演算の値に、直接依存することができません。拡張区間用の包含集合には、通常なら未定義の点に関する演算要件が課せられます。未定義の演算には不定形式 、 、 、 が含まれます。

包含集合の閉包単位は、特異なまたは不定な点での式の包含集合の値の識別の問題を解決します。この単位は包含集合が閉包であることを示します。変域の境界上の点での関数の閉包は、すべての集積点 (limit point または accumulation point) を含みます。詳細については、「用語」と 「参考文献」で引用した補足文献 [1]、[3]、[10]、[11] を参照してください。

記号表現では、cset(x op y, {(x0, y0)}) = となります。ここでは、 は op 演算の閉包を表し、{x0} は 1 つの要素 x0 だけを持つ単集合を表します。下付き文字の 0 は、変数 x の特異な値 x0 と変数自体を記号的に区別するのに用いられます。たとえば、x0 = 1、op =3 ÷、y0 = 0を使うと、x0³3 ÷ y0 は未定義となりますが、閉包は、 となります。

この結果は、次のような限界を持つ、

次のどちらかのシーケンスを使って取得できます。

、または、

この 2 つのシーケンスを使うと、x0 = 1、y0 = 0 での除算演算子の閉包である上記{yj}は次のようになります。

以下の表 2-5 から表 2-9 までの表は 4 つの基本算術演算子用の包含集合を示しています。

表 2-5   加算用の包含集合:cset(x +y, {(x0, y0)})
cset(x + y, {(x0, y0)}) {-} {real: y0} {+}
{-} {-} {-}
{real: x0} {-} {x0 + y0} {+}
{+} {+} {+}


表 2-6   減算用の包含集合:cset(x - y, {(x0, y0)})
cset(x - y, {(x0, y0)}) {-} {real: y0} {+}
{-} {-} {-}
{real: x0} {+} {x0 - y0} {-}
{+} {+} {+}


表 2-7   乗算用の包含集合:cset(x × y, {(x0, y0)})
cset(x × y, {(x0, y0)}) {-} {real: y0 < 0} {0} {real: y0 > 0} {+}
{-} {+} {+} {-} {-}
{real: x0 < 0} {+} {x × y} {0} {x × y} {-}
{0} {0} {0} {0}
{real: x0 > 0} {-} x × y {0} x × y {+}
{+} {-} {-} {+} {+}


表 2-8   除算用の包含集合:cset(x ÷ y, {(x0, y0)})
cset(x ÷ y, {(x0, y0)}) {-} {real: y0 < 0} {0} {real: y0 > 0} {+}
{-} [0, +] {+} {-, +} {-} [-, 0]
{real: x0 0} {0} {x ÷ y} {-, +} {x ÷ y} {0}
{0} {0} {0} {0} {0}
{+} [-, 0] {-} {-, +} {+} [0, +]


表の中のすべての入力は単集合として示しています。結果は、単集合、集合、または、区間として示しています。あいまいさを避けるため、たとえば、 、 、 のような慣行の表記を用いていません。これらの表は、各演算への単集合入力に対する結果を示しています。一般集合 (または区間) の入力に対する結果は、入力集合 (または区間) の範囲にまたがる単一点結果の合同です。

1 つのケースとして、ゼロによる除算では、結果は区間でなく、集合 です。この場合、区間算術の包含の制約に反しない現在のシステムでの最も狭い区間は、区間 となります。

符号の変更は期待とおりの結果を生成します。

これらの結果を区間終了点の計算用の公式に組み込むために必要なのは、同様に丸め方向に符号化される必要な終了点を識別することだけです。 を使って (- に対する) 丸め切り下げを表し、 を使って (+に対する) 丸め切り上げを表すと、以下のようになります。

and
and

同様に、 なので、

and

となります。

最後に、Fortran では空の区間は文字列 [empty] で表され、集合代数の で表される空の集合と同じ特性を持ちます。空の区間に関する任意の算術演算は空の区間結果を生成します。空の区間用法の追加情報については、「参考文献」で引用した補足文献 [6]、[7] を参照してください。

f95 は、これらの結果を用いて、閉じた区間システムを実装しています。すべての算術演算と関数は常に有効な区間結果を生成しますから、システムは閉じています。「参考文献」で引用した補足文献 [2]、[8] を参照してください。

べき乗演算子 X**N と X**Y

べき乗演算子は整数指数 (X**N) と共に使うことも、連続する指数 (X**Y) と共に使うこともできます。べき乗演算子は連続する指数と共に用いると、4 つの算術演算子に類似した不定の形式を持ちます。

整数指数のケースでは、 の囲みが含まなければならないすべての値の集合は、次のようになります。

単調性は、整数べき乗関数の鋭い区間の囲みを構築するのに使用できます。n = 0 であれば、すべての について、cset(xn, {x0}) = 1 であり、また、すべての N について、[empty]**N = [empty]となります。

連続する指数のケースでは、 の区間の囲みが含まなければならないすべての値の集合は次のようになります。

ここでは、 は、式 の包含集合です。関数 は、 の値だけを考慮する必要のあることを明示し、これは、Fortran での REAL 引数を持つ X**Y の定義と一貫性があります。

区間引数が空であるか、または、x < 0であれば、この結果は空になります。これは、Fortran での X**Y の点バージョンと一貫性があります。

表 2-9 は、cset(exp(yln (x)), {(y0, x0)}) のすべての特異点と不定形式についての内部的な集合を表しています。

表 2-9   cset(exp(yln(x)), {(y0, x0)})
x0 y0 cset(exp(yln(x)), {(y0, x0))}
0 y0 < 0 +
1 - [0,+]
1 + [0,+]
+ 0 [0,+]
0 0 [0,+]


表 2-9 の結果は、以下の 2 つの方法で求めることができます。

ほとんどの合成では、2 つ目のオプションを使う方が簡単です。十分な条件が満たされない場合、合成の囲みはその包閉の合成から計算することができます。つまり、各下位式の包閉を使って式全体の包閉を計算します。存在するケースでは次のようになります。

cset(exp(yln(x)), {x0, y0}) =

常にあてはまるケースは次のようになります。

cset(exp(yln(x)), {x0, y0})

これは区間演算が区間にどのように機能するか正確に表しているという点に留意してください。ln とexp 関数に必要な包閉は以下のとおりです。

包閉合成の等式に必要な条件は、式が単一用途式 (SUE = single-use expression) でなければならないことです。つまり、各独立変数は式の中で 1 回だけ現れることができることを意味します。

存在するケースでは、式は明らかに 1 つの SUE となります。

表 2-9 の項目は、ln とexp 関数の包閉に関する表 2-7 での基本乗算の包含集合用法の直接の結果です。たとえば、x0 = 1 と y0 = - を使うと、ln(x0) = 0 となります。表 2-7 での値 - と0 に関する乗算の包閉について、結果は [-, +] となります。最後に、表 2-9 での 2 番目の項目は、exp([-, +])= [0, +] となります。残りの項目も同じステップを使って取得できます。exp(y ln(x)) の包含集合から直接導くことで、これらと同じ結果が得られます。今度は、任意の式の包閉合成等式の十分な条件が明らかにされていません。しかし、それでも以下のようになります。

集合理論演算子

f95 は以下のような、2 つの区間の区間包と積集合を判定するための集合理論演算子をサポートしています。

包: X Y、または (X.IH.Y)

解説: 2 つの区間の区間包です。区間包はオペランド区間のすべての要素を含む最小の区間です。

数学定義:


引数: X と Y は、同じ KTPV を持つ区間でなければなりません。

結果型: X と同じです。

積集合: X Y、または (X.IX.Y)

解説: 2 つの区間の積集合です。

算術と演算の定義:


引数: X と Y は、同じKTPVを持つ区間でなければなりません。

結果型: X と同じです。

集合の関係

f95 は区間をサポートするために拡張された下記のような集合関係演算子を提供しています。

素: X Y = 、または (X.DJ.Y)

解説: 2 つの区間が素であるかどうかをテストします。

算術と演算の定義:


引数: X と Y は、同じ KTPV を持つ区間でなければなりません。

結果型: デフォルトの論理スカラーです。

要素: r Y、または (R.IN.Y)

解説: 数 R が区間 Y の要素であるかどうかをテストします。

算術と演算の定義:

引数: R の型は INTEGER または REAL であり、Y の型は INTERVAL です。

結果型: デフォルトの論理スカラーです。

次の注釈は 集合関係に関するものです。

内部:(X .INT. Y)

解説: X が Y の内部かどうかをテストします。

位相空間での集合の内部は、すべての開いた部分集合の和集合です。

区間について、X .INT. Y (Y の内部における X) は X が Y の 1 つの部分集合であり、下記の両方の関係が false となることを意味します。

ですが、[empty] .INT. [empty] = true である点に注意してください。

空の集合は開いているので、それ自体の 1 つの部分集合となります。

算術と演算の定義:

引数: X と Y は、同じ KTPV を持つ区間でなければなりません。

結果型: デフォルトの論理スカラーです。

真部分集合: X Y または (X.PSB.Y)

解説: X が Y の真部分集合であるかどうかをテストします。

算術と演算の定義:

引数: X と Y は、同じ KTPV を持つ区間でなければなりません。

結果型: デフォルトの論理スカラーです。

真超集合: X Y、または (X.PSP.Y)

解説: を持つ真超集合を参照してください。

部分集合: X Y、または (X.SB.Y)

解説: X が Y の部分集合であるかどうかをテストします。

算術と演算の定義:



引数: X と Y は、同じ KTPV を持つ区間でなければなりません。

結果型: デフォルトの論理スカラーです。

超集合: X Y、または (X.SP.Y)

解説: を持つ超集合を参照してください。

関係演算子

.qop.で表される組み込みの区間関係演算子は、次の連結により構成されます。

.SEQ. と.SNE. の代わりに、デフォルト演算子の.EQ.(または、==) と.NE. (または、/=) が受け入れられます。コードのあいまいさを取り除くために、他のすべての区間関係演算子は、接頭辞を指定しなければなりません。

すべての区間関係演算子は同じ優先順位を持ちます。算術演算子は関係演算子よりも高い優先順位を持ちます。

区間関係式は 2 つのオペランドが最初に評価され、その後で、2 つの式の値が比較されることにより評価されます。指定された関係を持つ場合は結果が true となり、それ以外は false となります。

最大幅要求式処理が呼び出されると、区間関係演算子の両方の区間オペランド式に適用されます。

「nop」を演算子 op の補数とした場合、「certainly」と「possibly」演算子は次のように関係付けられます。

.Cop. ≡ .NOT.(.Pnop.)
.Pop. ≡ .NOT.(.Cnop.)


注意 - この「certainly」と「possibly」演算子の間の同一性は op ∈ {EQ, NE} であれば無条件に、それ以外の場合は両方のオペランドが空の場合にだけ成り立ちます。逆に、op ∈ {LT, LE, GT, GE} であり、どちらかのオペランドが空である場合は、同一性は成り立ちません。

2 つのオペランドのどちらも空でない場合を前提に、表 2-10 は、次の形式のすべての区間関係演算子の Fortran 演算定義を含んでいます。

[x,x].qop.[y,y]

最初の桁は接頭辞の値を含み、最初の行は演算子接尾辞の値を含んでいます。表に示した条件が満たされると結果は true となります。

表 2-10   区間順位関係の演算定義

LT. LE. EQ. GE. GT. NE.

 
.
S
x < y
and
x < y
x  y
and
x  y
x = y
and
x = y
x  y 
and
x  y
x > y 
and
x > y
x  y
or
x  y

 
.
C

 
x < y

 
x  y
y  x
and
x  y

 
x  y

 
x > y
x > y
or
y > x

 
.
P

 
x < y

 
x  y
x  y
and
y  x

 
x  y

 
x > y
 y > x
or
x > y


コード例 2-7   関係演算子

math% cat ce2-7.f95
INTERVAL :: X = [1.0, 3.0], Y = [2.0, 4.0], Z 
INTEGER  :: V = 4, W = 5
LOGICAL  :: L1, L2, L3, L4
REAL :: R

 
L1 = (X == X) .AND. (Y .SEQ. Y)
L2 = X .SLT. Y

 
! 最大幅要求コード
Z  = W
L3 = W .CEQ. Z
L4 = X-Y .PLT. V-W
IF( L1 .AND. L2 .AND. L3 .AND. L4) PRINT *, 'Check1'

 
! 同等の厳密コード (L3 と L4 への代入用)
L3 = INTERVAL(W, KIND=8) .CEQ. Z
L4 = X-Y  .PLT. INTERVAL(V, KIND=8)-INTERVAL(W, KIND=8)
IF(L3 .AND. L4) PRINT *, 'Check2'
END
math% f95 -xia ce2-7.f95
math% a.out
 Check1
 Check2

コード例 2-7 注記:

集合関係演算子

次のような関係を持つ、2 つの点 x と y 間の「断定的な」順位関係について、

op � {LT, LE, EQ, GE, GT} and

対応する 2 つの空でない区間 X と Y 間の「集合の関係」.Sop.の数学定義は、次のようになります。

x と y の 2 点間の関係 について、対応する 2 つの空でない区間 X と Y 間の「集合の関係」.SNE.は、次のようになります。

空の区間は、後続の各関係の中で明示的に考慮されます。どの場合も次の型規則に従います。

引数: X と Y は、同じ KTPV を持つ区間でなければなりません。

結果型: デフォルトの論理スカラーです。

「Certainly」(断定的な) 関係演算子

「断定的な」関係演算子は、オペランド区間のすべての要素について前提となる関係が true であれば、true となります。たとえば、すべての と について、x < y であれば、[a,b] .CLT. [c,d]は true となります。これは、b < c と同じです。

次のような関係を持つ、2 つの点 x と y 間の「断定的な」順位関係について、

op � {LT, LE, EQ, GE, GT} and

対応する 2 つの区間 X と Y 間の「断定的な」true の関係.Cop.は、次のようになります。

否定的な、「断定的に」等しくない関係を除いて、「断定的な」関係のどちらかのオペランドが空であれば、その結果は false となります。この 1 つの例外である「断定的に」等しくない関係 .CNE. は、この場合に true となります。

それぞれの「断定的な」関係演算子では、次の型規則に従います。

引数: X と Y は、同じ KTPV を持つ区間でなければなりません。

結果型: デフォルトの論理スカラーです。

「Possibly」(可能性のある) 関係演算子

「可能性のある」関係演算子は、オペランド区間の任意の要素が前提となる関係を満たせば、true となります。たとえば、x < y であるような、 と が存在すれば、[a,b] .PLT. [c,d]は true となります。これは、a < d と同じです。

次のような関係を持つ、2 つの点 x と y 間の「肯定的な」順位関係について、

op � {LT, LE, EQ, GE, GT} and

対応する 2 つの区間 X と Y 間の「可能性のある」true の関係 .Pop. は、次のように定義されます。

空の区間が「可能性のある」関係のオペランドであれば、結果は false となります。この 1 つの例外である、否定的な「可能性のある」等しくない関係 .PNE. は、この場合に true となります。

それぞれの「可能性のある」関係演算子では、以下の型規則に従います。

引数: X と Y は、同じ KTPV を持つ区間でなければなりません。

結果型: デフォルトの論理スカラーです。

組み込み区間演算子の拡張

ユーザーの提供する演算子インタフェースブロックの INTERFACE 文の中で指定された演算子が組み込みの区間演算子 (たとえば .IH.) である場合、組み込みの区間演算子の 1 つの拡張が作成されます。

組み込みの区間演算子を拡張するユーザーが提供する演算子関数は、オペランドのデータ型についてその演算子が事前定義されている場合、拡張することができません。

以下のリストのような引数の組み合わせについては、組み込みの区間演算子 +、-、*、/、.IH.、.IX.、** が事前定義されており、ユーザーが拡張することはできません。

(任意の INTERVAL 型、任意の INTERVAL 型)
(任意の INTERVAL 型、任意の REAL または INTEGER 型)
(任意の REAL または INTEGER 型、任意の INTERVAL 型)

整数指数を持つ区間演算子 ** は事前定義されており、次のような引数の組み合わせとしてユーザーが拡張することはできません。

(任意の INTERVAL 型、任意の INTEGER 型)

.IN. を除き、区間関係演算子は以下のリストのような引数の組み合わせとして事前定義されていますから、ユーザーが拡張することはできません。

(任意の INTERVAL 型、任意の INTERVAL 型)
(任意の INTERVAL 型、任意の REAL または INTEGER 型)
(任意の REAL または INTEGER 型、任意の INTERVAL 型)

区間関係演算子 .IN. は事前定義されており、次のような引数の組み合わせとして、ユーザーが拡張することはできません。

(任意の REAL または INTEGER 型、任意の INTERVAL 型)

コード例 2-8 の定義では、.IH.が (LOGICAL, INTERVAL(16)) オペランド用には事前定義されていないので、S1 と S2 インタフェースは正しい記述です。

コード例 2-8   区間の.IH. 演算子の拡張

math% cat ce2-8.f95
MODULE M
INTERFACE OPERATOR (.IH.)
    MODULE PROCEDURE S1
    MODULE PROCEDURE S2
END INTERFACE
CONTAINS
REAL FUNCTION S1(L, Y)
LOGICAL, INTENT(IN)      ::  L 
INTERVAL(16), INTENT(IN) ::  Y
    S1 = 1.0
END FUNCTION S1

INTERVAL FUNCTION S2(R1, R2)
REAL, INTENT(IN) ::  R1 
REAL, INTENT(IN) ::  R2
    S2 = [2.0]
END FUNCTION S2
END MODULE M

PROGRAM TEST
USE M
INTERVAL(16) :: X = [1, 2]
LOGICAL      :: L = .TRUE.
REAL         :: R = 0.1
PRINT *, 'L  .IH. X  = ', L  .IH. X
PRINT *, 'R1 .IH. R2 =', R1 .IH. R2
END PROGRAM TEST
 
math% f95 -xia ce2-8.f95
math% a.out
 L  .IH. X  =  1.0
 R1 .IH. R2 = [2.0,2.0]

コード例 2-9 の + 演算子の拡張は、(INTERVAL, INTERVAL) 型のオペランド用に事前定義されている組み込みの区間 (+) 演算子の定義を変更しようとしているので正しくありません。

コード例 2-9   組み込みの区間の (+) 演算子用法と衝突するユーザー定義のインタフェース

math% cat ce2-9.f95
MODULE M1
INTERFACE OPERATOR (+)
    MODULE PROCEDURE S4
END INTERFACE
CONTAINS
REAL FUNCTION S4(X, Y)
INTERVAL, INTENT(IN) ::  X
INTERVAL, INTENT(IN) ::  Y  
    S4 = 4.0
END FUNCTION S4
END MODULE M1

PROGRAM TEST
USE M1
INTERVAL :: X = [1.0], Y = [2.0]
PRINT *, 'X + Y = ', X + Y
END PROGRAM TEST
 
math% f95 -xia ce2-9.f95

MODULE M1
       ^  
"ce2-9.f95", Line = 1, Column = 8: エラー:コンパイラがモジュール "M" 
でエラーを検出しました。このモジュールにはモジュール情報ファイルは作成されま
せん。

    MODULE PROCEDURE S4
                     ^  
"ce2-9.f95", Line = 3, Column = 22: エラー:この個別引用仕様 "S1" 
は、"ih" の組み込み使用と衝突しています。

USE M1
    ^  
"ce2-9.f95", Line = 14, Column = 5: エラー:モジュール "M" にはコンパ
イラエラーがあるため、USE 文を通してこのモジュールから獲得された宣言は不十分
な可能性があります。

f90: コンパイル時間 0.820000 SECONDS
f90: 最大フィールド長 5518744 10 進ワード
f90: 17 ソース行

コード例 2-10 では、.IH. は (INTERVAL(4), INTERVAL(8)) のオペランド用に事前定義されているので、以下の S1 インタフェースは正しくありません。

コード例 2-10   組み込みの.IH.用法と衝突するユーザー定義のインタフェース

math% cat ce2-10.f95
MODULE M
INTERFACE OPERATOR (.IH.)
    MODULE PROCEDURE S1
END INTERFACE
CONTAINS
INTERVAL FUNCTION S1(X, Y)
INTERVAL(4), INTENT(IN) ::  X
INTERVAL(8), INTENT(IN) ::  Y 
    S1 = [1.0]
END FUNCTION S1
END MODULE M

 
PROGRAM TEST
USE M
INTERVAL(4) :: X = [1.0]
INTERVAL(8) :: Y = [2.0]
PRINT *, 'X .IH. Y = ', X .IH. Y
END PROGRAM TEST
math% f95 -xia ce2-10.f95

 
MODULE M
       ^ 
"ce2-10.f95", Line = 1, Column = 8: エラー:コンパイラがモジュール "M" 
でエラーを検出しました。このモジュールにはモジュール情報ファイルは作成されま
せん。

 
    MODULE PROCEDURE S1
                     ^  
"ce2-10.f95", Line = 3, Column = 22: エラー:この個別引用仕様 "S1" 
は、"ih" の組み込み使用と衝突しています。

 
USE M
    ^ 
"ce2-10.f95", Line = 14, Column = 5:  エラー:モジュール "M" にはコン
パイラエラーがあるため、USE 文を通してこのモジュールから獲得された宣言は不十
分な可能性があります。

 
f90: コンパイル時間 0.190000 SECONDS
f90: 最大フィールド 4135778 10 進ワード
f90: 18 ソース行
f90: 3 個のエラー, 0 個の警告, 0 個の他のメッセージ, 0 個の ANSI

組み込みの区間演算子を拡張する演算子関数の引数の数は、コード例 2-11 で示しているように、組み込みの演算子に必要なオペランド数と一致しなければなりません。

コード例 2-11   事前定義された区間演算子の引数の数の間違った変更

math% cat ce2-11.f95
MODULE M
INTERFACE OPERATOR (.IH.)
    MODULE PROCEDURE S1
END INTERFACE
CONTAINS
REAL FUNCTION S1(R)
REAL, INTENT(IN) :: R 
    S1 = 1.0
END FUNCTION S1
END MODULE M

PROGRAM TEST
USE M
REAL :: R = 0.1
PRINT *, ' .IH. R = ', .IH. R
END PROGRAM TEST
math% f95 -xia ce2-11.f95

MODULE M
       ^ 
"ce2-11.f95", Line = 1, Column = 8: エラー:コンパイラがモジュール "M" 
でエラーを検出しました。このモジュールにはモジュール情報ファイルは作成されま
せん。

    MODULE PROCEDURE S1
                     ^  
"ce2-11.f95", Line = 3, Column = 22: エラー:個別引用仕様 "S1" は利用
者定義 2 項演算子の引用仕様宣言の内部にあるときは、ちょうど 2 個の仮引数をも
たなければなりません。

USE M
    ^ 
"ce2-11.f95", Line = 13, Column = 5: エラー:モジュール "M" にはコンパ
イラエラーがあるため、USE 文を通してこのモジュールから獲得された宣言は不十分
な可能性があります。

PRINT *, ' .IH. R = ', .IH. R
                       ^      
"ce2-11.f95", Line = 15, Column = 24: エラー:予期しない構文: 
"operand" が予期されるところに "." がありました。

f90: コンパイル時間 0.200000 SECONDS
f90: 最大フィールド長 4135778 10 進ワード
f90: 16 ソース行
f90: 4 個のエラー, 0 個の警告, 0 個の他のメッセージ, 0 個の ANSI

組み込みの区間二項演算子は、1 つの INTERVAL 引数をとる単項演算子関数を使用して拡張することはできません。

コード例 2-12 では、「+」は区間オペランド用に定義済みなので、S1 インタフェースは正しくありません。

コード例 2-12   組み込みの単項「+」用法と衝突するユーザー定義のインタフェース

math% cat ce2-12.f95
MODULE M
INTERFACE OPERATOR (+)
    MODULE PROCEDURE S1
END INTERFACE
CONTAINS
REAL FUNCTION S1(X)
    INTERVAL, INTENT(IN) :: X 
    S1 = 1.0
END FUNCTION S1
END MODULE M

PROGRAM TEST
USE M
INTERVAL :: X = 0.1
PRINT *, ' + X = ', + X
END PROGRAM TEST

math% f95 -xia ce2-12.f95

MODULE M
       ^ 
"ce2-12.f95", Line = 1, Column = 8: エラー:コンパイラがモジュール "M" 
でエラーを検出しました。このモジュールにはモジュール情報ファイルは作成されま
せん。

    MODULE PROCEDURE S1
                     ^  
"ce2-12.f95", Line = 3, Column = 22: エラー:この個別引用仕様 "S1" 
は、"+" の組み込み使用と衝突しています。

USE M
    ^ 
"ce2-12.f95", Line = 13, Column = 5: エラー:モジュール "M" にはコンパ
イラエラーがあるため、USE 文を通してこのモジュールから獲得された宣言は不十分
な可能性があります。

f90: コンパイル時間 0.290000 SECONDS
f90: 最大フィールド長 4146432 10 進ワード
f90: 16 ソース行
f90: 3 個のエラー, 0 個の警告, 0 個の他のメッセージ, 0 個の ANSI

一般的なインタフェースブロックの中では、INTERFACE 文の中で指定した一般的な名前が組み込みの区間サブプログラムの名前であれば、特定のユーザー定義サブプログラムは組み込みサブプログラムの定義済みの意味を拡張します。

同じ一般名を持つサブプログラムへのすべての参照は、あいまいであってはなりません。

組み込みのサブプログラムは、そのインタフェース定義もまた一般的なインタフェースブロックで指定された特定の組み込みサブプログラムの 1 つの集まりとして扱われます。

コード例 2-13   組み込み区間関数 WID の正しい拡張

math% cat ce2-13.f95
MODULE M
INTERFACE WID
    MODULE PROCEDURE S1
    MODULE PROCEDURE S2
END INTERFACE
CONTAINS
REAL FUNCTION S1(X)
REAL, INTENT(IN) :: X 
    S1 = 1.0
END FUNCTION S1
INTERVAL FUNCTION S2(X, Y)
INTERVAL, INTENT(IN) :: X 
INTERVAL, INTENT(IN) :: Y 
    S2 = [2.0]
END FUNCTION S2
END MODULE M

PROGRAM TEST
USE M
INTERVAL :: X = [1, 2], Y = [3, 4]
REAL     :: R = 0.1
PRINT *, WID(R)
PRINT *, WID(X, Y)
  
END PROGRAM TEST
math% f95 -xia ce2-13.f95
math% a.out
 1.0
 [2.0,2.0]

コード例 2-14 は正しいコードです。

コード例 2-14   組み込み区間関数 ABS の正しい拡張

math% cat ce2-14.f95
MODULE M
INTERFACE ABS
    MODULE PROCEDURE S1
END INTERFACE
CONTAINS
INTERVAL FUNCTION S1(X)
INTERVAL, INTENT(IN) :: X 
    S1 = [-1.0]
END FUNCTION S1
END MODULE M
PROGRAM TEST
USE M
INTERVAL :: X = [1, 2]
PRINT *, ABS(X)
  
END PROGRAM TEST
math% f95 -xia ce2-14.f95
math% a.out
 [-1.0,-1.0]

コード例 2-15 は正しいコードです。

コード例 2-15   組み込み区間関数 MIN の正しい拡張

math% cat ce2-15.f95
MODULE M
INTERFACE MIN
    MODULE PROCEDURE S1
END INTERFACE
CONTAINS
INTERVAL FUNCTION S1(X, Y)
    INTERVAL(4), INTENT(IN) :: X
    INTERVAL(8), INTENT(IN) :: Y 
    S1 = [-1.0]
END FUNCTION S1
END MODULE M

 
PROGRAM TEST
USE M
INTERVAL(4) :: X = [1, 2]
INTERVAL(8) :: Y = [3, 4]
REAL        :: R = 0.1
PRINT *, MIN(X, Y)
END PROGRAM TEST
math% f95 -xia ce2-15.f95
math% a.out
 [-1.0,-1.0]

最大幅要求の評価を持つ拡張演算子

コード例 2-16 は、組み込みの区間演算子の事前定義バージョンと拡張バージョンを呼び出す場合の、最大幅要求式処理がどのように発生するかを示しています。

コード例 2-16   組み込み区間演算子の事前定義バージョンを呼び出す場合の最大幅要求式の処理

math% cat ce2-16.f95
MODULE M
INTERFACE OPERATOR (.IH.)
    MODULE PROCEDURE S4 
END INTERFACE
CONTAINS 
INTERVAL FUNCTION S4(X, Y) 
    COMPLEX, INTENT(IN) :: X 
    COMPLEX, INTENT(IN) :: Y
    S4 = [0]
END FUNCTION S4
END MODULE M
USE M
INTERVAL :: X = [1.0]
REAL     :: R = 1.0
COMPLEX  :: C = (1.0, 0.0)
X = (R-0.1).IH.(R-0.2)   ! 両方の引数が最大幅要求で、
                         ! 組み込みの区間演算子.IH.が呼び出される。
                         
X = X .IH. (R+R)         ! 両方の引数が最大幅要求で、
                         ! 組み込みの区間演算子.IH.が呼び出される。
                         
X = X .IH. (R+R+X)       ! 第2引数が最大幅要求で、  
                         ! 組み込みの区間演算子.IH.が呼び出される。
                         
X = (R+R) .IH. (R+R+X)   ! 両方の引数が最大幅要求で、
                         ! 組み込みの区間演算子.IH.が呼び出される。
                         
X = C .IH. (C+R)         ! 最大幅要求なしで、s4が呼び出される。
END

 
math% f95 -xia ce2-16.f95
math% a.out

コード例 2-17 は、ユーザー定義の演算子を呼び出す場合に最大幅要求式の処理がどのように発生するか示しています。

コード例 2-17   ユーザー定義演算子を呼び出す場合の最大幅要求式の処理

math% cat ce2-17.f95
MODULE M
INTERFACE OPERATOR (.AA.)
    MODULE PROCEDURE S1
    MODULE PROCEDURE S2
END INTERFACE
CONTAINS 
INTERVAL FUNCTION S1(X, Y)
INTERVAL, INTENT(IN) :: X 
REAL, INTENT(IN)     :: Y
    PRINT *, 'S1 is invoked.'
    S1 = [1.0]
END FUNCTION S1
INTERVAL FUNCTION S2(X, Y)
INTERVAL, INTENT(IN) :: X 
INTERVAL, INTENT(IN) :: Y
    PRINT *, 'S2 is invoked.'
    S2 = [2.0]
END FUNCTION S2
END MODULE M
USE M
INTERVAL :: X = [1.0]
REAL     :: R = 1.0
X = X .AA. R+R     ! S1 is invoked
X = X .AA. X       ! S2 is invoked
END

 
math% f95 -xia ce2-17.f95

    MODULE PROCEDURE S1
                     ^  
"ce2-17.f95", Line = 3, Column = 22: 警告:最大幅要求の評価は、ユーザー
定義の引数に適用されません。

USE M
    ^ 
"ce2-17.f95", Line = 20, Column = 5: 警告:最大幅要求の評価は、ユーザー
定義の引数に適用されません。

f90: コンパイル時間 0.700000 SECONDS
f90: 最大フィールド長 5605590 DECIMAL WORDS
f90: 26 ソース行
f90: 0 個のエラー, 2 個の警告, 0 個の他のメッセージ, 0 個の ANSI
math% a.out
 S1が呼び出されました。
 S2が呼び出されました。

INTERVAL (X [,Y, KIND])

解説: INTERVAL 型へと変換します。

クラス: 要素別処理関数

引数:

X は、INTEGER、REAL、または、INTERVAL 型です。

Y (オプション) は INTEGER または REAL 型です。X が INTERVAL 型であれば、Y は指定してはいけません。

KIND (オプション) はスカラー INTEGER の初期値式です。

結果の特性: INTERVAL

KIND が存在する場合は、結果の KTPV の決定にその値が使われます。それ以外は、結果の KTPV はデフォルトで使われる区間の KTPV と同じです。

包含:

X が区間の場合は包含が保証されます。たとえば、次の場合、

INTERVAL(16):: X

INTERVAL (X, KIND=4) の結果には INTERVAL X が含まれます。

しかし、REAL(8) :: X, Y であれば、INTERVAL(X,Y, KIND=4) の結果は内部的な区間 X .IH. Y を含むとは限りません。この理由は、X と Y が REAL 式でもよく、それらの値は保証されないからです。

INTERVAL 構成子は、必ずしも同じ終了点を持つ INTERVAL 文字定数の値を含むわけではありません。たとえば、INTERVAL(1.1,1.3) は必ずしも外部値 ev([1.1, 1.3]) = [1.1, 1.3] を含むわけではありません。その理由は、REAL 定数の内部値が未知の正確さを持つ近似値であるからです。

常に 2 つの REAL 値を含む区間を構築するためには、コード例 2-18 で示しているように、区間包演算子 .IH. を使います。

結果値: 区間の結果値は 1 つの有効な区間です。

Y が存在せず、X が区間である場合、INTERVAL(X[,KIND]) は X を含む 1 つの区間であり、INTERVAL(X[,KIND]) は左右の終了点 [XL,XU] を持つ 1 つの区間となります。

この場合、

XL = REAL(INF(X) [,KIND]) は丸め切り下げにより、XL .LE. INF(X) となり、

また、

XU = REAL(SUP(X) [,KIND]) は丸め切り上げにより、XU .GE. SUP(X) となります。

X と Y が共に存在する (このため、区間ではない) 場合、INTERVAL(X,Y[,KIND]) は左右の終了点がそれぞれ REAL(X[,KIND]) と REAL(Y[,KIND]) に等しい終了点を持つ区間となります。


注 - このケースでは、有向の丸めは指定されません。このため、包含は提供されません。

以下の 2 つのケースでは [-inf,inf] が返されます。

最大幅要求のスコープ制限

組み込みの 区間構成子関数は以下の 2 つの用途で用いられます。

所与の非区間 (REAL または INTEGER) 式 EXP について、次のコードは、

INTERVAL Y
REAL R
R =
EXP
Y = R

次のコードと同じです。

INTERVAL Y
Y = INTERVAL(
EXP)

これは、次のコードとは異なります。

INTERVAL Y
Y =
EXP

後のコードは、EXP を 1 つの区間式として評価することになります。最初の 2 つの部分コードでは、式 EXP は非区間式として評価され、その結果が縮退区間の構築に使われています。

2 つの引数 EXP1 と EXP2 を使えば、区間(EXP1, EXP2)は両方の式を最大幅要求式処理から隔離し、その式の非区間評価結果と同じ終了点を持つ 1 つの区間を構築します。

KIND パラメータを含めると、結果の KTPV を制御できるようになります。これは多くの場合、明示的な KTPV 変換が必要な -strict 式処理のもとで必要です。

非区間引数を持つ組み込みの区間関数の扱いには注意してください。区間の包含が必要な場合は、コード例 2-18 で示しているように、区間包演算子.IH.を使ってください。

区間構成子は INTERVAL と REAL または INTERGER 式間の境界として動作します。この境界の非 INTERVAL 側では正確性 (このため、さらに包含も) の保証を強制することができません。

コード例 2-18   .IH. 演算子を使用した包含

math% cat ce2-18.f95
REAL(16) :: A, B
INTERVAL :: X1, X2
PRINT *, "Press Control/D to terminate!"
WRITE(*, 1, ADVANCE='NO')
READ(*, *, IOSTAT=IOS) A, B
DO WHILE (IOS >= 0)
    PRINT *, " FOR A =", A, ", AND B =", B
    
    ! 最大幅要求コード
     X1 = A .IH. B                                    
    
    ! 同等の厳密コード
    X2 = INTERVAL(INTERVAL(A, KIND=16) .IH. INTERVAL(B, KIND=16))
    IF (X1 .SEQ. X2)  PRINT *, 'Check.'
    PRINT *, 'X1 = ', X1
    WRITE(*, 1, ADVANCE='NO')
    READ(*, *, IOSTAT=IOS)  A, B
END DO
1  FORMAT(" A, B = ")
END
math% f95 -xia ce2-18.f95
math% a.out
 Control/D to terminate!
 A, B = 1.3 1.7
 FOR A = 1.3 , AND B = 1.7
 X1 =  [1.2999999999999998,1.7000000000000002]
 A, B = 0.0  0.2
 FOR A = 0.0E+0 , AND B = 0.2
 X1 =  [0.0E+0,0.20000000000000002]
 A, B = <Control-D>

組み込みの区間構成子関数の使い方の詳細については、「INTERVAL (X [,Y, KIND])」を参照してください。

組み込みの区間構成子関数の KTPV 個別名

表 2-11 に示しているように、組み込みの区間構成子関数は、オプションの KIND パラメータを使用しない KTPV 個別名を使用して呼び出すことができます。

表 2-11   組み込みの区間構成子関数用の KTPV 個別式
KTPV個別名 結果
DINTERVAL(X[,Y])
INTERVAL(X[,Y], KIND = 8)、または、INTERVAL(X[,Y])
SINTERVAL(X[,Y])
INTERVAL(X[,Y], KIND = 4)
QINTERVAL(X[,Y])
INTERVAL(X[,Y], KIND = 16)


組み込み区間構成子関数の変換例

この節の 3 つの例は、組み込みの区間構築子を使って、REAL から INTERVAL 型データ項目に変換する方法を示しています。コード例 2-19 は、区間構築子のREAL 式引数が REAL 演算を使って評価されるので最大要求幅式の評価から隔離されることを示しています。

コード例 2-19   区間変換

math% cat ce2-19.f95
REAL        :: R = 0.1, S = 0.2, T = 0.3
REAL(8)     :: R8 = 0.1D0, T1, T2
INTERVAL(4) :: X, Y
INTERVAL(8) :: DX, DY
R = 0.1
Y  = INTERVAL(R, R, KIND=4)
X  = INTERVAL(0.1, KIND=4) 	 ! 7行目 
IF ( X == Y ) PRINT *, 'Check1'
X  = INTERVAL(0.1, 0.1, KIND=4) 	 ! 10行目
IF ( X == Y ) PRINT *, 'Check2'
T1 = R+S
T2 = T+R8
DY = INTERVAL(T1, T2)         
DX = INTERVAL(R+S, T+R8) 	 ! 15行目
IF ( DX == DY ) PRINT *, 'Check3'
DX = INTERVAL(Y, KIND=8) 	 ! 17行目
IF (Y .CEQ. INTERVAL(0.1, 0.1, KIND=8)) PRINT *, 'Check4'
END
 
math% f95 -xia ce2-19.f95
math% a.out
 Check1
 Check2
 Check3
 Check4

コード例 2-19 注記:

コード例 2-20 は、区間構成子を使って、Y の終了点が所与の区間、X の要素とならない、可能な最小区間 Y を構築する方法を示しています。

コード例 2-20   所与の実数を含む狭い区間を作成する

math% cat ce2-20.f95
INTERVAL :: X = [10.E-10,11.E+10]
INTERVAL :: Y
Y = INTERVAL(-TINY(INF(X)), TINY(INF(X))) + X
PRINT *, X .INT. Y
END
math% f95 -xia ce2-20
math% a.out
  T

所与の区間 X について、条件 X .INT. Y を満たす鋭い区間 Y が構築されます。内部集合関係に関する情報については、「内部:(X .INT. Y)」を参照してください。

コード例 2-21 は、区間構成子がどのような場合に区間 [-INF,INF] と[MAX_FLOAT,INF] を返すかを示しています。

コード例 2-21   INTERVAL(NaN)

math% cat ce2-21.f95
REAL :: R = 0., S = 0.
T = R/S                        ! 2行目  
PRINT *, T
PRINT *, INTERVAL(T, S)        ! 4行目 
PRINT *, INTERVAL(T, T)        ! 5行目 
PRINT *, INTERVAL(2., 1.)      ! 6行目 
PRINT *, INTERVAL(1./R)        ! 7行目 
END
 
math% f95 -xia ce2-21.f95
math% a.out
 NaN
 [-Inf,Inf]
 [-Inf,Inf]
 [-Inf,Inf]
 [1.7976931348623157E+308,Inf]

コード例 2-21 注記:

組み込みの一般区間関数用の個別名

組み込みの一般区間関数用の f95 個別名は、末尾が組み込み関数の一般名となり、Vで始まり、その後ろに、INTERVAL(4)、INTERVAL(8)、INTERVAL(16) 型の引数用にそれぞれ S、D、または Q が続きます。

f95 では、INTERVAL(16) データ型用には次の個別名組み込み関数だけがサポートされています。

VQABS、VQAINT、VQANINT、VQINF、VQSUP、VQMID、VQMAG、VQMIG、VQISEMPTY

非区間プログラムでの名前空間の衝突を回避するために、コマンド行オプションによる方法でのみ個別名が利用できるようになっています。

より詳細な情報については、「区間のコマンド行オプション」を参照してください。

サポートされるすべての組み込み関数は個別名を持ちます。たとえば、表 2-12 では、ABS 組み込み関数の区間バージョンの名前を一覧表示しています。

表 2-12   組み込みの区間 ABS 関数用の固有の名前
個別名 引数 結果
VSABS INTERVAL(4) INTERVAL(4)
VDABS INTERVAL(8) INTERVAL(8)
VQABS INTERVAL(16) INTERVAL(16)


これ以外の個別名組み込み関数は、「組み込み関数」に一覧表示されています。

INTERVAL

この節では f95 により認識される INTERVAL 文を解説します。ここでは、考えられる制約と例を交えて、各文の構文と解説を示します。

型の宣言

INTERVAL 名前付き定数、変数、関数の結果を宣言するには、INTERVAL 文を使用します。INTERVAL は標準の数値型宣言文と同じ構文と意味論を持つ組み込みの数値型宣言文です。INTERVAL 文を使った用法では、他の数値型宣言用法に存在するのと同じ指定が利用できます。

解説:宣言は、INTERVAL、INTERVAL(4)、INTERVAL(8)、INTERVAL(16)のいずれかにすることができます。

INTERVAL

次のような宣言では、

INTERVAL :: W

変数 W は、デフォルトの 8 の区間 KTPV を持ち、16 バイトの連続するメモリーを占有します。Sun WorkShop 6 の Fortran 95 では、デフォルトの区間 KTPV は、-xtypemap または -r8const のような任意のコマンド行オプションにより変更されることはありません。

INTERVAL は構造型名としては使用できません。たとえば、コード例 2-22 のコードは正しくありません。

コード例 2-22   間違った構造型: INTERVAL

TYPE INTERVAL
	 REAL :: INF, SUP
END TYPE INTERVAL

n {4, 8, 16} 用の INTERVAL(n)

次のような宣言では、

INTERVAL(n) :: W

変数 W は、KTPV = n の KTPV を持ち、2n バイトの連続するメモリーを占有します。

コード例 2-23 は、異なる KTPV を持つ区間変数の宣言を示しています。最大幅要求値と厳密値の整列も示しています。

コード例 2-23   異なる KTPV を持つ区間の宣言

math% cat ce2-23.f95
INTERVAL(4)  :: X1, X2 
INTERVAL(8)  :: Y1, Y2 
INTERVAL(16) :: Z1, Z2
REAL(8)      :: D = 1.2345 

 
! 最大幅要求コード
 X1 = D
 Y1 = D
 Z1 = D

 

 
! 同等の厳密コード
X2 = INTERVAL(INTERVAL(D, KIND=8), KIND=4) 
Y2 = INTERVAL(D, KIND=8)
Z2 = INTERVAL(D, KIND=16)

 
IF (X1 == X2) PRINT *, 'Check1'
IF (Y1 == Y2) PRINT *, 'Check2'
IF (Z1 == Z2) PRINT *, 'Check3'
END 
 
math% f95 -xia ce2-23.f95
math% a.out
 Check1
 Check2
 Check3

コード例 2-24 は、区間変数の宣言と初期化について示しています。区間定数を別の方法で表現するには、「区間定数」を参照してください。

コード例 2-24   区間変数の宣言と初期化

math% cat ce2-24.f95
INTERVAL :: U = [1, 9.1_8], V = [4.1]

 
! 最大幅要求コード
INTERVAL :: W1 = 0.1_16

 
! 同等の厳密コード
INTERVAL :: W2 = [0.1_16]

 
PRINT *, U, V
IF (W1 .SEQ. W2) PRINT *, 'Check'
END 
 
math% f95 -xia ce2-24.f95
math% a.out
 [1.0,9.1000000000000015] [4.0999999999999996,4.1000000000000006]
 検証

任意の初期化を伴う宣言文の中では、データ式の型が記号名の型と一致しない場合、型変換が実行されます。

コード例 2-25   区間配列の宣言

INTERVAL(4) :: R(5), S(5) 
INTERVAL :: U(5), V(5) 
INTERVAL(16) :: X(5), Y(5) 

DATA 文

構文

区間変数を含む DATA 文の構文は、区間変数が区間定数を用いて初期化される点を除けば、他の数値データ型のものと同じです。

コード例 2-26   区間変数を含む DATA 文

INTERVAL X
DATA X/[1,2]/

EQUIVALENCE 文

任意の区間変数または配列は、次の制限付きで EQUIVALENCE 文の中に現れてもかまいません。つまり、結合対応が区間変数または配列を含む場合、結合対応内部のすべてのオブジェクトは、コード例 2-18 で示しているように、同じ型を持たなければなりません。これは区間固有の制約ではなく、Fortran 規格の制約です。

FORMAT 文

構文

区間用の反復可能な編集記述子は次のとおりです。

D ∈ {E, EN, ES, G}

である場合、

Fw.d、VFw.d、Dw.d、VDw.d、Dw.dEe、VDw.dEe、Yw.d、Yw.dEe
w と e は、非ゼロの符号なし整数定数を、d は符号なし整数定数を表します。

編集記述子を使って区間データを処理するための記述子の指定方法については、「入力と出力」を参照してください。また、非区間データを用いた標準編集記述子の動作については、Fortran のリファレンスマニュアルを参照してください。

すべての標準 Fortran の編集記述子は区間を受け入れます。区間専用バージョンの標準 E、F、G の編集記述子には接頭辞として V を付けることができます。

コード例 2-27 で示しているように、区間データを読み込みまたは書き出しする場合、反復不能の編集記述子を変更する必要はありません。

コード例 2-27   反復不能の編集記述子の例

math% cat ce2-27.f95
INTERVAL :: X = [-1.3, 1.3]
WRITE(*, '(SP, VF20.5)') X
WRITE(*, '(SS, VF20.5)') X
END
math% f95 -xia ce2-27.f95
math% a.out
 [-1.30001,+1.30001]
 [-1.30001, 1.30001]

解説

反復可能編集記述子

反復可能な編集記述子、E、F、EN、ES、G、VE、VEN、VES、VF、VG、Y は、区間データの編集方法を指定します。

コード例 2-28 は、区間固有の編集記述子の例を含んでいます。

コード例 2-28   区間固有の編集記述子を使った FORMAT 文

FORMAT(VE22.4E4) 
FORMAT(VEN22.4) 
FORMAT(VES25.5) 
FORMAT(VF25.5) 
FORMAT(VG25.5) 
FORMAT(VG22.4E4) 
FORMAT(Y25.5) 

追加的な例については、「入力と出力」を参照してください。

FUNCTION (外部)

コード例 2-29 で示しているように、区間外部関数と非区間外部関数との間には、関数と引数の定義の中で INTERVAL 型 (INTERVAL、INTERVAL(4)、INTERVAL(8)、または、INTERVAL(16)) を使用する点を除けば、他に違いはありません。

コード例 2-29   デフォルトの区間関数

INTERVAL FUNCTION SQR (A)                    ! 1行目
INTERVAL :: A 
SQR = A**2 
RETURN 
END 

1 行目のデフォルトの INTERVAL は、コード例 2-30 で示しているように、明示的な表現にすることができます。

コード例 2-30   明示的な INTERVAL(16) 関数宣言

INTERVAL(16) FUNCTION SQR (A)                ! 1行目

IMPLICIT 属性

区間名のデフォルト型を指定するには、IMPLICIT 属性を使用してください。

IMPLICIT INTERVAL (8) (V)

INTRINSIC 文

実際の引数として引き渡せるようにするために組み込みの関数を宣言するには、INTRINSIC 文を使用してください。

コード例 2-31    組み込みの関数宣言

INTRINSIC VDSIN, VDCOS, VQSIN
X = CALC(VDSIN, VDCOS, VQSIN) 


注 - INTRINSIC 文では、一般関数の個別名が使用され、実際の引数として引き渡されなければなりません。「組み込みの一般区間関数用の個別名」と「組み込み関数」を参照してください。

次の組み込みの区間関数は、一般関数ですから、実際の引数として引き渡すことはできません。

NDIGITS、INTERVAL

NAMELIST 文

NAMELIST 文は区間をサポートします。

コード例 2-32   NAMELIST での INTERVAL

CHARACTER(8) :: NAME 
CHARACTER(4) :: COLOR 
INTEGER      :: AGE 
INTERVAL(4)  :: HEIGHT 
INTERVAL(4)  :: WEIGHT 
NAMELIST /DOG/ NAME, COLOR, AGE, WEIGHT, HEIGHT 

PARAMETER 属性

PARAMETER 属性は、区間の初期化結果を名前付き定数 (PARAMETER) に代入するのに使用します。

構文

PARAMETER (p = e [, p = expr]...)

p 区間英字名
expr 区間定数式
= e の値を記号名 p に代入する
解説

記号名 p と定数式 expr は共に INTERVAL 型を持たなければなりません。

定数式では、整数の累乗に対する累乗法は許されます。

最大幅要求式処理のもとでは、区間の名前付き定数定義の中で、混合モードの区間式の評価がサポートされます。定数式の型が名前付き定数の型と一致しない場合は、最大幅要求式処理のもとで型変換が実行されます。


注意 - f95 では、非区間定数式は後続の混合モード区間式の中での使用を考慮せずにコンパイル時に評価されます。これらの式は最大幅要求式処理のスコープ外にあります。このため、非区間の名前付き定数の値の設定に用いられる点式の値を含むための要件は存在しません。混合モードの区間式の中で非区間の名前付き定数が現れる度に、ユーザーが気付くようコンパイル時の警告メッセージが出力されます。Fortran 規格で定義された名前付き定数はより適切には、読み取り専用変数と呼ばれます。読み取り専用変数に関連付けられた外部値は存在しません。

標準 Fortran 95 では、名前付き定数は、区間定数の最大下限と最小上限の表現には使用できません。この制約がこのリリースで強制されないのは、既知のエラーです。

コード例 2-33   非区間の PARAMETER 属性での定数式

math% cat ce2-33.f95
REAL(4), PARAMETER      :: R   = 0.1
INTERVAL(4), PARAMETER  :: I4  = 0.1
INTERVAL(16), PARAMETER :: I16 = 0.1
INTERVAL                :: XR, XI
XR = R4
XI = I4
IF ((.NOT.(XR.SP.I16)).AND. (XI.SP.I16)) PRINT *, 'Check'
END
math% f95 -xia ce2-33.f95
math% a.out
 検証


注 - XR は、1/10 を含みませんが、XI の場合は含みます。

Fortran 95 形式の POINTER

ポインタを使用して区間にアクセスすることができます。

コード例 2-34   区間ポインタ

INTERVAL, POINTER :: PX
INTERVAL :: X
X => P

文関数

パラメータ付き区間式の宣言と評価には文関数を使用することができます。その場合、非区間文関数の制約が適用されます。

コード例 2-35   区間文関数

math% cat ce2-35.f95
INTERVAL :: X, F
F(X) = SIN(X)**2 + COS(X)**2
IF(1 .IN. F([0.5])) PRINT *, 'Check'
END 
math% f95 -xia ce2-35.f95
math% a.out
 Check

型宣言文

型宣言文は、変数並びの中の変数のデータ型を指定します。オプションとして、型宣言文は配列の次元を指定し、値を使用して初期化します。

構文

構文は、型が INTERVAL、INTERVAL(4)、INTERVAL(8)、INTERVAL(16)のINTERVAL 型指定子のいずれかである点を除けば、非区間の数値データ型の場合と同じです。

解説

型宣言文の特性は、INTERVAL 型についても、他の数値データ型の場合と同じです。

制約

非 INTERVAL の数値型の場合と同じです。

コード例 2-36   INTERVAL の型宣言文

INTERVAL     :: I, J = [0.0] 
INTERVAL(16) :: K = [0.1, 0.2_16] 
INTERVAL(16) :: L = [0.1] 

例の注記:

WRITE 文

WRITE 文は、非 INTERVAL 型の変数が処理されるのと同じ方法で、区間変数を受け入れて入力/出力の並びを処理します。定義済みの区間編集記述子を使えば、区間データの書式化記述を行うことができます。変数群要素並びの WRITE 文は区間をサポートします。

READ 文

READ 文は、非 INTERVAL 型の変数が処理されるのと同じ方法で、区間変数を受け入れて入力/出力の並びを処理します。

入力と出力

区間入力/出力を実行するプロセスは他の非区間データ型の場合と同じです。

外部表現

x が、並びによる、または、書式化された入力/出力を用いて読み書きできる外部 (小数) 数であるものとします。内部的な近似値と外部値との区別に関しては、「Fortran 拡張」以下の各節を参照してください。このような数は外部区間または終了点のいずれかの表現に使えます。外部区間には、次に示す 3 つの表示可能な形式があります。

正または負の不定区間終了点は、マイナスまたはオプションのプラス記号の接頭辞を持つ大文字と小文字を区別しない文字列 INF または INFINITY としての入力/出力です。

空の区間は、角括弧 [...] で囲まれた大文字と小文字を区別しない文字列 EMPTY としての入力/出力です。文字列 EMPTY は、その前後を空白とすることができます。

コード例 1-6 を使えば、拡張区間を試すことができます。

さらに詳細については、「算術演算子 +、-、*、/」を参照してください。

入力

入力時点では、任意の外部区間 X またはその構成要素である X_inf と X_sup を、Dw.d 編集記述子が受け入れる任意の方法で書式化することができます。そこで、input-field、input-field1、input-field2 が、それぞれ、Dw'.d、Dw1.d、Dw2.d 編集記述子用の有効な入力フィールドであるものとします。

w は区間入力フィールドの幅であるものとします。入力時に、w はゼロより大きくなければいけません。すべての区間編集記述子は、以下の 3 つの形式のどれか 1 つの形式で区間データの入力を受け入れます。

最初の形式 (角括弧で囲まれ、コンマで区切られた 2 つの数) は、馴染みのある [inf, sup] 表現です。

2 番目の形式 (角括弧で囲まれた単一の数) は点、または縮退した区間を表します。

3 番目の形式 (角括弧なし) は区間の単数形式であり、ここでは区間幅の決定に最終表示桁が用いられます。「Y 編集記述子を用いた単数編集」を参照してください。さらに詳細な情報については、M.Schulte、V.Zelov、G.W.Walster、D.Chiriaev 著、「Single-Number Interval I/O」、『Developments in Reliable Computing』、T. Schulte他 (Kluwer 1999年) を参照してください。

最大下限が内部的に表現できない場合は、同じものよりも小さいことがわかっている内部的な近似値へと丸め切り下げが行われます。最小下限が内部的に表現できない場合は、入力値と同じものよりも大きいことがわかっている内部的な近似値へと丸め切り上げが行われます。縮退した区間が内部的に表現できない場合は、丸め切り下げまたは丸め切り上げにより、入力値と同じものを含むことがわかっている内部的なINTERVAL 近似値が形成されます。

並びによる入力

入力の並び項目が区間である場合、入力記録内部の対応する要素は外部の区間またはヌル値でなければなりません。

外部の区間値は、区間、REAL または INTEGER 文字定数と同じ形式を持つことができます。区間の値が角括弧 [...] で囲まれない REAL または INTEGER 文字定数の形式を持つ場合、外部の区間は単数区間表現 ([x] + [-1,1]uld −最終桁での単位) を使って翻訳されます。

[inf, sup] 入力形式を使う場合は、最大下限 (infimum) とカンマの間、または、カンマと最小上限 (supremum) の間で記録終了が発生する可能性があります。

2 つの連続するコンマにより指定されたヌル値は、対応する区間の並び項目が変更されないことを意味します。


注 - 区間の最大下限または最小上限用にヌル値を使用してはいけません。

コード例 2-37   並び入力/出力コード

math% cat ce2-37.f95
INTERVAL, DIMENSION(6) :: X
INTEGER I
DO I = LBOUND(X, 1), UBOUND(X, 1)
    READ(*, *) X(I) 
    WRITE(*, *) X(I) 
END DO
END 
math% f95 -xia ce2-37.f95
math% a.out
1.234500
 [1.2344989999999997,1.2345010000000001]
[1.2345]
 [1.2344999999999999,1.2345000000000002]
[-inf,2]
 [-Inf,2.0]
[-inf]
 [-Inf,-1.7976931348623157E+308]
[EMPTY]
 [EMPTY]
[1.2345,1.23456]
 [1.2344999999999999,1.2345600000000002]

書式付き入力/出力

次に、区間編集記述子を示します。

区間編集記述子は以下のような指定を行います。

w と d パラメータは必ず使用しなければなりません。Ee は、オプションです。

w と d 指定子は必ず存在しなければならず、以下の制約に従わなければなりません。

入力動作

書式付き区間入力の入力動作は、すべての場合で格納された内部的な近似値が入力文字列で表される外部値を含むという点を除けば、他の数値データ型の場合と同じです。このため、包含では、区間終了点の丸めが必要になることがあります。任意の入力区間文字を input_string、これに対応する外部値 ev を (input_string)、入力変換後の結果としての内部的な近似値を X とすると、次のようになります。

ev(input_string) ⊆ X

入力過程では、すべての区間編集記述子は同じ意味論を持ちます。パラメータ w の値は、外部の区間を含むフィールド幅であり、e の値は無視されます。

出力動作

書式付き区間出力の出力動作は、すべての場合で出力文字列の算術値が出力並びの内部的なデータ項目算術値を含まなければならない点を除けば、他のデータ型の場合と同じです。このため、包含では区間終了点の丸めが必要になることもあります。任意の内部的な区間 X が与えられると、これに対応する出力文字 output_string と外部値 ev(output_string) は、次に関連付けられます。

X ev(output_string)

出力過程では、異なる編集記述子を用いると、区間出力並び項目の区間値が異なる形式を使用して表示されるようになります。しかし、包含の制約は次のことを要求します。

ev(input_string) X ev(output_string)

書式付き入力

「書式付き入力/出力」に掲載したすべての区間編集記述子について、書式化出力の動作は同じです。「入力」で解説しているすべての入力が受け入れられます。

入力フィールドが小数点を含む場合、d の値は無視されます。入力フィールドで小数点が省略されている場合、d は入力値の小数点の位置を表します。つまり、入力値は整数として読み取られて、10(-d) が乗ぜられます。

コード例 2-38   入力値の小数点は書式指定子に優先する

math% cat ce2-38.f95
INTERVAL :: X, Y
READ(*, '(F10.4)') X
READ(*, '(F10.4)') Y
WRITE(*, *)'1234567890123456789012345678901234567890-position'
WRITE(*, '(1X, E19.6)') X
WRITE(*, '(1X, E19.6)') Y
END
math% f95 -xia ce2-38.f95
math% a.out
[.1234]
[1234]
 1234567890123456789012345678901234567890-position
      0.123400E+000 
      0.123400E+000 

コード例 2-39   区間のすべての編集記述子は単数の入力を受け入れる

math% cat ce2-39.f95
INTERVAL, DIMENSION(9) :: X
INTEGER                :: I
READ(*, '(Y25.3)')   X(1)
READ(*, '(E25.3)')   X(2)
READ(*, '(F25.3)')   X(3) 
READ(*, '(G25.3) ')  X(4) 
READ(*, '(VE25.3)')  X(5) 
READ(*, '(VEN25.3)') X(6) 
READ(*, '(VES25.3)') X(7) 
READ(*, '(VF25.3)')  X(8) 
READ(*, '(VG25.3)')  X(9)
DO I = LBOUND(X, 1), UBOUND(X, 1) 
    PRINT *, X(I)
END DO
END 
%math f95 -xia ce2-39.f95
%math a.out
1.23    
1.23
1.23
1.23
1.23
1.23
1.23
1.23
1.23
 [1.2199999999999999,1.2400000000000003]
 [1.2199999999999999,1.2400000000000003]
 [1.2199999999999999,1.2400000000000003]
 [1.2199999999999999,1.2400000000000003]
 [1.2199999999999999,1.2400000000000003]
 [1.2199999999999999,1.2400000000000003]
 [1.2199999999999999,1.2400000000000003]
 [1.2199999999999999,1.2400000000000003]
 [1.2199999999999999,1.2400000000000003]

空白の編集 (BZ)

後続のゼロは単数の区間入力では意味を持つので、区間リスト項目の入力のために空白を処理すると、BZ 制御編集記述子は無視されます。

コード例 2-40   BZ 記述子

math% cat ce2-40.f95
INTERVAL :: X
REAL(4)  :: R
READ(*, '(BZ, F40.6 )') X
READ(*, '(BZ, F40.6 )') R
WRITE(*, '(VF40.3)')    X
WRITE(*, '(F40.3)')     R
END
math% f95 -xia ce2-40.f95
math% a.out
[.9998   ]
    .9998
 [             0.999,             1.000]
                                   1.000

桁移動数 (P)

Y、VE、VEN、VES、VF、VG 記述子用の桁移動数と、区間に適用された場合の F、E、EN、ES、G 編集記述子用の桁移動数は P 編集記述子で変更できます。P 編集記述子は、区間の終了点を REAL 値の場合と同様の方法で桁移動します。

書式付き出力

区間に適用された、F、E、G 編集記述子は、F または G 編集記述子が用いられると出力フィールドが F 編集記述子を使用して書式化されるようになるという点を除けば、Y 編集記述子と同じ意味を持ちます。E 編集記述子が使用される場合は、出力フィールドは E 編集記述子により記述された形式を常に持つようになります。

書式付き区間出力は次のような特性を持ちます。

表 2-13 は、出力に関する指数フィールド、e のデフォルト値を示しています。

表 2-13   出力編集記述子の指数フィールドデフォルト値
編集記述子 INTERVAL(4) INTERVAL(8) INTERVAL(16)
Y, E, EN, ES, G 
3 3 3
VE, VEN, VES, VG 
2 2 3


Y 編集記述子を用いた単数編集

Y 編集記述子は単数形式での拡張区間値を書式化します。

外部区間値が縮退していない場合、出力形式は REAL または INTEGER の文字定数 (角括弧 [...] で囲まない X ) の場合と同じです。外部値は縮退していない算術区間
[x] + [-1,1]uld に翻訳されます。

Y 編集記述子の一般形式は次のとおりです。

Yw.dEe

d 指定子は、有効桁の表示用に割り当てられた場所の数を設定します。しかし、実際に表示される桁数は、w の値と外部区間の幅に依存して、d より多いことも、少ないこともあります。

e 指定子 (存在すれば) は、指数用に確保された出力下位フィールドの場所の数を定義します。

e 指定子が存在すると、出力フィールドは (F 編集記述子とは反対に) E 編集記述子により記述された形式を持つようになります。

単数区間表現は、[inf, sup] 表現よりも正確性に劣ることがしばしばあります。これは、特に区間または区間の単数表現がゼロまたは無限大を含んでいる場合にあてはまります。

たとえば、[-15, +75] の単数表現の外部値は、ev([0E2]) = [-100, +100]です。[1, ∞] の単数表現の外部値は、ev([0E+inf]) = です。

これらの場合、内部的な近似値のより狭い外部表現を生成するために、w 文字の入力フィールド内部の最大表示可能な有効桁数を表示する d' ≧ 1と共に、VGw.d'Ee 編集記述子が使われます。

コード例 2-41   Y [inf, sup] 形式の出力

math% cat ce2-41.f95
INTERVAL :: X = [-1, 10]
INTERVAL :: Y = [1, 6]
WRITE(*, '(Y20.5)') X 
WRITE(*, '(Y20.5)') Y 
END
math% f95 -xia ce2-41.f95
math% a.out
 [-1.     ,0.1E+002]
 [1.0     ,6.0     ]

w 文字出力フィールド内部の縮退した区間の表示が可能であれば、単数の出力文字列は通常の角括弧 [...] で囲まれ、結果が点であること示します。

十分なフィールド幅があれば、より大きい有効桁数を表示できるかどうかに応じて、E または F 編集記述子が使用されます。E と F 編集記述子を使用した表示桁数が同じであれば、F 編集記述子が使用されることになります。

コード例 2-42   Yw.d 出力

cat math% cat ce2-42.f95
WRITE(*, *) '1234567890123456789012345678901234567890-position'   
WRITE(*, '(1x, F20.6)') [1.2345678, 1.23456789]
WRITE(*, '(1x, F20.6)') [1.234567, 1.2345678]
WRITE(*, '(1x, F20.6)') [1.23456, 1.234567]
WRITE(*, '(1x, F20.6)') [1.2345, 1.23456]
WRITE(*, '(1x, F20.6)') [1.5111, 1.5112]
WRITE(*, '(1x, F20.6)') [1.511, 1.512]
WRITE(*, '(1x, F20.6)') [1.51, 1.52]
WRITE(*, '(1x, F20.6)') [1.5, 1.5]
END
math% f95 -xia ce2-42.f95
math% a.out
 1234567890123456789012345678901234567890-position
       1.2345679     
       1.234567      
       1.23456       
       1.2345        
       1.511         
       1.51          
       1.5           
 [     1.50000000000]

区間幅が増えると、単数表現で表示される桁数は減少します。区間が縮退していると、残りのすべての位置がゼロで埋められ、縮退した区間の値が正確に表される場合は角括弧が追加されます。

組み込みの関数 NDIGITS (表 2-21 を参照してください) は、単数形式を使った区間変数または配列の書き出しに必要な最大上位桁数を返します。

コード例 2-43   NDIGITS 組み込み関数を使用した Yw.d 出力

math% cat ce2-43.f95
INTEGER :: I, ND, T, D, DIM
PARAMETER(D=5)      ! デフォルトの桁数
PARAMETER(DIM=8)
INTERVAL, DIMENSION(DIM) :: X
CHARACTER(20) :: FMT
X = (/ [1.2345678, 1.23456789], &
  [1.234567, 1.2345678], &
  [1.23456, 1.234567], &
  [1.2345, 1.23456], &
  [1.5111, 1.5112], &
  [1.511, 1.512], &
  [1.51, 1.52], &
  [1.5]/)
ND=0
DO I=1, DIM
    T = NDIGITS(X(I))
    IF(T == EPHUGE(T)) THEN ! 区間は縮退している
        ND = MAX(ND, D)
    ELSE   
        ND = MAX( ND, T )
    ENDIF   
END DO
 
WRITE(FMT, '(A2, I2, A1, I1, A1)') '(E', 10+ND, '.', ND, ')'

DO I=1, DIM
    WRITE(*, FMT) X(I) 
END DO
END
math% f95 -xia ce2-43.f95
math% a.out
  0.12345679E+001 
  0.1234567 E+001 
  0.123456  E+001 
  0.12345   E+001 
  0.1511    E+001 
  0.151     E+001 
  0.15      E+001 
[ 0.15000000E+001]

読みやすくするため、小数点は常に出力フィールドの右側から数えて、p = e + d + 4の位置に配置されます。

コード例 2-44   {Y, F, E, G}w.d 出力では、d は上位桁の最小値を表示設定する

math% cat ce2-44.f95
INTERVAL :: X = [1.2345678, 1.23456789] 
INTERVAL :: Y = [1.5] 
WRITE(*, *) '1234567890123456789012345678901234567890-position'   
WRITE(*, '(1X, F20.5)') X  
WRITE(*, '(1X, F20.5)') Y 
WRITE(*, '(1X, 1E20.5)') X 
WRITE(*, '(1X, 1E20.5)') Y 
WRITE(*, '(1X, G20.5)') X 
WRITE(*, '(1X, G20.5)') Y 
WRITE(*, '(1X, Y20.5)') X 
WRITE(*, '(1X, Y20.5)') Y 
END 
math% f95 -xia ce2-44.f95
math% a.out
 1234567890123456789012345678901234567890-position
        1.2345679    
 [      1.5000000000]
        0.12345E+001 
 [      0.15000E+001]
        1.2345679    
 [      1.5000000000]
        1.2345679    
 [      1.5000000000]

指数部の数字の数は、オプションの e 指定子で指定します。指数部の数が指定される場合、w は少なくとも、d + e + 7 でなければなりません。

コード例 2-45   Yw.dEe 出力 (e 指定子の用法)

math% cat ce2-45.f95
INTERVAL :: X = [1.2345, 1.2346] 
INTERVAL :: Y = [3.4567, 3.4568] 
INTERVAL :: Z = [1.5] 
WRITE(*, *) '1234567890123456789012345678901234567890-position'   
WRITE(*, '(1X, Y19.5E4)') X 
WRITE(*, '(1X, Y19.5E4)') Y 
WRITE(*, '(1X, Y19.5E4)') Z 
WRITE(*, '(1X, Y19.5E3)') X 
WRITE(*, '(1X, Y19.5E3)') Y 
WRITE(*, '(1X, Y19.5E3)') Z 
END 
math% f95 -xia ce2-45.f95
math% a.out
 1234567890123456789012345678901234567890-position
      0.1234 E+0001 
      0.3456 E+0001 
 [    0.15000E+0001]
       0.1234 E+001 
       0.3456 E+001 
 [     0.15000E+001]

E 編集記述子

E 編集記述子は、Y 編集記述子の単数 E 形式を使用して、区間データ項目を書式化します。

一般形式は次のとおりです。

Ew.dEe
コード例 2-46   Ew.dEe 編集記述子

math% cat ce2-46.f95
INTERVAL :: X = [1.2345678, 1.23456789] 
INTERVAL :: Y = [1.5]
WRITE(*, *) '1234567890123456789012345678901234567890-position'   
WRITE(*, '(1X, E20.5)')   X 
WRITE(*, '(1X, E20.5E3)') X 
WRITE(*, '(1X, E20.5E3)') Y 
WRITE(*, '(1X, E20.5E4)') X 
WRITE(*, '(1X, E20.5E2)') X 
END 
math% f95 -xia ce2-46.f95
math% a.out
 1234567890123456789012345678901234567890-position
        0.12345E+001 
        0.12345E+001 
 [      0.15000E+001]
       0.12345E+0001 
         0.12345E+01 

F 編集記述子

F 編集記述子は、区間の Y 編集記述子の F 形式だけを使って、区間データ項目を書式化します。この一般形式は次のとおりです。

Fw.d

F 記述子を使うと、d を指定する場合よりも上位の桁を表示できるようになります。表示されない桁に対応する位置は空白で埋められます。

コード例 2-47   Fw.d 編集記述子

math% cat ce2-47.f95
INTERVAL :: X = [1.2345678, 1.23456789] 
INTERVAL :: Y = [2.0] 
WRITE(*, *) '1234567890123456789012345678901234567890-position'   
WRITE(*, '(1X, F20.4)') X 
WRITE(*, '(1X, E20.4)') X 
WRITE(*, '(1X, F20.4)') Y 
WRITE(*, '(1X, E20.4)') Y 
END
math% f95 -xia ce2-47.f95
math% a.out
 1234567890123456789012345678901234567890-position
         1.2345679   
         0.1234E+001 
 [       2.000000000]
 [       0.2000E+001]

G 編集記述子

G 編集記述子は、単数 E または Y 編集記述子の F 形式を使って、区間データ項目を書式化します。この一般形式は次のとおりです。

Gw.dEe
コード例 2-48   Gw.dEe 編集記述子

math% cat ce2-48.f95
INTERVAL :: X = [1.2345678, 1.23456789] 
WRITE(*, *) '1234567890123456789012345678901234567890-position'   
WRITE(*, '(1X, G20.4)')   X 
WRITE(*, '(1X, G20.4E3)') X 
END 
math% f95 -xia ce2-48.f95
math% a.out
 1234567890123456789012345678901234567890-position
         1.2345679   
         0.1234E+001


注 - F 記述子に従って区間の終了点が出力できない場合、G 編集記述子は E 記述子を使用します。

VE 編集記述子

VE 編集記述子の一般形式は次のとおりです。

VEw.dEe

Xd が、Ew'.d 編集記述子を使用した有効な外部値であるものとします。VE 編集記述子は、区間データ項目を次の形式で出力します。

[X_inf,X_sup]、ただし、w' = (w-3)/2

外部値 X_inf と X_sup は、それぞれ、区間出力並び項目の最大下限と最小上限に関する下限と上限です。

コード例 2-49   VE の出力

math% cat ce2-49.f95
INTERVAL :: X = [1.2345Q45, 1.2346Q45] 
WRITE(*, *) '1234567890123456789012345678901234567890-position'
WRITE(*, '(1X, VE25.3)')   X
WRITE(*, '(1X, VE33.4E4)') X
END
math% f95 -xia ce2-49.f95
math% a.out
 1234567890123456789012345678901234567890-position
 [ 0.123E+046, 0.124E+046]
 [   0.1234E+0046,   0.1235E+0046]

VEN 編集記述子

VEN 編集記述子の一般形式は次のとおりです。

VENw.dEe

X_inf と X_sup が、ENw'.d 編集記述子を使って表示される有効な外部値であるものとします。VEN 編集記述子は、区間データ項目を次の形式で出力します。

[X_inf,X_sup]、ただし、w' = (w-3)/2

外部値 X_inf と X_sup は、それぞれ、区間出力並び項目の最大下限と最小上限です。

コード例 2-50   VEN の出力

math% cat ce2-50.f95
INTERVAL :: X = [1024.82] 
WRITE(*, *) '1234567890123456789012345678901234567890-position'
WRITE(*, '(1X, VEN25.3)') X
WRITE(*, '(1X, VEN33.4E4)') X
END
math% f95 -xia ce2-50.f95
math% a.out
 1234567890123456789012345678901234567890-position
 [ 1.024E+003, 1.025E+003]
 [   1.0248E+0003,   1.0249E+0003]

VES 編集記述子

VES 編集記述子の一般形式は次のとおりです。

VESw.dEe

X_inf と X_supが、ESw'.d 編集記述子を使用した有効な外部値であるものとします。VES 編集記述子は、区間データ項目を次の形式で出力します。

[X_inf,X_sup]、ただし、w' = (w-3)/2

外部値 X_inf と X_sup は、それぞれ、区間出力並び項目の最大下限と最小上限です。

コード例 2-51   VES の出力

math% cat ce2-51.f95
INTERVAL :: X = [21.234] 
WRITE(*, *) '1234567890123456789012345678901234567890-position'
WRITE(*, '(1X, VES25.3)')   X
WRITE(*, '(1X, VES33.4E4)') X
END
math% f95 -xia ce2-51.f95
math% a.out
 1234567890123456789012345678901234567890-position
 [ 2.123E+001, 2.124E+001]
 [   2.1233E+0001,   2.1235E+0001]

VF 編集記述子

X_inf と X_supが、Fw'.d 編集記述子を使用して表示される有効な外部値であるものとします。VF 編集記述子は、区間データ項目を次の形式で出力します。

[X_inf,X_sup]、ただし、w' = (w-3)/2

外部値 X_inf と X_sup は、それぞれ、区間出力並び項目の最大下限と最小上限です。

コード例 2-52   VF 出力編集

math% cat ce2-52.f95
INTERVAL :: X = [1.2345, 1.2346], Y = [1.2345E11, 1.2346E11] 
WRITE(*, *) '1234567890123456789012345678901234567890-position'
WRITE(*, '(1X, VF25.3)') X
WRITE(*, '(1X, VF25.3)') Y
END
math% f95 -xia ce2-52.f95
math% a.out
 1234567890123456789012345678901234567890-position
 [      1.234,      1.235]
 [***********,***********]


注 - 書式付き文に従って区間が出力できない場合は、アスタリスク (「*」) が表示されます。

VG 編集記述子

区間の出力では、G 編集記述子が区間の終了点出力の書式化に使われる点を除けば、VG 編集は VE 編集または VF 編集と同じです。

コード例 2-53   VG の出力

math% cat ce2-53.f95
INTERVAL :: X = [1.2345, 1.2346], Y = [1.2345E11, 1.2346E11] 
WRITE(*, *) '1234567890123456789012345678901234567890-position'
WRITE(*, '(1X, VG25.3)') X
WRITE(*, '(1X, VG25.3)') Y
END 
math% f95 -xia ce2-53.f95
math% a.out
 1234567890123456789012345678901234567890-position
 [  1.23     ,  1.24     ]
 [ 0.123E+012, 0.124E+012]


注 - F 記述子に従って区間の終了点が出力できない場合、VG 編集記述子は E 記述子を使用します。

書式なし入力/出力

書式なし入力/出力は、データの内部的な表現を変更せずに、メモリー位置との間でデータの転送に用います。区間を使う場合には、入力/出力に関する外側の丸めが回避できるので、書式なし入力/出力は特に重要です。


注 - 書式なし入力/出力は書式なし区間データの読み書きのためだけに使ってください。将来のリリースとのバイナリファイルの互換性は保証されません。
書式なし入力/出力は区間データ項目が透明であるという事実に依存しています。

並びによる出力

左右の終了点用の REAL 定数は、F または E 編集記述子を使用して生成されます。|x|が、出力区間終了点の絶対値であるものとします。すると、

であれば、0PFw.d 編集記述子を使用して終了点が生成されます。それ以外の場合は、1PEw.dEe 記述子が使用されます。f95 では、d1 = -2、かつ、d2 = +8 です。

f95 での区間データ項目の出力については、d と e 用の値は、同じ KTPV を持つ REAL 型用のものと同じです。w の値は、コード例 2-37 が示しているように、2 つの REAL と角括弧「 [ 」、「 ] 」とコンマの 3 つの追加文字の調整を行います。

単数入力/出力と基本変換

単数区間入力はその直後に出力が続くと、実際に基数変換が、格納された入力区間幅を 1 または 2-ulp だけ増加させるため、小数桁の正確性が失われた形で現れます。たとえば、1.37 の入力の直後に表示を行うと、1.3 が出力されることになります。「書式付き入力/出力」を参照してください。

コード例 1-6 で示しているように、プログラムは、入力値と (入力文字列を有効な内部的な近似値に変換するための) 内部的な読み取りとを正確に反映するために、文字入力/出力を使用しなければなりません。

組み込み区間関数

この節には f95 の組み込みの区間関数の特性定義が含まれています。

複数の KTPV を持つ引数を受け入れる一般的な組み込みの区間関数は、一般的な名前と KTPV 個別名の両方を持ちます。組み込みの関数がその KTPV 個別名の名前を使用して呼び出される場合、引数はそれに見合った KTPV を持たなければなりません。


注 - f95 では、いくつかの KTPV-16 個別組み込み関数は提供されていません。これは、実装上の未解決の問題です。

複数の区間データ項目 (たとえば、SIGN(A,B)) を受け入れる関数を使用した場合は、すべてのデータ引数は同じ KTPV を持たなければなりません。最大幅要求式処理のもとでは、この制約への準拠が自動的に行われます。厳密式処理を使う場合は、組み込み関数の引数に関する型と KTPV の制限を開発者の責任で守らなければなりません。異なる KTPV の引数を使用すると実行時エラーが発生します。

数学関数

この節では、区間引数を受け入れる型変換関数、三角関数、その他の関数を列挙します。区間 [ , ] での記号 と は、それぞれ、順位付けられた要素として、最大下限と最小上限を表すために用いられます。点 (非区間) 関数定義内部では、小文字の x と y は、REAL または INTEGER 値を表すために用いられます。

区間引数 X の関数 f の評価時には、区間結果 f(X) は、次のように包含集合、cset(f,{x})の囲みの中に入っていなければなりません。

n 個の変数の関数についても同様の結果が当てはまります。区間 が f の変域の外側の値を含む場合に含まれなければならない値の包含集合の決定のしかたについては、「参考文献」で引用した補足文献 [1] の中で解説されています。そこでの結果は、定義の境界上であるいは定義の変域の外側で評価される場合に、関数が生成できる値の集合を決定するために必要です。この包含集合と呼ばれる値の集合は、関数の引数または演算子オペランドの値のが何であるかにかかわらず有効な結果を返す区間システムを定義する上での鍵となります。このため、f95 の任意の組み込みの INTERVAL 関数に関し、引数の制約は存在しません。

逆正接の組み込み関数 ATAN2(Y,X)

この節では、逆正接組み込み関数の追加的な情報を提供します。詳細については、「参考文献」で引用した補足文献 [9] を参照してください。

解説: 一対の区間に対する逆正接組み込み関数の区間の囲みです。

数学定義:

クラス: 要素別処理関数です。

特別な値: 表 2-14 とコード例 2-24 は ATAN2 の不定形式を示しています。

表 2-14   ATAN2 の不定形式
y0 x0 cset(sin, {y0, x0}) cset(cos, {y0, x0}) cset(, {y0, x0})
0 0 [-1, 1] [-1, 1]
+ + [0, 1] [0, 1]
+ - [0, 1] [-1, 0]
- - [-1, 0] [-1, 0]
- + [-1, 0] [0, 1]


コード例 2-54   ATAN2 の不定形式

math% cat ce2-54.f95
   INTERVAL :: X, Y
   INTEGER  :: IOS = 0
   PRINT *, "Press Control/D to terminate!"
   WRITE(*, 1, ADVANCE='NO')
   READ(*, *, IOSTAT=IOS) Y, X
   DO WHILE (ios >= 0)
      PRINT *, "For X =", X, "For Y =", Y
      PRINT *, 'ATAN2(Y,X)= ', ATAN2(Y,X)
      WRITE(*, 1, ADVANCE='NO')
      READ(*, *, IOSTAT=IOS) Y, X
   END DO
1  FORMAT("Y, X = ?")
   END
math% f95 -xia ce2-54.f95
math% a.out
 Press Control/D to terminate!
Y, X = ? [0] [0]
For X = [0.0E+0,0.0E+0] For Y = [0.0E+0,0.0E+0]
ATAN2(Y,X)=  [-3.1415926535897936,3.1415926535897936]
 Y, X = ? inf inf
For X = [1.7976931348623157E+308,Inf] For Y = 
[1.7976931348623157E+308,Inf]
 ATAN2(Y,X)=  [0.0E+0,1.5707963267948968]
 Y, X = ?inf -inf
For X = [-Inf,-1.7976931348623157E+308] For Y =
 [1.7976931348623157E+308,Inf]
 ATAN2(Y,X)=  [1.5707963267948965,3.1415926535897936]
 Y, X = ?-inf +inf
For X = [1.7976931348623157E+308,Inf] For Y = 
[-Inf,-1.7976931348623157E+308]
 ATAN2(Y,X)=  [-1.5707963267948968,0.0E+0]
 Y, X = ?-inf -inf
For X = [-Inf,-1.7976931348623157E+308] For Y = 
[-Inf,-1.7976931348623157E+308]
 ATAN2(Y,X)=  [-3.1415926535897936,-1.5707963267948965]
 Y, X = ? <Control-D>

引数: Y は INTERVAL 型です。X は Y と同じ型と KIND のパラメータです。

結果特性: 引数に同じ。

結果値: 区間の結果値は、指定した区間に対する 1 つの囲みです。理想的な囲みは、記述されたものと同じ数学的な区間を含む最小幅の区間です。

1 つまたは両方の引数が空であれば、結果は空になります。

x < 0、かつ、 の場合に、鋭い区間の囲み (Θで表される) を得るためには、すべての返される可能性のある区間角度の集合を一意に定義する次の方法を用いてください。

この選択を次の選択と合わせれば、

ATAN2(Y, X)が必ず含まなければならない区間角度 Θ の一意の定義となります。

表 2-15 は、鋭い区間角度の生成に必要な制限を満たすアルゴリズムでの Θ の終了点の計算に使用する REAL ATAN2 関数のテスト内容と引数を示しています。最初の 2 つの桁は区別するケースを定義しています。3 つ目の桁は区間 Θ の中点 m (Θ)の可能な値の範囲を含みます。最後の 2 つの桁は、REAL ATAN2 組み込み関数を使って、Θ の終了点が計算される方法を示しています。包含を保証するためには有向の丸めが使われなければなりません。

表 2-15   REAL ATAN2 関数のテスト内容と引数
Y X m() q q
- < y x < 0 ATAN2(y, x) ATAN2( , x) + 2
- = y x < 0 ATAN2(y, x) 2 -
< - x < 0 ATAN2(y, x) - 2 ATAN2( , x)


最大:MAX(X1,X2,[X3, ...])

解説: 最大範囲です。

max(X1, ..., Xn) に対する包含集合は次のとおりです。

MAX 組み込み関数の実装は次の式を満たさなければなりません。

MAX(X1,X2,[X3, ...]) {max(X1, ..., Xn)}

クラス: 要素別処理関数です。

引数: 引数は INTERVAL 型であり、同じ型と KIND 型のパラメータを持ちます。

結果特性: 結果特性は INTERVAL 型です。kind 型パラメータは引数と同じ型です。

最小:MIN(X1,X2,[X3, ...])

解説: 最小範囲です。

min(X1, ..., Xn) に対する包含集合は次のとおりです。

MIN 組み込み関数の実装は次の式を満たさなければなりません。

MIN(X1,X2,[X3, ...]) ⊇ {min(X1, ..., Xn)}

クラス: 要素別処理関数です。

引数: 引数は INTERVAL 型であり、同じ型と KIND 型のパラメータを持ちます。

結果特性: 結果は INTERVAL 型です。 kind 型パラメータは引数と同じ型です。

組み込み関数

表 2-17 から表 2-21 では、区間引数を受け入れる組み込み関数の特性を一覧表示しています。表 2-16 では、これらの表の区間組み込み関数の特性項目を一覧表示しています。

表 2-16   各区間組み込み関数の特性項目
特性項目 解説
組み込み関数 関数の処理内容
定義 数学上の定義
引数の数 関数が受け入れる引数の数
一般名 関数の一般名
個別名 関数の個別名
引数の型 各固有の名前に関連付けられたデータ型
関数の型 個別引数データ型に対する戻り値のデータ型


区間組み込み関数には、KTPV4、8、16 のバージョンが定義されています。対応する個別組み込み関数名は VS、VD、VQ で始まり、それぞれ、interVal Single、interVal Double、interVal Quad を表します。

各個別 REAL 組み込み関数に対応する区間組み込み関数が存在し、VSSIN() と VDSIN() のように、これらの関数には、VS、VD、VQ の接頭辞が付きます。

不定形式は可能ですから、「べき乗演算子 X**N と X**Y」と 「逆正接の組み込み関数 ATAN2(Y,X)」には、X**Y と ATAN2 関数の特別な値が含まれています。その他の組み込み関数ではこのような取り扱いの必要はありません。

表 2-17   組み込みの区間演算関数
組み込み関数 非区間での
定義
引数の数 総称名 個別名 引数の型 関数の型
絶対値 |a| 1
ABS
VDABS
VSABS
VQABS
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
切り上げ (注記 1 を参照) int(a) 1
AINT
VDINT
VSINT
VQINT
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
最近似値整数 a 0 の場合は int(a + .5) a < 0 の場合は int(a - .5) 1
ANINT
VDNINT
VSNINT
VQNINT
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
剰余 a-b(int(a/b)) 2
MOD
VDMOD
VSMOD
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
符号転送 (注記 2 を参照) |a| sgn(b) 2
SIGN
VDSIGN
VSSIGN
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
最大値の選択 (注記 3 を参照) max(a,b,...) 2
MAX
MAX
INTERVAL
INTERVAL
最小値の選択 (注記 3 を参照) min(a,b,...) 2
MIN
MIN
INTERVAL
INTERVAL
(1) a > 0 の場合は int(a) = floor(a)、a < 0 の場合は ceiling(a)

(2) signum 関数は、a < 0 の場合 sgn(a) = -1、a < 0の場合 +1、a = 0 の場合 0 となります。

(3) MIN と MAX 組み込み関数は、すべての引数が空でなければ、空の区間引数を無視します。すべての引数が空の場合は空の区間が返されます。


表 2-18   組み込みの区間型変換関数
変換先 引数の数 総称名 引数の型 関数の型
INTERVAL 1、2 または 3
INTERVAL
INTERVAL
INTERVAL(4)
INTERVAL(8)
INTEGER
REAL
REAL(8)
REAL(16)
INTERVAL
INTERVAL
INTERVAL
INTERVAL
INTERVAL
INTERVAL
INTERVAL
INTERVAL(4) 1 または 2
SINTERVAL
INTERVAL
INTERVAL(4)
INTERVAL(8)
INTEGER
REAL
REAL(8)
REAL(16)
INTERVAL(4)
INTERVAL(4)
INTERVAL(4)
INTERVAL(4)
INTERVAL(4)
INTERVAL(4)
INTERVAL(4)
INTERVAL(8) 1 または 2
DINTERVAL
INTERVAL
INTERVAL(4)
INTERVAL(8)
INTEGER
REAL
REAL(8)
REAL(16)
INTERVAL(8)
INTERVAL(8)
INTERVAL(8)
INTERVAL(8)
INTERVAL(8)
INTERVAL(8)
INTERVAL(8)
INTERVAL(16) 1 または 2
QINTERVAL
INTERVAL
INTERVAL(4)
INTERVAL(8)
INTERVAL(16)
INTEGER
REAL
REAL(8)
INTERVAL(16)
INTERVAL(16)
INTERVAL(16)
INTERVAL(16)
INTERVAL(16)
INTERVAL(16)
INTERVAL(16)


表 2-19   組み込みの区間三角関数
組み込み関数 非区間での定義 引数の数 総称名 個別名 引数の型 関数の型
正弦 sin(a) 1
SIN
VDSIN
VSSIN
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
余弦 cos(a) 1
COS
VDCOS
VSCOS
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
正接 tan(a) 1
TAN
VDTAN
VSTAN
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
逆正弦 arcsin(a) 1
ASIN
VDASIN
VSASIN
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
逆余弦 arccos(a) 1
ACOS
VDACOS
VSACOS
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
逆正接 arctan(a) 1
ATAN
VDATAN
VSATAN
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
逆正接 (注記 1 を参照) arctan(a/b) 2
ATAN2
VDATAN2
VSATAN2
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
双曲正弦 sinh(a) 1
SINH
VDSINH
VSSINH
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
双曲余弦 cosh(a) 1
COSH
VDCOSH
VSCOSH
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
双曲正接 tanh(a) 1
TANH
VDTANH
VSTANH
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
(1) a = h sin、b = h cos、かつ、h2 = a2 + b2 であれば、arctan(a/b) = となります。


表 2-20   その他の組み込みの区間数学関数
組み込み関数 非区間での
定義
引数の数 総称名 個別名 引数の型 関数の型
平方根 (注記 1 を参照) exp{ln(a)/2} 1
SQRT
VDSQRT
VSSQRT
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
指数 exp(a) 1
EXP
VDEXP
VSEXP
INTERVAL
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
自然対数 ln(a) 1
LOG
VDLOG
VSLOG
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
常用対数 log(a) 1
LOG10
VDLOG10
VSLOG10
INTERVAL(8)
INTERVAL(4)
INTERVAL(8)
INTERVAL(4)
(1) sqrt(a) は複数の値を持ちます。正と負の両方の平方根を含むためには、適切な区間の囲みが必要です。
SQRT 組み込み関数を次のように定義するとこの問題を除去できます。


表 2-21   区間組み込み関数 
組み込み関数 定義 引数の数 総称名 個別名 引数の型 関数の型
INF inf([a, b]) = a 1
INF
VDINF
VSINF
VQINF
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
REAL(8)
REAL(4)
REAL(16)
SUP sup([a, b]) = b 1
SUP
VDSUP
VSSUP
VQSUP
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
REAL(8)
REAL(4)
REAL(16)
幅 w([a, b]) = b - a 1
WID
VDWID
VSWID
VQWID
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
REAL(8)
REAL(4)
REAL(16)
中点 mid([a, b]) = (a + b)/2
1
MID
VDMID
VSMID
VQMID
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
REAL(8)
REAL(4)
REAL(16)
マグニチュード (注記 1 を参照) max(|a|) A 1
MAG
VDMAG
VSMAG
VQMAG
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
REAL(8)
REAL(4)
REAL(16)
ミグニチュード (注記 2 を参照) min(|a|) A 1
MIG
VDMIG
VSMIG
VQMIG
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
REAL(8)
REAL(4)
REAL(16)
空区間の検査 A が空なら true 1
ISEMPTY
VDISEMPTY
VSISEMPTY
VQISEMPTY
INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
LOGICAL
LOGICAL
LOGICAL
下限 floor(A) 1
FLOOR

INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
INTEGER
INTEGER
INTEGER
上限 ceiling(A) 1
CEILING

INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
INTEGER
INTEGER
INTEGER
精度 precision(A) 1
PRECISION

INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
INTEGER
INTEGER
INTEGER
範囲 range(A) 1
RANGE

INTERVAL(8)
INTERVAL(4)
INTERVAL(16)
INTEGER
INTEGER
INTEGER
桁数 (注記 3 を参照) Y 編集記述子を使った最大桁数 1
NDIGITS

INTERVAL
INTERVAL(4)
INTERVAL(16)
INTEGER
INTEGER
INTEGER
(1) mag([a, b]) = max(|a|,|b|)

(2) a > 0 または b < 0 であれば、mig([a, b]) = min(|a|,|b|)、その他の場合は、0

(3) 特別なケース: NDIGITS([-inf, +inf]) = NDIGITS([EMPTY]) = 0


参考文献

下記の技術報告書がオンラインで利用できます。これらのファイルの所在については、区間演算の README を参照してください。

  1. G.W.Walster、E.R.Hansen、J.D.Pryce著、『Extended Real Intervals and the Topological Closure of Extended Real Relations』、技術報告書、Sun Microsystems (2000 年 2 月)。

  2. G.William Walster著、『Empty Intervals』、技術報告書、Sun Microsystems
    (1998 年 4 月)。

  3. G.William Walster著、『Closed Interval Systems』、技術報告書、Sun Microsystems (1999 年 8 月)。

  4. G.William Walster著、『Literal Interval Constants』、技術報告書、Sun Microsystems (1999 年 8 月)。

  5. G.William Walster著、『Widest-need Interval Expression Evaluation』、技術報告書、Sun Microsystems (1999 年 8 月)。

  6. G.William Walster著、『Compiler Support of Interval Arithmetic With Inline Code Generation ans Nonstop Exception Handling』、技術報告書、Sun Microsystems (2000 年 2 月)。

  7. G.William Walster著、『Finding Roots on the Edge of a Function's Domain』、技術報告書、Sun Microsystems (2000 年 2 月)。

  8. G.William Walster著、『Implementing the 'Simple' Closed Interval System』、技術報告書、Sun Microsystems (2000 年 2 月)。

  9. G.William Walster著、『Interval Angles and the Fortran ATAN2 Intrinsic Function』、技術報告書、Sun Microsystems (2000 年 2 月)。

  10. G.William Walster著、『The 'Simple' Closed Interval System』、技術報告書、Sun Microsystems (2000 年 2 月)。

  11. G.William Walster、Margaret S. Bierman著、『Interval Arithmetic in Forte Developer Fortran』、技術報告書、Sun Microsystems (2000 年 2 月)。


サン・マイクロシステムズ株式会社
Copyright information. All rights reserved.
ホーム   |   目次   |   前ページへ   |   次ページへ   |   索引