Introduction

Type conversion includes implicit and explicit conversion. Implicit conversion is automatically performed by the system when types do not match. Explicit conversion is proactively performed by calling the type conversion API. The API converts the input data from the source type to the target type and returns the conversion result. The entire conversion process complies with the specified processing rules. The conversion result is affected by the rounding mode and saturation behavior. For details about the representation modes and rounding rules of floating-point numbers, see Function Usage.

Implicit Conversion

Implicit conversion refers to the behavior that the system automatically converts data from the source type to the target type without explicitly specifying the target type.

The following is an example of implicit conversion.
1
2
int32_t a;
a = 2.2f; // a = 2
Table 1 Implicit conversion rules

Input Data Type

Output Data Type

Rounding Rules and Special Values

Integer

int8_t/uint8_t/int16_t/uint16_t/int32_t/uint32_t/int64_t/uint64_t

Integer

int8_t/uint8_t/int16_t/uint16_t/int32_t/uint32_t/int64_t/uint64_t

Rounding complies with CAST_TRUNC.

Floating-point variable

float

Integer

int32_t/uint32_t/int64_t/uint64_t

Rounding complies with CAST_TRUNC.

When wide-range data is converted to narrow-range data:

  • If the input is +inf or greater than the maximum value that can be represented by this type, the conversion result is the maximum value.
  • If the input is -inf or less than the minimum value that can be represented by this type, the conversion result is the minimum value.
  • If the input is nan, the conversion result is 0.

half

int32_t/uint32_t

bfloat16_t

int32_t/uint32_t

Integer

int32_t

Floating-point variable

float/half/bfloat16_t

Rounding complies with CAST_RINT.

When wide-range data is converted to narrow-range data:

  • If the input is out of the range that can be represented by this type, the conversion result is the inf value of the corresponding sign.

uint32_t

float/half/bfloat16_t

int64_t

float

uint64_t

float

Floating-point variable

float

Floating-point variable

half/bfloat16_t

Rounding complies with CAST_RINT.

When wide-range data is converted to narrow-range data:

  • If the input is out of the range that can be represented by this type, the conversion result is the inf value of the corresponding sign.
  • If the input is nan, the conversion result is nan.

half

float/bfloat16_t

bfloat16_t

float/half

Example implicit conversions are as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// Convert int8_t to uint8_t.
int8_t a = -100;
uint8_t b = a; // b = 156

// Convert half to int32_t.
half a = 60000.6;
int32_t b = a; // b = 60000

// Convert int32_t to half.
int32_t a = 100000;
half b = a; // b = inf, 100000 is out of the range that can be represented by the half type.

// Convert float to half.
float a = -100000.0f;
half b = a; // b = -inf, -100000.0f is out of the range that can be represented by the half type.

Rounding Mode

The rounding mode controls how the precision loss is handled during conversions.

Table 2 Rounding modes supported by type conversion APIs

Rounding Mode

Description

API Name Format

CAST_RINT

