## Reinterpreting Data as Another Type

Consider the case where you want to mask off the sign bit of a floating-point type. There are multiple ways to solve this in C—using pointer aliasing, unions, or `memcpy`. Of these, only `memcpy` is strictly correct in C99. Because OpenCL C does not support `memcpy`, we need a different method to perform this masking-off operation. The general capability we need is the ability to reinterpret bits in a data type as another data type. In the example where we want to mask off the sign bit of a floating-point type, we want to reinterpret these bits as an unsigned integer type and then mask off the sign bit. Other examples include using the result of a vector relational operator and extracting the exponent or mantissa bits of a floating-point type.

The `as_type` and `as_type`
*
n
* built-in functions allow you to reinterpret bits of a data type as another data type of the same size. The

`as_type`is used for scalar data types (except

`bool`and

`void`) and

`as_type`

*for vector data types.*

`n``double`and

`half`are supported only if the appropriate extensions are supported by the implementation.

The following example describes how you would mask off the sign bit of a floating-point type using the `as_type` built-in function:

float f; uint u; u = as_uint(f); f = as_float(u & ~(1 << 31));

If the operand and result type contain the same number of elements, the bits in the operand are returned directly without modification as the new type. If the operand and result type contain a different number of elements, two cases arise:

- The operand is a 4-component vector and the result is a 3-component vector. In this case, the
`xyz`components of the operand and the result will have the same bits. The`w`component of the result is considered to be undefined. - For all other cases, the behavior is implementation-defined.

We next describe a few examples that show how to use `as_type` and `as_type`
*
n
*. The following example shows how to reinterpret an

`int`as a

`float`:

uint u = 0x3f800000; float f = as_float(u);

The variable `u`, which is declared as an unsigned integer, contains the value `0x3f800000`. This represents the single-precision floating-point value `1.0`. The variable `f` now contains the floating-point value `1.0`.

In the next example, we reinterpret a `float4` as an `int4`:

float4 f = (float4)(1.0f, 2.0f, 3.0f, 4.0f); int4 i = as_int4(f);

The variable `i`, defined to be of type `int4`, will have the following values in its `xyzw` components: `0x3f800000`, `0x40000000`, `0x40400000`, `0x40800000`.

The next example shows how we can perform the ternary selection operator (`?:`) for floating-point vector types using `as_type`
*
n
*:

// Perform the operation f = f < g ? f : 0 for components of a // vector float4 f, g; int4 is_less = f < g; // Each component of the is_less vector will be 0 if result of < // operation is false and will be -1 (i.e., all bits set) if // the result of < operation is true. f = as_float4(as_int4(f) & is_less); // This basically selects f or 0 depending on the values in is_less.

The following example describes cases where the operand and result have a different number of results, in which case the behavior of `as_type` and `as_type`
*
n
* is implementation-defined:

int i; short2 j = as_short2(i); // Legal. Result is implementation-defined int4 i; short8 j = as_short8(i); // Legal. Result is implementation-defined float4 f; float3 g = as_float3(f); // Legal. g.xyz will have same values as // f.xyz. g.w is undefined

This example describes reinterpreting a 4-component vector as a 3-component vector:

float4 f; float3 g = as_float3(f); // Legal. g.xyz will have same values as // f.xyz. g.w is undefined

The next example shows invalid ways of using `as_type` and `as_type`
*
n
*, which should result in compilation errors:

float4 f; double4 g = as_double4(f); // Error. Result and operand have // different sizes. float3 f; float4 g = as_float4(f); // Error. Result and operand have // different sizes