Type conversion: Floating-point and integer

The programming language Chora supports different data types to represent numerical operands. We distinguish between signed and unsigned integer data types (each with 8-, 16-, 32- or 64-bit precision) and the floating-point data type. In order to convert between integer and floating-point data types, a set of adequate floating-point to integer and one integer to floating-point conversion operators are available.

Syntax

Floating-point to integer conversion:

(int64)float‑operandorint64(float‑operand)

(int32)float‑operandorint32(float‑operand)

(int16)float‑operandorint16(float‑operand)

(int8)float‑operandorint8(float‑operand)

(uint64)float‑operandoruint64(float‑operand)

(uint32)float‑operandoruint32(float‑operand)

(uint16)float‑operandoruint16(float‑operand)

(uint8)float‑operandoruint8(float‑operand)

Integer to floating-point conversion:

(float)integer‑operandorfloat(integer‑operand)

Discussion

The floating-point to integer conversion operator converts the given float operand to a signed or unsigned integer data type. In practice, the conversion is performed in two steps. First the floating-point value is rounded to the next lower integer value. Then the integer conversion operation is applied on this value in order to convert it to the final destination data type.

Generally, this conversion results in a value with lower precision than the of the original floating-point value. Depending on the operand original content, the conversion may lead to the loss of information provided in it. Precisely, the integer conversion to a data type with lower rank or the conversion between signed and unsigned data types result in the integer value highest bits being truncated or reinterpreted.

In simple terms, if the value stored originally in the floating-point operand doesn't fit in the destination integer data type, the value resulting from the conversion will differ from the expected value. In the following example you see two float operands. While the value in the operand a1 is small enough to be converted in the int8 data type, the value in operand a2 doesn't fit in it and its conversion results in a completely different value:

var float a1 =  125.0;
var float a2 = -1251.69;

var int32 b1 = (int32)a1;  // b1 =  125
var int32 b2 = (int32)a2;  // b2 = -1251 (hex 0xFB1D)

var int8  b3 = (int8)a1;   // b3 =  125
var int8  b4 = (int8)a2;   // b4 =  29   (hex 0x1D)

The integer to floating-point conversion operator converts the given signed or unsigned integer operand to a float data type. Since the resolution of a floating-point operand depends on its values, this conversion may lead to the loss of precision. In particular large integer values can't be represented exactly by float. In the following example, the integer value a1 is small enough to be converted in the floating-point without losing the precision. In turn, the second operand a2 has no corresponding floating-point representation and is rounded from 33554419 to 33554420:

var int32 a1 = 3554419;
var int32 a2 = 33554419;

var float b1 = (float)a1; // b1 = 3554419.0
var float b2 = (float)a2; // b2 = 33554420.0

Explicit conversion

With the explicit conversion operator you specify explicitly how an operand should be treated within the implemented expression. Chora supports two equivalent notation variants how you can apply the conversion operators. In the first variant the destination data type is specified between a pair of (...) (parentheses). The second notation variant corresponds to a constructor invocation of the respective destination data type:

var int32 a = 1369;
var int32 b = 1251;

// Notation 1
var float c1 = (float)( a + b );

// Notation 2
var float c2 = float( a + b );

trace c1 == c2; // true

The explicit type conversion is performed with the above described side effects. Applying the conversion on an operand not fitting the destination data type will thus result in the original operand value being truncated, its sign being lost or its precision reduction. Since you apply the operation consciously, the Chora compiler will not report any warning nor error in such case.

Implicit conversion

Wherever it is not ambiguous, the Chora compiler applies the necessary type conversion implicitly. This is usually the case when you assign the result of an expression to e.g. a variable or you pass it as parameter in a method invocation. In such cases the Chora compiler can derive from the destination operand the corresponding data type and decide whether or not to convert the expression. For example, the following assignment implies the conversion to uint8 data type since the destination operand is the red instant property declared with uint8 as data type:

var float a   = 167.13;
var color clr = #00000000;

// Apply an implicit conversion from 'float' to 'uint8'
clr.red = a;  // clr.red = 167

If the applied implicit type conversion has potential side effects, the Chora compiler will report a warning giving you a chance to review the affected expression. To avoid the warning you can extend the expression by an additional explicit type conversion operator: