blob: a4ac7e1460b50684b0efeb3a7d1fbee4a3605745 [file] [edit]
// Copyright 2017-2020 The Khronos Group. This work is licensed under a
// Creative Commons Attribution 4.0 International License; see
// http://creativecommons.org/licenses/by/4.0/
[[conversions-library]]
=== Conversions Library
This section describes the explicit conversion cast functions.
These functions provide a full set of type conversions between supported scalar and vector data types (see the <<builtin-scalar-data-types, _Built-in Scalar Data Types_>> and the <<builtin-vector-data-types, _Built-in Vector Data Types_>> sections) except for the following types: `size_t`, `ptrdiff_t`, `intptr_t`, `uintptr_t`, and `void`.
The behavior of the conversion may be modified by one or two optional modifiers that specify saturation for out-of-range inputs and rounding behavior.
The `convert_cast` type conversion operator that specifies a rounding mode and saturation is also provided.
[[header-opencl_convert-synopsis]]
==== Header <opencl_convert> Synopsis
[source]
----
namespace cl
{
enum class rounding_mode { rte, rtz, rtp, rtn };
enum class saturate { off, on };
template <class T, class U>
T convert_cast(U const& arg);
template <class T>
T convert_cast(T const& arg);
template <class T, rounding_mode rmode, class U>
T convert_cast(U const& arg);
template <class T, rounding_mode rmode>
T convert_cast(T const& arg);
template <class T, saturate smode, class U>
T convert_cast(U const& arg);
template <class T, saturate smode>
T convert_cast(T const& arg);
template <class T, rounding_mode rmode, saturate smode, class U>
T convert_cast(U const& arg);
template <class T, rounding_mode rmode, saturate smode>
T convert_cast(T const& arg);
}
----
[[data-types]]
==== Data Types
Conversions are available for the following scalar types: `bool`, `char`, `uchar`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `half` [[ftnref4]] <<ftn4,[4]>>, `float`, `double`, and built-in vector types derived therefrom.
The operand and result type must have the same number of elements.
The operand and result type may be the same type in which case the conversion has no effect on the type or value of an expression.
Conversions between integer types follow the conversion rules specified in the {cpp14} specification except for out-of-range behavior and saturated conversions which are described in the <<out-of-range-behavior-and-saturated-conversions, _Out-of-Range Behavior and Saturated Conversions_>> section below.
[[rounding-modes]]
==== Rounding Modes
Conversions to and from floating-point type shall conform to IEEE-754 rounding rules.
Conversions may have an optional rounding mode specified as described in the table belows.
.Rounding Modes
[width="100%",cols="50%,50%",options="header"]
|====
| *Rounding Mode* | *Description*
| `rte` | Round to nearest even
| `rtz` | Round toward zero
| `rtp` | Round toward positive infinity
| `rtn` | Round toward negative infinity
|====
If a rounding mode is not specified, conversions to integer type use the `rtz` (round toward zero) rounding mode and conversions to floating-point type [[ftnref5]] <<ftn5,[5]>> uses the `rte` rounding mode.
[[out-of-range-behavior-and-saturated-conversions]]
==== Out-of-Range Behavior and Saturated Conversions
When the conversion operand is either greater than the greatest representable destination value or less than the least representable destination value, it is said to be out-of-range.
The result of out-of-range conversion is determined by the conversion rules specified by the {cpp14} specification in _chapter 4.9_.
When converting from a floating-point type to integer type, the behavior is implementation-defined.
Conversions to integer type may opt to convert using the optional saturation mode.
When in saturated mode, values that are outside the representable range shall clamp to the nearest representable value in the destination format.
(NaN should be converted to 0).
Conversions to floating-point type shall conform to IEEE-754 rounding rules. The `convert_cast` operator with a saturate argument may not be used for conversions to floating-point formats.
[[examples-1]]
==== Examples
[[example-1-1]]
===== Example 1
Examples of casting between two vector types with saturation.
[source]
----
#include <opencl_convert>
using namespace cl;
kernel void Foo() {
short4 s;
// negative values clamped to 0
ushort4 u = convert_cast<ushort4,saturate::on>(s);
// values > CHAR_MAX converted to CHAR_MAX
// values < CHAR_MIN converted to CHAR_MIN
char4 c = convert_cast<char4, saturate::on>(s);
}
----
[[example-2-1]]
===== Example 2
Examples of casting from float to integer vector type with saturation and rounding mode specified.
[source]
----
#include <opencl_convert>
using namespace cl;
kernel void Foo() {
float4 f;
// values implementation defined for
// f > INT_MAX, f < INT_MIN or NaN
int4 i1 = convert_cast<int4>(f);
// values > INT_MAX clamp to INT_MAX, values < INT_MIN clamp
// to INT_MIN. NaN should produce 0.
// The rtz rounding mode is used to produce the integer
// values.
int4 i2 = convert_cast<int4,saturate::on>(f);
// similar to convert_cast<int4>, except that floating-point
// values are rounded to the nearest integer instead of
// truncated
int4 i3 = convert_cast<int4, rounding_mode::rte>(f);
// similar to convert_cast<int4, saturate::on>, except that
// floating-point values are rounded to the nearest integer
// instead of truncated
int4 i4 = convert_cast<int4, rounding_mode::rte,
saturate::on>(f);
}
----
[[example-3]]
===== Example 3
Examples of casting from integer to float vector type.
[source]
----
#include <opencl_convert>
using namespace cl;
kernel void Foo() {
int4 i;
// convert ints to floats using the default rounding mode.
float4 f1 = convert_cast<float4>(i);
// convert ints to floats. integer values that cannot
// be exactly represented as floats should round up to the
// next representable float.
float4 f2 = convert_cast<float4, rounding_mode::rtp>(i);
}
----