5.6.9.3 Arithmetic Operators
Arithmetic operators are simple data operators that perform numerical computations on their operands.
-
arithmetic-operator-expression = unary-minus-operator-expression / addition-operator-expression / subtraction-operator-expression / multiplication-operator-expression / division-operator-expression / integer-division-operator-expression / modulo-operator-expression / exponentiation-operator-expression
Static semantics. Arithmetic operators are statically resolved as simple data operators.
An arithmetic operator is invalid if the declared type of any operand is an array or a UDT.
For unary arithmetic operators, unless otherwise specified in the specific operator’s section, the operator has the following declared type, based on the declared type of its operand:
Operand Declared Type |
Operator Declared Type |
---|---|
Byte |
Byte |
Boolean or Integer |
Integer |
Long |
Long |
LongLong |
LongLong |
Single |
Single |
Double, String or String * length |
Double |
Currency |
Currency |
Date |
Date |
Variant |
Variant |
For binary arithmetic operators, unless otherwise specified in the specific operator’s section, the operator has the following declared type, based on the declared type of its operands:
Left Operand Declared Type |
Right Operand Declared Type |
Operator Declared Type |
---|---|---|
Byte |
Byte |
Byte |
Boolean or Integer |
Byte, Boolean or Integer |
Integer |
Byte, Boolean or Integer |
Boolean or Integer |
Integer |
Long |
Byte, Boolean, Integer or Long |
Long |
Byte, Boolean, Integer or Long |
Long |
Long |
LongLong |
Any integral numeric type |
LongLong |
Any integral numeric type |
LongLong |
LongLong |
Single |
Byte, Boolean, Integer or Single |
Single |
Byte, Boolean, Integer or Single |
Single |
Single |
Single |
Long or LongLong |
Double |
Long or LongLong |
Single |
Double |
Double, String or String * length |
Any integral or floating-point numeric type, String or String * length |
Double |
Any integral or floating-point numeric type, String or String * length |
Double, String or String * length |
Double |
Currency |
Any numeric type, String or String * length |
Currency |
Any numeric type, String or String * length |
Currency |
Currency |
Date |
Any numeric type, String, String * length or Date |
Date |
Any numeric type, String, String * length or Date |
Date |
Date |
Any type except an array or UDT |
Variant |
Variant |
Variant |
Any type except an array or UDT |
Variant |
Runtime semantics:
§ Arithmetic operators are first evaluated as simple data operators.
§ If the value type of any operand is an array, UDT or Error, runtime error 13 (Type mismatch) is raised.
§ Before evaluating the arithmetic operator, its non-Null operands undergo Let-coercion to the operator’s effective value type.
§ For unary arithmetic operators, unless otherwise specified, the effective value type is determined as follows, based on the value type of the operand:
Operand Value Type |
Effective Value Type |
---|---|
Byte |
Byte |
Boolean or Integer or Empty |
Integer |
Long |
Long |
LongLong |
LongLong |
Single |
Single |
Double or String |
Double |
Currency |
Currency |
Date |
Date (however, the operand is Let-coerced to Double instead) |
Decimal |
Decimal |
Null |
Null |
§ For binary arithmetic operators, unless otherwise specified, the effective value type is determined as follows, based on the value types of the operands:
Left Operand Value Type |
Right Operand Value Type |
Effective Value Type |
---|---|---|
Byte |
Byte or Empty |
Byte |
Byte or Empty |
Byte |
Byte |
Boolean or Integer |
Byte, Boolean, Integer or Empty |
Integer |
Byte, Boolean, Integer or Empty |
Boolean or Integer |
Integer |
Empty |
Empty |
Integer |
Long |
Byte, Boolean, Integer, Long or Empty |
Long |
Byte, Boolean, Integer, Long or Empty |
Long |
Long |
LongLong |
Any integral numeric type or Empty |
LongLong |
Any integral numeric type or Empty |
LongLong |
LongLong |
Single |
Byte, Boolean, Integer, Single or Empty |
Single |
Byte, Boolean, Integer, Single or Empty |
Single |
Single |
Single |
Long or LongLong |
Double |
Long or LongLong |
Single |
Double |
Double or String |
Any integral or floating-point numeric type, String or Empty |
|
Any integral or floating-point numeric type, String or Empty |
Double or String |
|
Currency |
Any integral or floating-point numeric type, Currency, String or Empty |
Currency |
Any integral or floating-point numeric type, Currency, String or Empty |
Currency |
Currency |
Date |
Any integral or floating-point numeric type, Currency, String, Date or Empty |
Date (however, the operands are Let-coerced to Double instead) |
Any integral or floating-point numeric type, Currency, String, Date or Empty |
Date |
Date (however, the operands are Let-coerced to Double instead) |
Decimal |
Any numeric type, String, Date or Empty |
Decimal
|
Any numeric type, String, Date or Empty |
Decimal |
Decimal
|
Null |
Any numeric type, String, Date, Empty, or Null |
Null |
Any numeric type, String, Date, Empty, or Null |
Null |
Null |
Error |
Error |
Error |
Error |
Any type except Error |
Runtime error 13 (Type mismatch) is raised. |
Any type except Error |
Error |
Runtime error 13 (Type mismatch) is raised. |
The value type of an arithmetic operator is determined from the value the operator produces, the effective value type and the declared type of its operands as follows:
If the arithmetic operator produces a value within the valid range of its effective value type, the operator’s value type is its effective value type.
Otherwise, if the arithmetic operator produces a value outside the valid range of its effective value type, arithmetic overflow occurs. The behavior of arithmetic overflow depends on the declared types of the operands:
If neither operand has a declared type of Variant, runtime error 6 (Overflow) is raised.
If one or both operands have a declared type of Variant:
If the operator’s effective value type is Integer, Long, Single or Double, the operator’s value type is the narrowest type of either Integer, Long or Double such that the operator value is within the valid range of the type. If the result does not fit within Double, runtime error 6 (Overflow) is raised.
If the operator’s effective value type is LongLong, runtime error 6 (Overflow) is raised.
If the operator’s effective value type is Date, the operator’s value type is Double. If the result does not fit within Double, runtime error 6 (Overflow) is raised.
If the operator’s effective value type is Currency or Decimal, runtime error 6 (Overflow) is raised.
The operator’s result value is Let-coerced to this value type.
Arithmetic operators with an effective value type of Single or Double perform multiplication, floatingpoint division and exponentiation according to the rules of IEEE 754 arithmetic, which can operate on or result in special values such as positive infinity, negative infinity, positive zero, negative zero or NaN (not a number).
An implementation can choose to perform floating point operations with a higher-precision than the effective value type (such as an "extended" or "long double" type) and coerce the resulting value to the destination declared type. This can be done for performance reasons as some processors are only able to reduce the precision of their floating-point calculations at a severe performance cost.