Rounding to the nearest even number (banker's rounding)

srctype2dsttype_rn

CAST_FLOOR

Rounding down

SrcType2DstType_rd

CAST_CEIL

Rounding up

srctype2dsttype_ru

CAST_ROUND

Rounding off

srctype2dsttype_rna

CAST_TRUNC

Rounding towards zero

srctype2dsttype_rz

CAST_ODD

Rounding to the nearest odd number

srctype2dsttype_ro

CAST_HYBRID

Hybrid rounding mode. This stochastic rounding mode is currently used exclusively when the output is of hi8 type.

srctype2dsttype_rh

This table describes the API name format corresponding to each input mode. In the format, srctype indicates the source operand type, and dsttype indicates the output target type. For example, if the float type is converted to the half type and the CAST_RINT mode is used for rounding, the API name is __float2half_rn.

Saturation Behavior

The saturation behavior controls how the special values such as nan and inf, and the results that are out of the representable range of the target type are handled.

Table 3 Description of saturation behaviors

Mode

Description

API Name Format

Non-saturation mode

Default mode.

  • If the input is out of the range that can be represented by this type, the conversion result is the inf value of the corresponding sign.
  • If the input is nan, the conversion result is nan.

srctype2dsttype_r[xx]

Saturation mode

In saturation mode:

  • If the input is +inf or greater than the maximum value that can be represented by this type, the conversion result is the maximum value.
  • If the input is -inf or less than the minimum value that can be represented by this type, the conversion result is the minimum value.
  • If the input is nan, the conversion result is 0.

srctype2dsttype_r[xx]_sat

Methods of Controlling Saturation Behaviors

The saturation behavior is controlled by bit[60] and bit[48] of the CTRL register and API functions. For details about how to set the CTRL register in SIMD and SIMT programming scenarios, see SetCtrlSpr(ISASI). For SIMT programming, the CTRL register is not supported.

When wide-range data is converted to narrow-range data and the target type of the conversion is not float, including conversions such as float to half, float to bfloat16_t, bfloat16_t to half, and float or half to hifloat8_t, fp8_e4m3fn_t, or fp8_e5m2_t, the saturation behavior of the API is affected by bit[60] and bit[48] of the hardware register CTRL. The specific behaviors are as follows:

  • When bit[60] of the CTRL register is 0, the saturation behavior is independently controlled by the API.
    • The conversion result of the API with the suffix __sat is in saturation mode.
    • The conversion result of the API without the suffix __sat is in non-saturation mode.
  • When bit[60] of the CTRL register is 1, the saturation behavior is globally controlled by bit[48] of the CTRL register.
    • When bit [48] of the CTRL register is 1, the conversion result of the API is in non-saturation mode.
    • When bit[48] of the CTRL register is 0, the conversion result of the API is in saturation mode.
Table 4 Final saturation behavior of converting wide-range data to narrow-range data

Bit[60] of CTRL

Bit[48] of CTRL

API Name Format

Final Saturation Behavior

0

/

Without __sat

Non-saturation

1

1

/

Non-saturation

0

/

__sat

Saturation

1

0

/

Saturation

The saturation behavior is only controlled by bit[48] of the CTRL register in the following two scenarios:

  • Conversion from narrow-range data to wide-range data, where the target operand type is not float, that is, conversion from half to bfloat16_t and from hifloat8_t to half.
  • Conversion from half to half and from bfloat16_t to bfloat16_t.

The specific behaviors are as follows:

  • When bit [48] of the CTRL register is 1, the conversion result of the API is in non-saturation mode.
  • When bit[48] of the CTRL register is 0, the conversion result of the API is in saturation mode.
Table 5 Final saturation behavior of converting narrow-range data to wide-range data and converting data of the same type

Bit[60] of CTRL

Bit[48] of CTRL

Final Saturation Behavior

/

1

Non-saturation

/

0

Saturation

If the target type is float, all type conversion APIs only support the non-saturation mode. When a floating-point number is converted to an integer, the conversion result is in saturation mode.

Examples of Data Type Conversion Rules

Table 6 Examples of precision conversion rules

Input Data Type

Output Data Type

Example of Precision Conversion Rule

float

float

Rounds src based on the rounding mode (a precision conversion mode, see Table 2) and saves the result in float format in dst.

For example, in the case of input 0.5:

The output is 0.0 in CAST_RINT mode, 0.0 in CAST_FLOOR mode, 1.0 in CAST_CEIL mode, 1.0 in CAST_ROUND mode, and 0.0 in CAST_TRUNC mode.

half

Example 1: For input 0.5 + 2-12, it is represented as 2-1 * (1 + 2-11) in float type, meaning that E = –1 + 127 = 126, and M = 2-11.

The exponent bits of the half type can represent 2-1, meaning E = –1 + 15 = 14. However, the half type has only 10 mantissa bits. Therefore, rounding is required.

In CAST_RINT mode, the result mantissa is 0000000000, E = 14, and M = 0. The final result is 0.5.

In CAST_FLOOR mode, the result mantissa is 0000000000, E = 14, and M = 0. The final result is 0.5.

In CAST_CEIL mode, the result mantissa is 0000000001, E = 14, and M = 2-10. The final result is 0.5 + 2-11.

In CAST_ROUND mode, the result mantissa is 0000000001, E = 14, and M = 2-10. The final result is 0.5 + 2-11.

In CAST_TRUNC mode, the result mantissa is 0000000000, E = 14, and M = 0. The final result is 0.5.

In CAST_ODD mode, the result mantissa is 0000000001, E = 14, and M = 2-10. The final result is 0.5 + 2-11.

For details about the final saturation behavior of float-to-half conversion, see Table 4.

Example 2: For input inf, the output is 65504 in saturation mode, and inf in non-saturation mode.

Example 3: For input -inf, the output is -65504 in saturation mode, and -inf in non-saturation mode.

Example 4: For input nan, the output is 0 in saturation mode, and nan in non-saturation mode.

bfloat16_t

Example 1: For input 0.5 + 2-9 + 2-11, it is represented as 2–1 * (1 + 2–8 + 2–10) in float format, meaning that E = –1 + 127 = 126 and M = 2–8 + 2–10.

The number of exponent bits of bfloat16_t is the same as that of float, that is, E = 126. However, bfloat16_t has only 7 mantissa bits. Therefore, rounding is required.

In CAST_RINT mode, the result mantissa is 0000001, E = 126, and M = 2–7. The final result is 0.5 + 2–8.

In CAST_FLOOR mode, the result mantissa is 0000000, E = 126, and M = 0. The final result is 0.5.

In CAST_CEIL mode, the result mantissa is 0000001, E = 126, and M = 2–7. The final result is 0.5 + 2–8.

In CAST_ROUND mode, the result mantissa is 0000001, E = 126, and M = 2–7. The final result is 0.5 + 2–8.

In CAST_TRUNC mode, the result mantissa is 0000000, E = 126, and M = 0. The final result is 0.5.

For details about the final saturation behavior of float-to-bfloat16_t conversion, see Table 4.

Example 2: For input inf, the output is about 3.39*1038 in saturation mode, and inf in non-saturation mode.

Example 3: For input -inf, the output is about -3.39*1038 in saturation mode, and -inf in non-saturation mode.

Example 3: For input nan, the output is 0 in saturation mode, and nan in non-saturation mode.

int32_t

Example 1: For input 222 + 0.5, the output is 222 in CAST_RINT mode, 222 in CAST_FLOOR mode, 222 + 1 in CAST_CEIL mode, 222 + 1 in CAST_ROUND mode, and 222 in CAST_TRUNC mode.

Example 2: For input inf, the output is 231-1.

Example 3: For input -inf, the output is 2-31.

Example 4: For input nan, the output is 0.

uint32_t

Example 1: For input 222 + 0.5, the output is 222 in CAST_RINT mode, 222 in CAST_FLOOR mode, 222 + 1 in CAST_CEIL mode, 222 + 1 in CAST_ROUND mode, and 222 in CAST_TRUNC mode.

Example 2: For input inf, the output is 232-1.

Example 3: For input -inf, the output is 0.

Example 4: For input nan, the output is 0.

int64_t

Example 1: For input 222 + 0.5, the output is 222 in CAST_RINT mode, 222 in CAST_FLOOR mode, 222 + 1 in CAST_CEIL mode, 222 + 1 in CAST_ROUND mode, and 222 in CAST_TRUNC mode.

Example 2: For input inf, the output is 232-1.

Example 3: For input -inf, the output is 0.

Example 4: For input nan, the output is 0.

uint64_t

Example 1: For input 222 + 0.5, the output is 222 in CAST_RINT mode, 222 in CAST_FLOOR mode, 222 + 1 in CAST_CEIL mode, 222 + 1 in CAST_ROUND mode, and 222 in CAST_TRUNC mode.

Example 2: For input inf, the output is 264-1.

Example 3: For input -inf, the output is 0.

Example 4: For input nan, the output is 0.

hifloat8_t

Rounds src based on the rounding mode and saves the result in hifloat8_t format in dst (the overflow part is saturated).

For example, if the input is 1.75, the output is 2 in CAST_ROUND mode. For details about the output in CAST_HYBRID mode, see Table 9.

fp8_e4m3fn_t

Rounds src based on the rounding mode and saves the result in fp8_e4m3fn_t format in dst (the overflow part is saturated).

For example, if the input is 2.5, the output is 2 in CAST_RINT mode.

fp8_e5m2_t

Rounds src based on the rounding mode and saves the result in fp8_e5m2_t format in dst (the overflow part is saturated).

For example, if the input is 2.5, the output is 2 in CAST_RINT mode.

half

half

Rounds src based on the rounding mode and saves the result in half format in dst.

For example, in the case of input 0.5:

The output is 0.0 in CAST_RINT mode, 0.0 in CAST_FLOOR mode, 1.0 in CAST_CEIL mode, 1.0 in CAST_ROUND mode, and 0.0 in CAST_TRUNC mode.

float

There is no precision conversion issue, and the rounding mode does not take effect.

Example 1: For input 1.5 - 2-10, the output is 1.5 - 2-10.

The half-to-float conversion only supports non-saturation behaviors.

Example 2: For input inf, the output is inf.

Example 3: For input -inf, the output is -inf.

Example 4: For input nan, the output is nan.

bfloat16_t

Example 1: For input 0.5 + 2-9 + 2-11, it is represented as 2–1 * (1 + 2–8 + 2–10) in half format, meaning that E = -1 + 15 = 14 and M = 2-8 + 2-10.

The exponent bits of the bfloat16_t type can represent 2-1, meaning E = -1 + 127 = 126. However, the bfloat16_t type has only 7 mantissa bits. Therefore, rounding is required.

In CAST_RINT mode, the result mantissa is 0000001, E = 126, and M = 2–7. The final result is 0.5 + 2-8.

In CAST_FLOOR mode, the result mantissa is 0000000, E = 126, and M = 0. The final result is 0.5.

In CAST_CEIL mode, the result mantissa is 0000001, E = 126, and M = 2–7. The final result is 0.5 + 2–8.

In CAST_ROUND mode, the result mantissa is 0000001, E = 126, and M = 2–7. The final result is 0.5 + 2–8.

In CAST_TRUNC mode, the result mantissa is 0000000, E = 126, and M = 0. The final result is 0.5.

For details about the final saturation behavior of half-to-bfloat16_t conversion, see Table 5.

Example 2: For input inf, the output is about 3.39*1038 in saturation mode, and inf in non-saturation mode.

Example 3: For input -inf, the output is about -3.39*1038 in saturation mode, and -inf in non-saturation mode.

Example 4: For input nan, the output is 0 in saturation mode, and nan in non-saturation mode.

int32_t

Example 1: For input 29 + 0.5, the output is 29 in CAST_RINT mode, 29 in CAST_FLOOR mode, 29 + 1 in CAST_CEIL mode, 29 + 1 in CAST_ROUND mode, and 29 in CAST_TRUNC mode.

Example 2: For input inf, the output is 231-1.

Example 3: For input -inf, the output is 2-31.

Example 4: For input nan, the output is 0.

uint32_t

Example 1: For input 29 + 0.5, the output is 29 in CAST_RINT mode, 29 in CAST_FLOOR mode, 29 + 1 in CAST_CEIL mode, 29 + 1 in CAST_ROUND mode, and 29 in CAST_TRUNC mode.

Example 2: For input inf, the output is 232-1.

Example 3: For input -inf, the output is 0.

Example 4: For input nan, the output is 0.

hifloat8_t

Rounds src based on the rounding mode and saves the result in hifloat8_t format in dst (the overflow part is saturated).

For example, in the case of input 1.75:

The output is 2 in CAST_ROUND mode. For details about the output in CAST_HYBRID mode, see Table 10.

bfloat16_t

bfloat16_t

Rounds src based on the rounding mode and saves the result in bfloat16_t format in dst.

For example, in the case of input 0.5:

The output is 0.0 in CAST_RINT mode, 0.0 in CAST_FLOOR mode, 1.0 in CAST_CEIL mode, 1.0 in CAST_ROUND mode, and 0.0 in CAST_TRUNC mode.

float

There is no precision conversion issue, and the rounding mode does not take effect.

Example 1: For input 1.5 - 2-6, the output is 1.5 - 2-6.

The bfloat16_t-to-float conversion only supports non-saturation behaviors.

Example 2: For input inf, the output is inf.

Example 3: For input -inf, the output is -inf.

Example 4: For input nan, the output is nan.

half

Example 1: For input 1.5 - 2-6, the output is 1.5 - 2-6.

For details about the final saturation behavior of bfloat16-to-half conversion, see Table 4.

Example 2: For input inf, the output is 65504 in saturation mode, and inf in non-saturation mode.

Example 3: For input -inf, the output is -65504 in saturation mode, and -inf in non-saturation mode.

Example 3: For input nan, the output is 0 in saturation mode, and nan in non-saturation mode.

int32_t

Example 1: For input 26 + 0.5, the output is 26 in CAST_RINT mode, 26 in CAST_FLOOR mode, 26 + 1 in CAST_CEIL mode, 26 + 1 in CAST_ROUND mode, and 26 in CAST_TRUNC mode.

Example 2: For input inf, the output is 231-1.

Example 3: For input -inf, the output is 2-31.

Example 4: For input nan, the output is 0.

uint32_t

Example 1: For input 26 + 0.5, the output is 26 in CAST_RINT mode, 26 in CAST_FLOOR mode, 26 + 1 in CAST_CEIL mode, 26 + 1 in CAST_ROUND mode, and 26 in CAST_TRUNC mode.

Example 2: For input inf, the output is 232-1.

Example 3: For input -inf, the output is 0.

Example 4: For input nan, the output is 0.

hifloat8_t

float

Stores src in dst in float format. There is no precision conversion issue, and no rounding mode is involved.

For example, if the input is 2, the output is 2.

half

Stores src in dst in half format. There is no precision conversion issue, and no rounding mode is involved.

For example, if the input is 2, the output is 2.

fp8_e4m3fn_t

float

Stores src in dst in float format. There is no precision conversion issue, and no rounding mode is involved.

For example, if the input is 2, the output is 2.

fp8_e5m2_t

float

Stores src in dst in float format. There is no precision conversion issue, and no rounding mode is involved.

For example, if the input is 2, the output is 2.

int32_t

float

Example 1: For input 225 + 3, it is represented as 225 * (1 + 2-24 + 2-25) in float type, meaning that E = 25 + 127 = 152 and M = 2-24 + 2-25.

However, float has only 23 mantissa bits. Therefore, rounding is required.

In CAST_RINT mode, the result mantissa is 00000000000000000000001, E = 152, and M = 2-23. The final result is 225 + 4.

In CAST_FLOOR mode, the result mantissa is 00000000000000000000000, E = 152, and M = 0. The final result is 225.

In CAST_CEIL mode, the result mantissa is 00000000000000000000001, E = 152, and M = 2-23. The final result is 225 + 4.

In CAST_ROUND mode, the result mantissa is 00000000000000000000001, E = 152, and M = 2-23. The final result is 225 + 4.

In CAST_TRUNC mode, the result mantissa is 00000000000000000000000, E = 152, and M = 0. The final result is 225.

half

Example 1: For input 212 + 3, it is represented as 212 *(1 + 2-11 + 2-12) in half type, meaning that E = 12 + 15 = 27 and M = 2-11 + 2-12.

However, half has only 10 mantissa bits. Therefore, rounding is required.

In CAST_RINT mode, the result mantissa is 0000000001, E = 27, and M = 2-10. The final result is 212 + 4.

In CAST_FLOOR mode, the result mantissa is 0000000000, E = 27, and M = 0. The final result is 212.

In CAST_CEIL mode, the result mantissa is 0000000001, E = 27, and M = 2-10. The final result is 212 + 4.

In CAST_ROUND mode, the result mantissa is 0000000001, E = 27, and M = 2-10. The final result is 212 + 4.

In CAST_TRUNC mode, the result mantissa is 0000000000, E = 27, and M = 0. The final result is 212.

Example 2: For input 231 - 1, the return value is 65504.0 in SAT mode and inf in NO_SAT mode.

Example 3: For input -231, the return value is -65504.0 in SAT mode and -inf in NO_SAT mode.

bfloat16_t

Example 1: For input 29 + 3, it is represented as 29 *(1 + 2-8 + 2-9) in bfloat16_t type, meaning that E = 9 + 127 = 136 and M = 2-8 + 2-9.

However, bfloat16_t has only 7 mantissa bits. Therefore, rounding is required.

In CAST_RINT mode, the result mantissa is 0000001, E = 136, and M = 2-7. The final result is 29 + 4.

In CAST_FLOOR mode, the result mantissa is 0000000, E = 136, and M = 0. The final result is 29.

In CAST_CEIL mode, the result mantissa is 0000001, E = 136, and M = 2-7. The final result is 29 + 4.

In CAST_ROUND mode, the result mantissa is 0000001, E = 136, and M = 2-7. The final result is 29 + 4.

In CAST_TRUNC mode, the result mantissa is 0000000, E = 136, and M = 0. The final result is 29.

uint32_t

float

Example 1: For input 225 + 3, it is represented as 225 * (1 + 2-24 + 2-25) in float type, meaning that E = 25 + 127 = 152 and M = 2-24 + 2-25.

However, float has only 23 mantissa bits. Therefore, rounding is required.

In CAST_RINT mode, the result mantissa is 00000000000000000000001, E = 152, and M = 2-23. The final result is 225 + 4.

In CAST_FLOOR mode, the result mantissa is 00000000000000000000000, E = 152, and M = 0. The final result is 225.

In CAST_CEIL mode, the result mantissa is 00000000000000000000001, E = 152, and M = 2-23. The final result is 225 + 4.

In CAST_ROUND mode, the result mantissa is 00000000000000000000001, E = 152, and M = 2-23. The final result is 225 + 4.

In CAST_TRUNC mode, the result mantissa is 00000000000000000000000, E = 152, and M = 0. The final result is 225.

half

Example 1: For input 212 + 3, it is represented as 212 *(1 + 2-11 + 2-12) in half type, meaning that E = 12 + 15 = 27 and M = 2-11 + 2-12.

However, half has only 10 mantissa bits. Therefore, rounding is required.

In CAST_RINT mode, the result mantissa is 0000000001, E = 27, and M = 2-10. The final result is 212 + 4.

In CAST_FLOOR mode, the result mantissa is 0000000000, E = 27, and M = 0. The final result is 212.

In CAST_CEIL mode, the result mantissa is 0000000001, E = 27, and M = 2-10. The final result is 212 + 4.

In CAST_ROUND mode, the result mantissa is 0000000001, E = 27, and M = 2-10. The final result is 212 + 4.

In CAST_TRUNC mode, the result mantissa is 0000000000, E = 27, and M = 0. The final result is 212.

Example 2: For input 232 - 1, the return value is 65504.0 in SAT mode and inf in NO_SAT mode.

bfloat16_t

Example 1: For input 29 + 3, it is represented as 29 *(1 + 2-8 + 2-9) in bfloat16_t type, meaning that E = 9 + 127 = 136 and M = 2-8 + 2-9.

However, bfloat16_t has only 7 mantissa bits. Therefore, rounding is required.

In CAST_RINT mode, the result mantissa is 0000001, E = 136, and M = 2-7. The final result is 29 + 4.

In CAST_FLOOR mode, the result mantissa is 0000000, E = 136, and M = 0. The final result is 29.

In CAST_CEIL mode, the result mantissa is 0000001, E = 136, and M = 2-7. The final result is 29 + 4.

In CAST_ROUND mode, the result mantissa is 0000001, E = 136, and M = 2-7. The final result is 29 + 4.

In CAST_TRUNC mode, the result mantissa is 0000000, E = 136, and M = 0. The final result is 29.

int64_t

float

Example 1: For input 225 + 3, it is represented as 225 * (1 + 2-24 + 2-25) in float type, meaning that E = 25 + 127 = 152 and M = 2-24 + 2-25.

However, float has only 23 mantissa bits. Therefore, rounding is required.

In CAST_RINT mode, the result mantissa is 00000000000000000000001, E = 152, and M = 2-23. The final result is 225 + 4.

In CAST_FLOOR mode, the result mantissa is 00000000000000000000000, E = 152, and M = 0. The final result is 225.

In CAST_CEIL mode, the result mantissa is 00000000000000000000001, E = 152, and M = 2-23. The final result is 225 + 4.

In CAST_ROUND mode, the result mantissa is 00000000000000000000001, E = 152, and M = 2-23. The final result is 225 + 4.

In CAST_TRUNC mode, the result mantissa is 00000000000000000000000, E = 152, and M = 0. The final result is 225.

uint64_t

float

Example 1: For input 225 + 3, it is represented as 225 * (1 + 2-24 + 2-25) in float type, meaning that E = 25 + 127 = 152 and M = 2-24 + 2-25.

However, float has only 23 mantissa bits. Therefore, rounding is required.

In CAST_RINT mode, the result mantissa is 00000000000000000000001, E = 152, and M = 2-23. The final result is 225 + 4.

In CAST_FLOOR mode, the result mantissa is 00000000000000000000000, E = 152, and M = 0. The final result is 225.

In CAST_CEIL mode, the result mantissa is 00000000000000000000001, E = 152, and M = 2-23. The final result is 225 + 4.

In CAST_ROUND mode, the result mantissa is 00000000000000000000001, E = 152, and M = 2-23. The final result is 225 + 4.

In CAST_TRUNC mode, the result mantissa is 00000000000000000000000, E = 152, and M = 0. The final result is 225.