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.