(57)【特許請求の範囲】
【請求項１】
組み込みソフトウェアを構成する任意の情報処理機能として定義されたブロックに対応したプログラムの動作確認を行うシミュレーション装置であって、
前記ブロックに対応したプログラムのオペレータモデルまたはオペランドモデルを含んだコード片を保存するブロックデータベースからシミュレーション対象であるブロックのコード片に含まれるオペレータモデルまたはオペランドモデルの型に対応した整数型及び浮動小数点型の値を取得するシミュレーションモデル値取得機能と、
シミュレーションモデルデータベースから取得された前記ブロックに対応したシミュレーションモデルのオペレータモデルまたはオペランドモデルに対して前記整数型及び浮動小数点型の初期値を設定するシミュレーションモデル初期値設定機能と、
前記シミュレーション対象のオペレータモデルまたはオペランドモデルの型に対応した整数型及び浮動小数点型の演算クラスのインスタンスに属する演算メソッドを選択するシミュレーションモデル型ごと演算選択機能と、
前記取得された前記オペレータモデルまたはオペランドモデルの値と前記設定された前記シミュレーションモデルの初期値とを前記選択された演算メソッドによる演算に供することにより、前記ブロックのシミュレーション演算を行うシミュレーションモデル演算機能と
を有することを特徴するシミュレーション装置。
【請求項２】
前記整数型及び浮動小数点型の演算クラスは、Ｃ言語の整数型及び浮動小数点型の演算クラスであること
を特徴とする請求項１に記載のシミュレーション装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ソフトウェアの開発支援システムに係わり、特に組み込みソフトウェアとして作成するプログラムの動作確認に使用するシミュレーション装置によるシミュレーション方法に関するものである。
【背景技術】
【０００２】
組込みソフトウェア開発では、演算に関する設計図としてブロック図を作成する。ブロック図の要素としてはブロックと線があり、これらが図面上で接続されることで、ソフトウェアとして実現したい内容を表現する。この設計図を元にユーザがソフトウェアとして組み込もうとする任意の情報処理機能をブロック図として定義し、定義されたブロック図の動作確認はブロック単体または全体のシミュレーションを行うことが特許文献１によって公知となっている。
【０００３】
図１７は、特許文献１におけるシミュレーション装置の構成図を示したもので、コンピュータとその資源を利用したソフトウェアで各機能が実現されている。
【０００４】
各機能は、組み込みソフトウェアを構成する各ブロック図について個々に作成されたコード片を保存するブロックデータベース１と、このデータベースに保存するコード片からオペレータモデルとオペランドモデル構成のシミュレーションモデルを作成するシミュレーションモデル作成機能２と、シミュレーションモデルのうち、オペレータモデルに演算対象のシミュレーションモデルを関連付ける演算対象関連付け機能３と、シミュレーションモデルのうち、オペランドモデルにブロック図の実際の情報を関連付けるブロック図情報関連付け機能４と、作成したシミュレーションモデルをデータベース５に保存するシミュレーションモデル保存機能６を備える。
【０００５】
シミュレーションモデル実行機能７は、シミュレーションモデル作成機能２で作成したシミュレーションモデル、またはシミュレーションモデルデータベース５から取得機能８が取得するシミュレーションモデルについて、シミュレーションを実行する。このシミュレーションの実行は、後述のように、多数のブロックの接続によって１つのまとまった機能をもたせたプログラムについて、その一連の動作の正常／異常をチェックする場合などに利用する。
【０００６】
ブロック単体に対応するプログラムの動作チェックのためのシミュレーションは機能９〜１５によって実行される。これら各機能は、シミュレーションモデルデータベース５からシミュレーションモデル取得機能８が取得するシミュレーション対象ブロック単体の入力に初期値を設定するシミュレーション初期値設定機能９と、取得したシミュレーション対象ブロック単体について、ブロックデータベース１から実際の値を取得するシミュレーションモデル値取得機能１０と、シミュレーションモデルで取得した値と演算対象から取得した値を使用してシミュレーション演算するシミュレーションモデル演算機能１１と、シミュレーション演算結果を演算結果データベース１２に保存するシミュレーションモデル演算結果保存機能１３と、演算結果データベース１２から演算結果の一部またはすべてを取得する演算結果取得機能１４と、取得した演算結果を外部表示装置（ディスプレイなど）に表示する演算結果表示機能１５で構成される。
【先行技術文献】
【特許文献】
【０００７】
【特許文献１】特開２００９−１９３１８２
【非特許文献】
【０００８】
日本福祉大学情報社会科学論文集  第11巻  「大きな整数と除算アルゴリズム」ｐ８１〜８９
【発明の概要】
【発明が解決しようとする課題】
【０００９】
特許文献１のようなシミュレーション装置がＣ／Ｃ＋＋／Ｊａｖａ（登録商標）のような高級言語（以下、記述言語と記載する）で実現されるとき、シミュレーションモデルの演算およびそのオペランド・結果について次のような問題がある。
【００１０】
シミュレーション対象のプログラムのソースコードはＣ言語のような高級言語（以下、対象言語と記載する）で記述（生成）されるので、演算のオペランドや演算結果には型がある。例えばＣ言語では、整数型としてchar, signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsgined long, long long, unsigend long long、浮動小数点数型としてfloat, double, long doubleなどの型が規定されており、これらの型はそれぞれに取りうる値の範囲が限定されている。その範囲は対象言語の規格では厳密に定められずコンパイラや設定によって異なる場合があるが、これは対象とするコンパイラと設定を特定すれば確定できる。
【００１１】
図２に一例として組込み環境で使われるSuperHプロセッサ用開発環境HEWでの各型の取りうる値の範囲を示す。
問題は、上記のような対象言語による数値演算を記述言語によってシミュレーション記述する場合に
(1) 対象言語の基本型（言語仕様で定義された型）が、記述言語の基本型の範囲で表現できないことがある。
具体例として、Ｃ言語のunsgined long long型が取りうる値の範囲は少なくとも0〜18446744073709551615を含み、Ｊａｖａ言語の基本型で最も大きな整数型であるlong型(-9223372036854775808〜9223372036854775807)の範囲に入らないためＣ言語のunsgined long long型をＪａｖａ言語の基本型では表現できない。
【００１２】
(2) 記述言語の演算において演算結果が取りうる値の範囲を逸脱してもチェックできないことがある。
実際にＣ／Ｃ＋＋／Ｊａｖａでは、基本整数型の演算結果が取りうる値の範囲を逸脱する場合にコンパイル時にも実行時にも通知されない。多くの場合には単に表現できない上位ビットを無視した値に置換されるだけである。
という点である。
【００１３】
記述言語に対象言語と同等の型（取りうる範囲が同じで範囲を逸脱する場合を含めて演算に対する振る舞いが同じ型）が存在し、かつ各型で取りうる値の範囲からの逸脱をシミュレーションで確認する必要が無い場合は、シミュレーション装置で対象言語と同じ動作ができるという意味でこれは問題にならない。しかし、記述言語に対象言語と同等の型が存在しない場合、あるいはシミュレーションで各型で取りうる値の範囲からの逸脱を確認する必要がある場合には、この問題に対応する必要がある。
【００１４】
整数型に対する四則演算の演算結果を範囲逸脱せずに収めるには、オペランドの型に対して、加減算の場合で1ビット以上、乗算の場合では2倍以上のビット数の範囲を表現できる必要がある。最大の基本型に対応するには多倍長演算が必要になる。
例えばＪａｖａ言語標準ライブラリの多倍長演算クラスjava.math.BigDecimalのような多倍長演算が可能な型を利用すれば、非常に広い範囲の数が扱えるため対象言語の基本型で取りうる値の範囲は確実に表現することができるので(1)が解決でき、演算結果の値も表現できるため演算後に結果の値が各型で取りうる値の範囲に入るか否か比較チェックすることで(2)も解決できる。取りうる値の範囲外であったときには範囲逸脱としてマークするほか、対象言語で範囲を逸脱した場合に取るのと同様の値に置換することもできる。
しかし、多倍長演算は非常に重たい計算であり、シミュレーションに大きな時間が掛かるという問題がある。
【００１５】
本発明の目的は、処理の無駄を省いて高速処理を可能とするソフトウェアの開発支援システムにおけるシミュレーション方法を提供することにある。
【課題を解決するための手段】
【００１６】
本発明の一態様は、組み込みソフトウェアを構成する任意の情報処理機能として定義されたブロックに対応したプログラムの動作確認を行うシミュレーション装置であって、前記ブロックに対応したプログラムのオペレータモデルまたはオペランドモデルを含んだコード片を保存するブロックデータベースからシミュレーション対象であるブロックのコード片に含まれるオペレータモデルまたはオペランドモデルの型に対応した整数型及び浮動小数点型の値を取得するシミュレーションモデル値取得機能と、シミュレーションモデルデータベースから取得された前記ブロックに対応したシミュレーションモデルのオペレータモデルまたはオペランドモデルに対して前記整数型及び浮動小数点型の初期値を設定するシミュレーションモデル初期値設定機能と、前記シミュレーション対象のオペレータモデルまたはオペランドモデルの型に対応した整数型及び浮動小数点型の演算クラスのインスタンスに属する演算メソッドを選択するシミュレーションモデル型ごと演算選択機能と、前記取得された前記オペレータモデルまたはオペランドモデルの値と前記設定された前記シミュレーションモデルの初期値とを前記選択された演算メソッドによる演算に供することにより、前記ブロックのシミュレーション演算を行うシミュレーションモデル演算機能とを有する。
【００１７】
本発明の一態様は、前記シミュレーション装置において、前記整数型及び浮動小数点型の演算クラスは、Ｃ言語の整数型及び浮動小数点型の演算クラスである。
【発明の効果】
【００１９】
以上のとおり、本発明によれば、プログラムの動作において大きな時間を使うオブジェクト生成・削除の処理が大幅に減らせ、また無駄な演算を削減することができる。これらにより、演算クラスを例えばＪａｖａ言語標準ライブラリの多倍長演算クラスjava.math.BigDecimalのような多倍長演算が可能な型を利用した場合と比べて、演算部分については十数倍から数十倍、シミュレーション全体としても数倍から十数倍の高速実行が可能となる。
【図面の簡単な説明】
【００２０】
【図１】本発明の実施形態を示すシミュレーション装置の構成図。
【図２】対象言語Ｃ言語による型毎に対応する値の範囲図。
【図３】ブロック図とコード片とシミュレーションモデルの関係図。
【図４】範囲チェック付演算クラスの構成図。
【図５】範囲チェック付演算クラスのメンバとメソッドの構成図。
【図６】CheckedUInt64型の値をCheckedFloat64型の変数へ代入時のシーケンス図。
【図７】CheckedUInt64型による加算フローチャート。
【図８】CheckedUInt64型による減算フローチャート。
【図９】CheckedUInt64型による乗算フローチャート。
【図１０】CheckedUInt64型による除算フローチャート。
【図１１】CheckedUInt64型による剰余フローチャート。
【図１２】CheckedUInt64型による内部比較メソッドのフローチャート。
【図１３】CheckedInt64型による加算フローチャート。
【図１４】CheckedInt64型による減算フローチャート。
【図１５】CheckedInt64型による乗算フローチャート。
【図１６】CheckedUInt32型による乗算フローチャート。
【図１７】従来のシミュレーション装置の構成図。
【発明を実施するための形態】
【００２１】
図1は本発明に使用されるシミュレーション装置の構成図を示したもので、図１７で示す従来のシミュレーション装置と異なる点は、シミュレーションモデル型ごと演算選択機能１６を設けると共に、シミュレーションモデル演算機能１１´に型ごとの演算機能を付加したものである。他は図１７で示すシミュレーション装置と同様である。
【００２２】
シミュレーション装置が扱うシミュレーションモデルにおいては、演算内容を指示する記号などのオペレータを表すオペレータモデルと、演算対象となる値や変数などのオペランドを表すオペランドモデルとで、オペレータが扱うオペランドおよびオペレータの演算結果について、シミュレーションモデル型ごと演算選択機能１６において値や変数の型を保持する。この型は図３のようにブロック図からシミュレーションモデルを作成する手順において、値や変数に付随する型情報（図３で付加したｉｎｔ型の表現部分）からシミュレーションモデルに型を反映する。
【００２３】
シミュレーションモデル演算機能１１´は、シミュレーションモデル型ごと演算選択機能１６に保持された型ごと数値範囲チェック付き演算クラス・インスタンスに属する演算メソッドを、オペランドの範囲チェック付演算クラス・インスタンスを引数に呼び出して型ごとに異なる機能を構成してシミュレーション演算を実行する。
【００２４】
例えば、記述言語がオブジェクト指向言語の場合、型ごとの演算機能１１´はクラスの継承を用いて簡潔に記述できる。記述言語がオブジェクト指向言語で無い場合は記述が複雑になるが、オブジェクト指向を模擬する記述を行うことでオブジェクト指向言語の場合と同様に型を表現できる。 
【００２５】
以下、対象言語Ｃ言語で型ごとの値の範囲が図２のパターン、記述言語Ｊａｖａ言語の場合について、型に対応する範囲チェック付き演算クラスの構成を記述する。
【００２６】
図４に範囲チェック付き演算クラスの継承図を示す。また図５に
CheckedUInt64を例に範囲チェック付き演算クラスのメンバとメソッドの詳細構成を示す。
CheckedNumberは範囲チェック付き演算クラスの基底クラスであり、オーバーフロー(overflow)、アンダーフロー(underflow)、桁落ち(canceling)、不正確(inaccurate)といった値の状態を保持する。また、シミュレーションで実行する各種演算を実現する処理を抽象メソッドとして宣言する。
【００２７】
演算としては、単項マイナス(minus)、加算(add)、減算(sub)、乗算(mul)、除算(div)、剰余(mod)、論理積(and)、論理和(or)、排他的論理和(xor)、論理否定(not)、左シフト(shift_l)、右シフト(shift_r)、一致比較(equal)、大小比較(more, less)、代入(set)などがある。これらはオペランドをメソッドの引数に取り、演算結果を自身に保存する。なおＣ言語には等号を含む大小比較や、演算と代入を合わせた複合代入演算もあるが、本実施例では説明の煩雑さを避けるために記述を省略している。また、演算の途中で明示的あるいは暗示的な型変換が発生する場合、それはシミュレーションモデルの作成において異なる型間の代入演算に展開されているものとし、具体的な動作は代入演算として説明する。
【００２８】
CheckedIntegerおよびCheckedFloatingPointはCheckedNumberの継承クラスで、それぞれ整数型および浮動小数点型を示す。これらは整数型のみで定義された演算(論理演算など)で型チェックするためなどに用いる。
【００２９】
CheckedIntegerの継承クラスとしてはＣ言語の各整数型に対応するクラスがあり、それぞれの型の値(value)を保持するとともに整数演算の処理を実装する。なお図２でcharとsigned char、intとlong、unsigned intとunsigned longはそれぞれ同じ値の範囲を取るので、これらは本実施例においてはそれぞれ同じクラスを用いている。
【００３０】
CheckedFloatingPointの継承クラスとしてはＣ言語の各浮動小数点数型に対応するクラスがあり、それぞれの型の値を保持するとともに浮動小数点演算の処理を実装する。なお図２でdoubleとlong doubleは同じ値の範囲を取るので、これらは本実施例においては同じクラスを用いている。
【００３１】
次に具体的な動作について説明する。
作成されたブロック単体に対応するプログラムの動作チェックのためのシミュレーションは図１で示す機能９〜１６によって行われる。シミュレーションモデル取得機能８によりデータベース５から取得したシミュレーションモデルの初期値をシミュレーションモデル初期値設定機能９により設定する。一方、シミュレーションモデル値取得機能１０は、関連付けられているオペレータモデルまたはオペランドモデルから値を取得する。
【００３２】
シミュレーションモデル型ごと演算選択機能１６には、シミュレーションモデル初期値設定機能９により設定された初期値と、シミュレーションモデル値取得機能１０により取得・設定されたオペレータモデルまたはオペランドモデルの値を型毎に演算選択する。シミュレーションモデル演算機能１１´には、プログラム演算の数値範囲チェック付演算手段が設けられており、シミュレーションモデル型ごと演算選択機能１６に保持された数値範囲チェック付き演算クラス・インスタンスに属する演算メソッドを、オペランドの範囲チェック付演算クラス・インスタンスを引数に呼び出してブロック単体のシミュレーション演算を行う。
この演算結果はシミュレーションモデル演算結果保存機能１３により、演算結果データベース１２に保存する。
【００３３】
シミュレーションモデル演算機能１１´の数値範囲チェック付演算手段は、上記のシミュレーション演算を、演算結果の範囲チェック付き演算クラス・インスタンスに属する演算メソッドを、オペランドの範囲チェック付き演算クラス・インスタンスを引数に呼び出すことで実現する。本発明では、範囲チェック付き演算クラスの継承クラス毎の値の保持方法および演算の実現方法に特徴を持たせ、処理のムダを省いて高速化するものである。記述言語全体に共通する特徴点としては、以下がある。
・プログラムにおいて処理が重いオブジェクトの生成・削除を減らすため、演算処理においてクラス・オブジェクトの生成を控えて基本型変数のみで演算処理を行う
・代入においてinstanceofを使ったオブジェクトのクラス識別を行うと処理が重たいので、ビジターパターンを応用した呼び返しコードによりinstanceofを使わないクラス別処理を実施する
以下、クラスごとの演算方法を含めて工夫に必要な動作について記載する。
１．型全体に共通するものについて
（１）代入
シミュレーション実行においては随所でCheckedNumber型の値をCheckedNumber型変数に代入する処理が必要になる。値も変数も実際にはCheckedNumberの継承クラスのオブジェクトであるので、個別に変換を行ったりエラーを提示する必要があるが、instanceofなどの型判定手段を用いてクラスを特定する処理は重く実行に時間が掛かる。
【００３４】
CheckedNumber型で宣言した、set、assignTo、setCheckedUInt64等の代入メソッドを利用し、以下のような手順で高速な代入を実現する。
【００３５】
図６に代入の実行シーケンスの例を示す。図６はCheckedUInt64型の値fromを、CheckedFloat64型の変数toに代入する手順のシーケンス図である。
（ａ），シミュレーション実行からto.set(from)を呼び出す。
setはCheckedNumberで宣言し、assignToを呼び出すように定義したメソッドである。
（ｂ），setがfrom.assignTo(this)を呼び出す。
assignToはCheckedNumberで宣言し、各継承クラスXXXで自身の型の値を代入するsetXXXメソッドを呼び出すように定義したメソッドである。
（ｃ），assignToがto.setCheckedUInt64(this)を呼び出す。
setCheckedUInt64はCheckedNumberで宣言し、エラーを出すように定義したメソッドである。
各継承クラスでCheckedUInt64からの代入が可能ならばsetCheckedUInt64を再定義して実際の値を代入する。代入の際に値が正確でなくなる場合やオーバーフローやアンダーフローが起きる場合はCheckedNumberの該当するメンバをtrueに設定する。
CheckedNumberの具象継承クラスごとに同様の代入メソッドをCheckedNumberで宣言して必要な継承クラスで再定義する。
（ｄ），CheckedUInt64値をCheckedFloat64に代入する場合は正確でなくなる可能性があるので、その場合はinaccurateをtrueにする。この代入は常にできるので、CheckedUInt64値をCheckedFloat64のデータメンバであるdouble型の変数に型変換して代入する。
なお、その他の各クラスでの代入時の詳細については後述の各クラスの説明に記載する。
（２）比較
Ｃ言語では比較の返値は整数なので、比較演算(equal, more, less)はCheckedInt32の返値を持つものとする。これらのメソッドはCheckedNumber型で宣言されCheckedInt32で再定義される。内部比較メソッド比較(cmp)の結果を使って、equal、more、lessの結果をそれぞれcmp(a,b)==0、cmp(a,b)>0、cmp(a,b)<0に従って求める。結果が真のときは1を、偽のときは0をそれぞれCheckedInt32型に設定して返す。
２．CheckedUInt64型について
（１）値保持
CheckedUInt64は64ビット幅を持つ非負整数の型である。Ｊａｖａ言語のlong型変数は64ビット幅を持つが符号付であり最上位ビットは符号を示すので値は63ビット分しか保持できない。しかし符号ビットを符号として扱わずに単にデータを保持するビットとして扱うなら64ビット幅を持つ非負整数をＪａｖａ言語のlong型変数に値を保存することが可能である。CheckedUInt64は、このようにしてＪａｖａ言語のlong型変数valueに値を保持する。
（３）加算
加算(add)のフローチャートを図７に示す。
addはCheckedNumber型で宣言されCheckedUInt64で再定義されたメソッドで、2つの引数a,bはCheckedNumber型で宣言されるがCheckedUInt64の値を持つ。これはシミュレーションモデルで保証できるのでフローチャートでは、型チェックと型変換の記述は省略する。
まず701で引数a,bをそれぞれ下位62ビットと上位2ビットに分けて、al、ah、bl、bhの変数に代入する。
次に702で下位・上位それぞれの加算を計算する。
最後に703で下位と上位を合成して加算結果を作り、上位が3を超えるとオーバーフローを設定する。
（４）減算
減算(sub)のフローチャートを図８に示す。
subはCheckedNumber型で宣言されCheckedUInt64で再定義されたメソッドで、2つの引数a,bはCheckedNumber型で宣言されるがCheckedUInt64の値を持つ。これはシミュレーションモデルで保証できるのでフローチャートでは、型チェックと型変換の記述は省略する。
まず801で引数a,bをそれぞれ下位63ビットと上位1ビットに分けて、al、ah、bl、bhの変数に代入する。
次に802で下位・上位それぞれの減算を計算する。
最後に803で下位と上位を合成して減算結果を作り、上位が負であるとオーバーフローを設定する。
（５）乗算
乗算(mul)のフローチャートを図９に示す。
mulはCheckedNumber型で宣言されCheckedUInt64で再定義されたメソッドで、2つの引数a,bはCheckedNumber型で宣言されるがCheckedUInt64の値を持つ。これはシミュレーションモデルで保証できるのでフローチャートでは、型チェックと型変換の記述は省略する。
まず901で引数a,bをそれぞれ下位30ビットと中位30ビットと上位4ビットに分けて、al、am、ah、bl、bm、bhの変数に代入する。
次に902で下位・中位・上位それぞれの乗算を計算する。このとき明らかにオーバーフローする組合せの乗算は計算しない。
最後に903で下位と中位と上位を合成して乗算結果を作り、上位が16以上の場合、および明らかにオーバーフローする組合せの乗算がゼロで無い場合にはオーバーフローを設定する。
（６）除算・剰余
除算(div)のフローチャートを図１０に、剰余(mod)のフローチャートを図１１に示す。
div、modはCheckedNumber型で宣言されCheckedUInt64で再定義されたメソッドで、2つの引数a,bはCheckedNumber型で宣言されるがCheckedUInt64の値を持つ。これはシミュレーションモデルで保証できるのでフローチャートでは、型チェックと型変換の記述は省略する。
除算と剰余の計算は演算結果を設定する部分を除きほぼ共通である。ここでは除算の説明のみ記載する。
まず1001で除数bの値がゼロかチェックする。ゼロのときは1002でゼロ割エラーの処理をする。シミュレーションが続けられないので中断するなどの処理になる。
【００３６】
そうでなければ、次に1003で除数が1かチェックする。1のときは商は被除数と同じなので1004で設定して最後に1015でオーバーフローをfalseに設定して終了する。
そうでなければ、次に1005でcmpにより除数が被除数より大きくないかチェックする。cmpはCheckedUInt64大小比較と同じやり方で比較を行う。この詳細は比較を参照のこと。除数が被除数より大きいときには1006で商はゼロとして最後に1015でオーバーフローをfalseに設定して終了する。
そうでなければ、次に1007でb.valueが負かチェックする。負のときは除数の最上位ビットが1である場合であり、商は1になるので1008で設定して最後に1015でオーバーフローをfalseに設定して終了する。
そうでなければ、1009でqにゼロ、rに被除数を設定する。
【００３７】
次に1010でrが負かチェックする。負のときは被除数の最上位ビットが1である場合であり、1011で除数の1になっている最上位ビットを被除数の最上位ビットの一つ下に揃えて差し引き、qに差し引いた分を商としてカウントする。1012で一回差し引いても被除数の最上位ビットがまだ1の場合は1013でもう一度差し引く。最大2回差し引いたら最上位ビットは必ず1でなくなるので、被除数・除数ともlongの範囲内で除算可能であり1014ではＪａｖａ言語の機能を使って除算を行う。最後に1015でオーバーフローをfalseに設定して終了する。
【００３８】
なお、1010〜1013で最大2回差し引く処理は、非特許文献１でＫｎｕｔｈのアルゴリズムと呼ばれる多倍長除算のアルゴリズムを応用したものである。
（７）論理演算・シフト演算
論理演算については、符号付整数でも非負整数でも同じ演算で良い。内部表現のlong値をそのまま演算すれば良い。
シフト演算についても左シフトは違いがないし、右シフトは論理右シフトを使用すれば良い。
これらの演算の詳細な処理は省略する。
（８）比較
内部比較メソッド(cmp)のフローチャートを図１２に示す。
cmpはCheckedNumber型で宣言されCheckedUInt64で再定義されたメソッドで、2つの引数a,bはCheckedNumber型で宣言されるがCheckedUInt64の値を持つ。これはシミュレーションモデルで保証できるのでフローチャートでは、型チェックと型変換の記述は省略する。
内部比較では、内部表現が符号付整数であることと、符号が異なるときの符号付整数では非負整数の場合と大小が逆になることを利用している。
まず1201でa,bの値を比較して一致すれば結果を0とする。
【００３９】
次に1203、1204でa,bの値の符号を調べ、一致する場合は1205へ、一致しない場合は1208へ進む。
1205〜1207ではa,bの値の大小を比較し、aが大きいとき1、そうでないとき-1とする。
1208〜1210でもa,bの値の大小を比較し、aが大きいとき-1、そうでないとき1とする。
最後に1211に到達したときの結果(result)の値を返す。
（９）代入
非負整数クラス(CheckedUInt8, CheckedUInt16, CheckedUInt32, CheckedUInt64)からの代入はそのまま代入できる。符号付整数クラス(CheckedInt8, CheckedInt16, CheckedInt32, CheckedInt64)からの代入では負の値ならオーバーフロー(overflow)を設定する。それ以外はそのまま代入できる。
浮動小数点数クラス(CheckedFloat32, CheckedFloat64)からの代入は、負の値あるいは表現可能な最大値を超える値ならオーバーフロー(overflow)を、それ以外で小数部分があれば不正確(inaccurate)を設定する。また値が0x1.0p63以上のときは代入にあたって符号ビットを別扱いで処理する。
３．CheckedInt64型について
（１）値保持
CheckedInt64は64ビット幅を持つ符号付整数の型である。Ｊａｖａ言語のlong型変数は64ビット符号付整数なのでＪａｖａ言語のlong型変数valueに値を保持する。
（２）加算
加算(add)のフローチャートを図１３に示す。
addはCheckedNumber型で宣言されCheckedInt64で再定義されたメソッドで、2つの引数a,bはCheckedNumber型で宣言されるがCheckedInt64の値を持つ。これはシミュレーションモデルで保証できるのでフローチャートでは、型チェックと型変換の記述は省略する。
まず1301で引数a,bをそれぞれ下位63ビットと上位(符号)ビットに分けて、al、ah、bl、bhの変数に代入する。このとき上位は算術右シフトにより符号ビットが全てのビットにコピーされている。
【００４０】
次に1302で下位・上位それぞれの加算を計算する。下位の桁上がりは論理右シフトにより上位に1として加算される。
最後に1303で下位と上位を合成して加算結果を作り、上位が0ないし-1になる場合以外はオーバーフローを設定する。
（３）減算
減算(sub)のフローチャートを図１４に示す。
subはCheckedNumber型で宣言されCheckedInt64で再定義されたメソッドで、2つの引数a,bはCheckedNumber型で宣言されるがCheckedInt64の値を持つ。これはシミュレーションモデルで保証できるのでフローチャートでは、型チェックと型変換の記述は省略する。
まず1401で引数aを下位63ビットと上位(符号)ビットに分けて、al、ahの変数に代入する。このとき上位は算術右シフトにより符号ビットが全てのビットにコピーされている。さらに引数bを下位63ビットと上位(符号)ビットに分けて、bl、bhの変数に代入するが、このときbの値を-1倍している。
【００４１】
次に1402で下位・上位それぞれの加算を計算する。下位の桁上がりは論理右シフトにより上位に1として加算される。
最後に1403で下位と上位を合成して加算結果を作り、上位が0ないし-1になる場合以外はオーバーフローを設定する。
（４）乗算
乗算(mul)のフローチャートを図１５に示す。
mulはCheckedNumber型で宣言されCheckedInt64で再定義されたメソッドで、2つの引数a,bはCheckedNumber型で宣言されるがCheckedInt64の値を持つ。これはシミュレーションモデルで保証できるのでフローチャートでは、型チェックと型変換の記述は省略する。
まず1501で値a, bの符号をas, bsに取り出し、演算結果の符合rsを計算する。
【００４２】
次に1502で符号をチェックして、非負のとき1503でaの値のまま、負のときは1504で-1倍してavに取得する。
同様に1505〜1507でbの値を非負にしてbvに取得する。
次に1508でCheckedUInt64の乗算(CheckedUInt64.mul)と同様の演算を行って積rvとオーバーフロー状態ovを得る。これはCheckedUInt64の乗算と同様の演算を行うのであって、CheckedUInt64.mulを呼び出して行うというわけではない。演算の手順は同じなので記述は省略する。
【００４３】
次に1509では積rvがlongにおける負の最大値である場合を確認する。この場合、-1倍しても内部表現が変わらないためである。このとき1510で積rvをvalueに設定する。1511で結果の符合を調べて、負なら1512でオーバーフローを1508の結果で設定し、正ならCheckedInt64で表現できない値なのでオーバーフローに設定する。
【００４４】
積rvがlongにおける負の最大値ではないとき、1514で結果の符合を調べて、負なら1515で-rvを、正なら1516でrvをvalueに設定する。さらに1517で積rvの値が負(すなわちCheckedInt64で表現できない値)のとき1518でオーバーフローに設定し、そうでなければ1519でオーバーフローを1508の結果で設定する。
（５）除算・剰余
CheckedInt64の除算・剰余の計算は、Ｊａｖａ言語のlongの範囲内で実行できオーバーフローも発生しない。このため特別な工夫は必要なく、ここでは詳細の記載を省略する。
（６）論理演算・シフト演算
論理演算については、内部表現のlong値をそのまま演算すれば良い。
シフト演算についても左シフトは違いがないし、右シフトは算術右シフトを使用すれば良い。
これらの演算の詳細な処理は省略する。
（７）比較
比較(cmp)は、内部表現のlong値をそのまま比較すれば良い。ここでは詳細の記載を省略する。
（８）代入
符号付整数クラ(CheckedInt8, CheckedInt16, CheckedInt32, CheckedInt64)からの代入はそのまま代入できる。
【００４５】
非負整数(CheckedUInt8, CheckedUInt16, CheckedUInt32, CheckedUInt64)からの代入は、値がCheckedInt64で表現できる最大値を超える場合はオーバーフロー(overflow)を設定する。それ以外はそのまま代入できる。
浮動小数点数クラス(CheckedFloat32, CheckedFloat64)からの代入は、表現可能な最大値を超える値ならオーバーフロー(overflow)を、それ以外で小数部分があれば不正確(inaccurate)を設定する。
４．CheckedUInt32型について
（１）値保持
CheckedUInt32は32ビット幅を持つ非負整数の型である。Ｊａｖａ言語のlong型変数は64ビット符号付整数なのでＪａｖａ言語のlong型変数valueに値を保持する。
（２）加算・減算
32ビット非負整数の加算・減算の結果は高々33ビットで表現できるので、演算をＪａｖａ言語のlong型で行って、その後にCheckedUInt32の範囲内に入るかどうかを確認の上でオーバーフロー(overflow)を設定すれば良い。
これらの演算の詳細な処理は省略する。
（３）乗算
乗算(mul)のフローチャートを図１６に示す。
mulはCheckedNumber型で宣言されCheckedUInt32で再定義されたメソッドで、2つの引数a,bはCheckedNumber型で宣言されるがCheckedUInt32の値を持つ。これはシミュレーションモデルで保証できるのでフローチャートでは、型チェックと型変換の記述は省略する。
まず1601で引数a,bをそれぞれ下位30ビットと上位2ビットに分けて、al、ah、bl、bhの変数に代入する。
【００４６】
次に1602で下位・上位それぞれの乗算を計算する。このとき明らかにオーバーフローする組合せの乗算は計算しない。
最後に1603で下位と上位を合成して乗算結果を作り、上位が4を越える場合、および明らかにオーバーフローする組合せの乗算がゼロで無い場合にはオーバーフローを設定する。
（４）除算・剰余
CheckedUInt32の除算・剰余の計算は、Ｊａｖａ言語のlongの範囲内で実行できオーバーフローも発生しない。このため特別な工夫は必要なく、ここでは詳細の記載を省略する。
（５）論理演算・シフト演算
論理演算については、内部表現のlong値をそのまま演算すれば良い。
シフト演算についても左シフトは違いがないし、右シフトは算術右シフトを使用すれば良い。
これらの演算の詳細な処理は省略する。
（６）比較
比較(cmp)は、内部表現のlong値をそのまま比較すれば良い。ここでは詳細の記載を省略する。
（７）代入
自身以下の非負整数クラス(CheckedUInt8, CheckedUInt16, Checked
UInt32)からの代入はそのまま代入できる。
大きな非負整数クラス(CheckedUInt64)からの代入は値がCheckedUInt32で表現できる最大値を超える場合はオーバーフロー(overflow)を設定する。それ以外はそのまま代入できる。
自身より小さな符号付整数クラス(CheckedInt8, CheckedInt16, CheckedInt32)からの代入は負の値ならオーバーフロー(overflow)を設定する。それ以外はそのまま代入できる。
【００４７】
大きな符号付整数クラス(CheckedInt64)からの代入は、負の値の場合、あるいは値がCheckedUInt32で表現できる最大値を超える場合はオーバーフロー(overflow)を設定する。それ以外はそのまま代入できる。
浮動小数点数クラス(CheckedFloat32, CheckedFloat64)からの代入は、表現可能な最大値を超える値ならオーバーフロー(overflow)を、それ以外で小数部分があれば不正確(inaccurate)を設定する。
５．CheckedInt32, CheckedInt16, CheckedInt8, CheckedUInt16, CheckedUInt8型について
（１）値保持
CheckedInt32, CheckedInt16, CheckedInt8, CheckedUInt16, 
CheckedUInt8は高々32ビット符号付整数で値を保持できる。Ｊａｖａ言語のlong型変数は64ビット符号付整数なのでＪａｖａ言語のlong型変数valueに値を保持する。
（２）加算・減算・乗算・除算・剰余・論理演算・シフト演算
全てＪａｖａ言語のlong型の範囲内で計算できる。他は明らかなのでCheckedInt32の乗算について確認する。
CheckedInt32で表現できる絶対値が最大の数は-231である。この数2つの積は262となり63ビットで表現できる。
これらの演算の詳細な処理は省略する。
（３）比較
比較(cmp)は、内部表現のlong値をそのまま比較すれば良い。ここでは詳細の記載を省略する。
（４）代入
それぞれ、より範囲の狭い整数クラスからの代入はそのまま代入できる。
同じサイズで符号付符号なしが異なる場合や、より範囲の広い整数クラスからの代入については、表現できる範囲外になればオーバーフロー(overflow)を設定する。それ以外はそのまま代入できる。
浮動小数点数クラス(CheckedFloat32, CheckedFloat64)からの代入は、表現可能な最大値を超える値ならオーバーフロー(overflow)を、それ以外で小数部分があれば不正確(inaccurate)を設定する。
６．CheckedFloat64型について
（１）値保持
Ｊａｖａ言語のdouble型で表現できるので、double型変数valueに値を保持する。
（２）加算・減算
演算はＪａｖａ言語のdouble型の計算で良い。
範囲判定としては、大きさが同じ数の差になる場合を除き、演算結果が非正規数になればアンダーフロー(underflow)とする。また、演算結果が無限大になればオーバーフロー(overflow)とする。
（３）乗算
演算はＪａｖａ言語のdouble型の計算で良い。
範囲判定としては、引数のどちらがかゼロの場合を除いて演算結果が非正規数になればアンダーフロー(underflow)とする。また、演算結果が無限大になればオーバーフロー(overflow)とする。
（４）除算
演算はＪａｖａ言語のdouble型の計算で良い。
範囲判定としては、被除数がゼロでなく除数が無限大でないのに演算結果が非正規数になればアンダーフロー(underflow)とする。また、演算結果が無限大になればオーバーフロー(overflow)とする。
（５）比較
比較(cmp)は、内部表現のdouble値をそのまま比較すれば良い。ここでは詳細の記載を省略する。
（６）代入
表現範囲の狭い整数クラス(CheckedUInt8, CheckedUInt16, CheckedUInt32, CheckedInt8, CheckedInt16, CheckedInt32)からの代入はそのまま代入すれば良い。
表現範囲の広い整数クラス(CheckedUInt64, CheckedInt64)からの代入では、整数値が大きくて有効数字が足りなくなる場合に不正確(inaccurate)を設定する。それ以外はそのまま代入すれば良い。
浮動小数点数クラス(CheckedFloat32)からの代入はそのまま代入すれば良い。
７．CheckedFloat32型について
（１）値保持
Ｊａｖａ言語のfloat型で表現できるので、float型変数valueに値を保持する。
（２）加算・減算
演算はＪａｖａ言語のdouble型の計算で良い。引数をdoubleに変換して計算し、結果をfloatに変換して格納する。
範囲判定としては、大きさが同じ数の差になる場合を除き、演算結果が非正規数になればアンダーフロー(underflow)とする。また、演算結果が無限大になればオーバーフロー(overflow)とする。
（３）乗算
演算はＪａｖａ言語のdouble型の計算で良い。引数をdoubleに変換して計算し、結果をfloatに変換して格納する。
範囲判定としては、引数のどちらがかゼロの場合を除いて演算結果が非正規数になればアンダーフロー(underflow)とする。また、演算結果が無限大になればオーバーフロー(overflow)とする。
（４）除算
演算はＪａｖａ言語のdouble型の計算で良い。引数をdoubleに変換して計算し、結果をfloatに変換して格納する。
範囲判定としては、被除数がゼロでなく除数が無限大でないのに演算結果が非正規数になればアンダーフロー(underflow)とする。また、演算結果が無限大になればオーバーフロー(overflow)とする。
（５）比較
比較(cmp)は、内部表現のfloat値をそのまま比較すれば良い。ここでは詳細の記載を省略する。
（６）代入
表現範囲の狭い整数クラス(CheckedUInt8, CheckedUInt16, CheckedInt8, CheckedInt16)からの代入はそのまま代入すれば良い。
表現範囲の広い整数クラス(CheckedUInt64, CheckedUInt32, CheckedInt64, CheckedInt32)からの代入では、整数値が大きくて有効数字が足りなくなる場合に不正確(inaccurate)を設定する。それ以外はそのまま代入すれば良い。
浮動小数点数クラス(CheckedFloat64)からの代入は有向桁数が足りない場合に不正確(inaccurate)を設定する。それ以外はそのまま代入すれば良い。
【００４８】
以上のように、本発明は、シミュレーション装置にシミュレーションモデル型ごと演算選択機能１６を設ける共に、シミュレーション演算機能１１´に型ごとの数値範囲チェック付演算手段を設け、この数値範囲チェック付演算手段により、演算結果の範囲チェック付き演算クラス・インスタンスに属する演算メソッドを、オペランドの範囲チェック付演算クラス・インスタンスを引数に呼び出してシミュレーション演算を行うものである。これによって、プログラムの動作において大きな時間を使うオブジェクト生成・削除の処理が大幅に減らせ、また無駄な演算を削減することができる。これらにより、演算クラスを例えばＪａｖａ言語標準ライブラリの多倍長演算クラスjava.math.BigDecimalのような多倍長演算が可能な型を利用した場合と比べて、演算部分については十数倍から数十倍、シミュレーション全体としても数倍から十数倍の高速実行が可能となる。
【符号の説明】
【００４９】
１…  ブロックデータベース
２…  シミュレーションモデル作成機能
３…  演算対象関連付け機能
４…  ブロック図情報関連付け機能
７…  シミュレーションモデル実行機能
９…  シミュレーションモデル初期値設定機能
１０…  シミュレーションモデル値取得機能
１１´…  シミュレーションモデル演算機能
１２…  演算結果データベース
１３…  シミュレーションモデル演算結果保存機能
１４…  演算結果値取得機能
１５…  演算結果表示機能
１６…  シミュレーションモデル型ごと演算選択機能
【図１】
0006339756.tif 000002
【図２】
0006339756.tif 000003
【図３】
0006339756.tif 000004
【図４】
0006339756.tif 000005
【図５】
0006339756.tif 000006
【図６】
0006339756.tif 000007
【図７】
0006339756.tif 000008
【図８】
0006339756.tif 000009
【図９】
0006339756.tif 000010
【図１０】
0006339756.tif 000011
【図１１】
0006339756.tif 000012
【図１２】
0006339756.tif 000013
【図１３】
0006339756.tif 000014
【図１４】
0006339756.tif 000015
【図１５】
0006339756.tif 000016
【図１６】
0006339756.tif 000017
【図１７】
0006339756.tif 000018