Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5005x 5005x 5005x 5005x 5005x 5005x 5005x 5005x 5005x 5005x 5005x 5005x 5005x 5005x 5005x 5005x 1x 1x 5005x 1x 1x 5005x 1x 1x 5005x 6x 1x 1x 5x 5x 4996x 5005x 2498x 2498x 2498x 2498x 4996x 4996x 4996x 4996x 4996x 4996x 4996x 4996x 4996x 4996x 4996x 4996x 4996x 4996x 4996x 4996x 5005x 4996x 4996x 5005x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 670x 670x 1000x 1000x 1000x 1000x 1000x 1000x 1000x 500x 500x 1000x 1000x 1000x 3996x 3996x 3996x 3996x 3996x 3996x 3996x 3996x 5005x 5005x 5005x 5005x 1988x 1988x 1988x 1988x 2x 2x 2x 2x 2x 2x 1988x 3996x 3996x 3996x 5005x 1x 1x 1x 1x 1x | /**
* @license Apache-2.0
*
* Copyright (c) 2025 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
// MODULES //
var NINF = require( '@stdlib/constants/float16/ninf' );
var PINF = require( '@stdlib/constants/float16/pinf' );
var isnan = require( '@stdlib/assert/is-nan' );
var abs = require( '@stdlib/math/base/special/abs' );
var exponent = require( '@stdlib/number/float64/base/exponent' );
var isNegativeZero = require( '@stdlib/assert/is-negative-zero' );
var toWords = require( '@stdlib/number/float64/base/to-words' );
// MAIN //
/**
* Returns an unsigned 16-bit integer corresponding to the IEEE 754 binary representation of a half-precision floating-point number.
*
* @param {number} x - half-precision floating-point number
* @returns {unsigned16} unsigned 16-bit integer
*
* @example
* var float64ToFloat16 = require( '@stdlib/number/float64/base/to-float16' );
*
* var f16 = float64ToFloat16( 1.05 );
* // returns 1.0498046875
*
* var w = toWord( f16 ); // => 0 01111 0000110011
* // returns 15411
*/
function toWord( x ) {
var mantissaHigh;
var mantissaLow;
var f64Exponent;
var f16Exponent;
var stickyBits;
var mantissa;
var roundBit;
var shift;
var sign;
var high;
var low;
var w;
// Handle special cases
if ( isnan( x ) ) { // NaN
return 0x7E00;
}
if ( x === PINF ) {
return 0x7C00; // +Infinity
}
if ( x === NINF ) {
return 0xFC00; // -Infinity
}
if ( x === 0 ) {
if ( isNegativeZero( x ) ) {
return 0x8000;
}
return 0x0000;
}
if ( x < 0 ) {
sign = 1;
} else {
sign = 0;
}
x = abs( x );
w = toWords( x );
high = w[ 0 ]; // high 32 bits
low = w[ 1 ]; // low 32 bits
mantissaHigh = high & 0xFFFFF; // 20 bits: mantissa[51:32]
mantissaLow = low; // 32 bits: mantissa[31:0]
// Store unbiased exponent of a 64-bit floating-point number.
f64Exponent = exponent( x );
// Calculate exponent of a 16-bit floating-point number.
f16Exponent = f64Exponent + 15;
// Handle overflow (infinity in float16)
if ( f16Exponent >= 31 ) {
if ( sign ) {
return 0xFC00; // -Infinity
}
return 0x7C00; // +Infinity
}
// Handle underflow (subnormal or zero in float16)
if ( f16Exponent <= 0 ) {
// Check if the value is too small to be represented even as a subnormal float16 number:
if ( f16Exponent < -10 ) {
return sign << 15; // Return zero with the appropriate sign bit
}
// Calculate the amount of right shift needed to denormalize the mantissa for subnormal representation:
shift = 1 - f16Exponent;
// Create an 11-bit mantissa by adding the implicit leading 1 bit and extracting the top 10 bits from mantissaHigh:
mantissa = 0x400 | ( mantissaHigh >>> 10 );
// Determine the round bit and sticky bits based on the shift amount to apply correct rounding:
if ( shift < 11 ) {
// Extract the round bit at the position that will be truncated after the shift:
roundBit = ( mantissa >>> ( shift - 1 ) ) & 1;
// Check if any bits below the round bit position are set (sticky bits):
stickyBits = ( mantissa & ( ( 1 << ( shift - 1 ) ) - 1 ) ) !== 0;
// If no sticky bits found in the 11-bit mantissa, check the remaining bits from the original float64 mantissa:
if ( !stickyBits ) {
stickyBits = ( ( mantissaHigh & 0x3FF ) !== 0 ) || ( mantissaLow !== 0 ); // eslint-disable-line max-len
}
} else {
// When the shift is 11 or greater, the round bit comes from the lower bits of mantissaHigh:
roundBit = ( mantissaHigh >>> ( 10 - ( shift - 11 ) - 1 ) ) & 1;
// Check if any bits below the round bit position in mantissaHigh or any bits in mantissaLow are set:
stickyBits = ( ( mantissaHigh & ( ( 1 << ( 10 - ( shift - 11 ) - 1 ) ) - 1 ) ) !== 0 ) || ( mantissaLow !== 0 ); // eslint-disable-line max-len
}
// Apply the denormalization shift to the mantissa:
mantissa = mantissa >>> shift;
// Round to nearest even
if ( roundBit && ( stickyBits || ( mantissa & 1 ) ) ) {
mantissa += 1;
}
return ( sign << 15 ) | mantissa;
}
// Extract the top 10 bits of the mantissa for normal float16 representation:
mantissa = mantissaHigh >>> 10;
// Extract the round bit (the first bit that will be truncated):
roundBit = ( mantissaHigh >>> 9 ) & 1;
// Check sticky bits (all bits below bit 41)
stickyBits = ( ( mantissaHigh & 0x1FF ) !== 0 ) || ( mantissaLow !== 0 );
// Round up if roundBit is 1 AND (sticky bits OR mantissa is odd)
if ( roundBit && ( stickyBits || ( mantissa & 1 ) ) ) {
mantissa += 1;
// Check for mantissa overflow (carries into exponent)
if ( mantissa > 0x3FF ) {
f16Exponent += 1;
mantissa = 0;
// Check for exponent overflow
if ( f16Exponent >= 31 ) {
if ( sign ) {
return 0xFC00; // -Infinity
}
return 0x7C00; // +Infinity
}
}
}
// Combine sign (1 bit), exponent (5 bits), and mantissa (10 bits)
return ( sign << 15 ) | ( f16Exponent << 10 ) | mantissa;
}
// EXPORTS //
module.exports = toWord;
|