Use Integer Values and Decimal Values in Configurator Rules
Consider how your configurator rule uses integer values and decimal values.
You must make sure that the result of multiplying integer values in your rule doesn't exceed Java's integer limit. Constraint Definition Language (CDL) uses Java's Double data type to store a decimal value. Double has a much higher limit than Java's Integer data type. In some cases, a rule that you create in CDL might result in a value that exceeds the integer's limit.
The result of a mathematical operation in a configurator rule depends on each operand's data type. If each of your operands are an integer, and if the value after the operator is a constant integer, or if it references an attribute that contains an integer value, then the result will be an integer.
Scenario
Consider a scenario.
IntegerFeature (min = 0, max = 2,147,483,647)
DecimalFeature (min = 0, max = 999,999,999,999,999)
Assume you have this logic in your rule.
IntegerFeature * 400,000 = DecimalFeature
You might assume that you can specify any value for IntegerFeature as long as that value remains in IntegerFeature's range, and then store the result of your multiplication in DecimalFeature.
However, IntegerFeature and the constant value of 400,000 are each an integer, 400,000 is after the operator, so the result of the multiplication must be an integer, not a decimal, and it must not exceed IntegerFeature's maximum value. At runtime, if you set IntegerFeature to a value that exceeds 5,368, you'll have an error.
Runtime Math | Result |
---|---|
5,368 multiplied by 400,000 equals 2,147,200,000. | 2,147,200,000 is less than IntegerFeature's 2,147,483,647 maximum, so you're good to go. |
5,369 multiplied by 400,000 equals 2,147,600,000. | 2,147,600,000 exceeds IntegerFeature's 2,147,483,647 maximum, so you'll have an error. |
Solutions
Convert an Operand to a Decimal
For example, change 400,000 to 400,000.0:
IntegerFeature * 400,000.0 = DecimalFeature
IntegerFeature * 1.00000001
Use a Decimal Feature or Supplemental Attribute
If you can't use a simple constant or a decimal value after the operator, then consider using a decimal feature instead of an integer feature.
IntegerFeature * m1.suppAttrs["IntegerAttribute"] = DecimalFeature
Other Alternatives
Code | Description |
---|---|
|
The SQRT function will return a decimal.
|
(IntegerFeature * 1.00000001)) *
m1.suppAttrs["IntegerAttribute"]
=DecimalFeature |
The 1.00000001 constant is a decimal. |
Modify the Sequence of Your Operands
If the solutions that we describe above don't work for you, then you can modify the sequence of your operands. The problem happens only when the value after the operator is static, so you can move that value to before the operator:
m1.suppAttrs["IntegerAttribute"] * IntegerFeature = DecimalFeature
Here's a more complex example:
Add &x.Quantity() * &x.suppAttrs["IntegerAttribute"] To DecimalFeature FOR
ALL &x IN {OptionClass.Options()}
You can rewrite it to avoid the problem:
Add (&x.Quantity() * SQRT(1)) * &x.suppAttrs["IntegerAttribute"] To
DecimalFeature FOR ALL &x IN {OptionClass.Options()}
Or, rewrite it this way:
Add &x.suppAttrs["IntegerAttribute"] * &x.Quantity() To DecimalFeature FOR
ALL &x IN {OptionClass.Options()}
The problem happens only when you multiply integer operands and the result overflows into a decimal. If the overflow doesn’t happen, then the sequence that you use for the operands doesn’t matter.