コンフィギュレータ・ルールでの整数値および小数値の使用
コンフィギュレータ・ルールで整数値と小数値をどのように使用するかを検討します。
ルールの整数値を乗算した結果がJavaの整数制限を超えないようにする必要があります。 制約定義言語(CDL)は、JavaのDoubleデータ型を使用して10進値を格納します。 Doubleは、JavaのIntegerデータ型よりもはるかに高い制限値を持っています。 場合によっては、CDLで作成したルールによって、整数の制限を超える値が生成されることがあります。
コンフィギュレータ・ルールの数学演算の結果は、各オペランドのデータ型によって異なります。 各オペランドが整数であり、演算子の後の値が定数整数である場合、または整数値を含む属性を参照する場合、結果は整数になります。
シナリオ
あるシナリオについて考えてみます。
IntegerFeature (min = 0, max = 2,147,483,647)
DecimalFeature (min = 0, max = 999,999,999,999,999)
ルールにこのロジックがあるとします。
IntegerFeature * 400,000 = DecimalFeature
値がIntegerFeatureの範囲に残っているかぎり、IntegerFeatureに任意の値を指定できると想定し、乗算の結果をDecimalFeatureに格納できます。
ただし、IntegerFeatureおよび定数値400,000はそれぞれ整数で、400,000は演算子の後であるため、乗算の結果は10進数ではなく整数である必要があり、IntegerFeatureの最大値を超えてはなりません。 実行時に、IntegerFeatureを5,368を超える値に設定すると、エラーが発生します。
ランタイム計算 | 結果 |
---|---|
5,368を400,000で乗算すると、2,147,200,000と等しくなります。 | 2,147,200,000はIntegerFeatureの最大値2,147,483,647より小さいため、行くのがよいです。 |
5,369を400,000で乗算すると、2,147,600,000と等しくなります。 | 2,147,600,000はIntegerFeatureの最大2,147,483,647を超えるため、エラーが発生します。 |
ソリューション
オペランドを小数に変換
たとえば、400,000を400,000.0に変更します:
IntegerFeature * 400,000.0 = DecimalFeature
IntegerFeature * 1.00000001
小数機能または補足属性の使用
演算子の後に単純な定数または10進値を使用できない場合は、整数機能のかわりに小数機能を使用することを検討してください。
IntegerFeature * m1.suppAttrs["IntegerAttribute"] = DecimalFeature
その他の選択肢
コード | 説明 |
---|---|
|
SQRT関数は小数を返します。
|
(IntegerFeature * 1.00000001)) * m1.suppAttrs["IntegerAttribute"] =DecimalFeature |
1.00000001定数は10進数です。 |
オペランドの順序の変更
上記の解決策がうまくいかない場合は、オペランドのシーケンスを変更できます。 この問題は、演算子の後ろの値が静的である場合にのみ発生するため、その値を演算子の前に移動できます:
m1.suppAttrs["IntegerAttribute"] * IntegerFeature = DecimalFeature
より複雑な例を次に示します:
Add &x.Quantity() * &x.suppAttrs["IntegerAttribute"] To DecimalFeature FOR
ALL &x IN {OptionClass.Options()}
これをリライトすると、問題を回避できます:
Add (&x.Quantity() * SQRT(1)) * &x.suppAttrs["IntegerAttribute"] To
DecimalFeature FOR ALL &x IN {OptionClass.Options()}
または、次のように書き換えます:
Add &x.suppAttrs["IntegerAttribute"] * &x.Quantity() To DecimalFeature FOR
ALL &x IN {OptionClass.Options()}
この問題は、整数オペランドを乗算して結果が10進数にオーバーフローした場合にのみ発生します。 オーバーフローが発生しない場合、オペランドに使用するシーケンスは問題になりません。