Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
inexorabletash committed May 8, 2024
1 parent a3ff823 commit ee629be
Showing 1 changed file with 96 additions and 0 deletions.
96 changes: 96 additions & 0 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ urlPrefix: https://tc39.es/ecma262/; spec: ECMA-262
text: element size; url: table-the-typedarray-constructors
text: element type; url: table-the-typedarray-constructors
text: view constructor; url: table-the-typedarray-constructors
text: equally close values; url: sec-ecmascript-language-types-number-type
</pre>

<pre class="link-defaults">
Expand Down Expand Up @@ -5937,6 +5938,101 @@ To <dfn data-lt="bidirectionally broadcasting the shapes">bidirectionally broadc
|shapeA| is <dfn>bidirectionally broadcastable</dfn> to |shapeB| if [=bidirectionally broadcasting the shapes=] |shapeA| and |shapeB| does not result in failure.
</p>

## Casting ## {#algorithms-casting}

<details open algorithm="cast">
<summary>
To <dfn>cast</dfn> a number |x| to a given {{MLOperandDataType}} |dataType|, optional boolean |restricted| (defaulting to false), optional boolean |enforceRange| (defaulting to false), and optional boolean |clamp| (defaulting to false), perform the following steps. They return a number or failure.
</summary>

1. Switch on |dataType|:
<dl class=switch>
: {{MLOperandDataType/"float32"}}
:: Return [=ConvertToFloat=](|x|, 32, |restricted|)
: {{MLOperandDataType/"float16"}}
:: Return [=ConvertToFloat=](|x|, 16, |restricted|)
: {{MLOperandDataType/"int64"}}
:: Return [=ConvertToInt=](|x|, 64, "signed", |enforceRange|, |clamp|).
: {{MLOperandDataType/"uint64"}}
:: Return [=ConvertToInt=](|x|, 64, "unsigned", |enforceRange|, |clamp|).
: {{MLOperandDataType/"int32"}}
:: Return [=ConvertToInt=](|x|, 32, "signed", |enforceRange|, |clamp|).
: {{MLOperandDataType/"uint32"}}
:: Return [=ConvertToInt=](|x|, 32, "signed", |enforceRange|, |clamp|).
: {{MLOperandDataType/"int8"}}
:: Return [=ConvertToInt=](|x|, 8, "signed", |enforceRange|, |clamp|).
: {{MLOperandDataType/"uint8"}}
:: Return [=ConvertToInt=](|x|, 8, "unsigned", |enforceRange|, |clamp|).
</dl>

NOTE: The input to [=cast=] is an abstract number with unlimited range and precision, including the special values Infinity, -Infinity and NaN. The output is also an abstract number, but exactly representable as the specified type.

ISSUE: Can we eliminate |restricted|, |enforceRange|, and |clamp| as parameters, if we always use the same conversions? Or if we never use |clamp|, at least combine |enforceRange| and |restricted|?

<div algorithm>
The <dfn>ConvertToFloat</dfn>(|x|, |bitLength|, |restricted|) steps are:

1. If |x| is NaN, then return NaN if |restricted| is false, and failure otherwise.
1. Let |lowerBound| be -2<sup>|bitLength| - 1</sup>.
1. Let |upperBound| be 2<sup>|bitLength| - 1</sup>.
1. Switch on |bitLength|:
<dl class=switch>
: 32
:: 1. Let |S| be the set of [[IEEE-754-2019]] binary32 floating point values except -0, but with |lowerBound| and |upperBound| added.
: 16
:: 1. Let |S| be the set of [[IEEE-754-2019]] binary16 floating point values except -0, but with |lowerBound| and |upperBound| added.
</dl>
1. Let |y| be the number in |S| that is closest to |x|, selecting the number with an even significand if there are two [=equally close values=]. (The two special values |lowerBound| and |upperBound| are considered to have even significands for this purpose.)
1. If |y| is |upperBound|, then return +Infinity if |restricted| is false, or failure otherwise.
1. If |y| is |lowerBound|, then return -Infinity if |restricted| is false, or failure otherwise.
1. If |y| is +0 and |x| is negative, return -0.
1. Return |y|.

NOTE: This is based on a definition in [[WEBIDL]], but extended to cover 16-bit floating point values.

</div>

<div algorithm>
The <dfn>ConvertToInt</dfn>(|x|, |bitLength|, |signedness|, |enforceRange|, |clamp|) steps are:

1. If |signedness| is "unsigned", then:
1. Let |lowerBound| be 0.
1. Let |upperBound| be 2<sup>|bitLength|</sup> - 1.
1. Otherwise:
1. Let |lowerBound| be -2<sup>|bitLength| - 1</sup>.
1. Let |upperBound| be 2<sup>|bitLength| - 1</sup> - 1.
1. If |x| is -0, then set |x| to +0.
1. If |enforceRange| is true, then:
1. If |x| is NaN, +Infinity, or -Infinity, then return failure.
1. Set |x| to [=IntegerPart=](|x|).
1. If |x| &lt; |lowerBound| or |x| &gt; |upperBound|, then return failure.
1. Return |x|.
1. If |x| is not NaN and |clamp| is true, then:
1. Set |x| to min(max(|x|, |lowerBound|), |upperBound|).
1. Round |x| to the nearest integer, choosing the even integer if it lies halfway between two, and choosing +0 rather than -0.
1. Return |x|.
1. If |x| is NaN, +0, +Infinity, or -Infinity, then return +0.
1. Set |x| to [=IntegerPart=](|x|).
1. Set |x| to |x| modulo 2<sup>|bitLength|</sup>.
1. If |signedness| is "signed" and |x| >= 2<sup>|bitLength| - 1</sup>,
then return |x| - 2<sup>|bitLength|</sup>.
1. Otherwise, return |x|.

NOTE: This is based on a definition in [[WEBIDL]] with these differences: 64-bit integers are not treated specially, the input |x| is an abstract number, |enforceRange| and |clamp| are explicit parameters, and it returns failure rather than throwing.

</div>

<div algorithm>
The <dfn>IntegerPart</dfn>(|n|) steps are:

1. Let |r| be floor(abs(|n|)).
1. If |n| &lt; 0, then return -1 * |r|.
1. Otherwise, return |r|.

</div>

</details>

Examples {#examples}
=====================

Expand Down

0 comments on commit ee629be

Please sign in to comment.