@@ -243,6 +243,124 @@ function yyBuffer( _size, _type, _alignment, _srcbytebuff ) {
243
243
}
244
244
}
245
245
}
246
+ if ( ! DataView . prototype . getFloat16 ) {
247
+ // #################################################################################################
248
+ /// Function: getFloat16
249
+ /// Description:
250
+ /// Retrieve and decode a 16-bit floating-point number from a DataView.
251
+ ///
252
+ /// Parameters:
253
+ /// byteOffset - The offset where the 16-bit float is stored.
254
+ /// littleEndian - Specifies the endianness of the data (true for little-endian, false for big-endian).
255
+ ///
256
+ /// Returns:
257
+ /// The decoded 16-bit floating-point number.
258
+ /// If the input data is invalid or out of range, NaN is returned.
259
+ // #################################################################################################
260
+ DataView . prototype . getFloat16 = function ( byteOffset , littleEndian ) {
261
+ // Define a custom getFloat16 method if it doesn't exist
262
+ // byteOffset: The offset where the 16-bit float is stored
263
+ // littleEndian: Specifies the endianness of the data
264
+
265
+ // Read the 16-bit float as an unsigned integer
266
+ const uint16 = this . getUint16 ( byteOffset , littleEndian ) ;
267
+
268
+ // Extract the sign bit (bit 15)
269
+ const sign = ( uint16 & 0x8000 ) ? - 1 : 1 ;
270
+
271
+ // Extract the exponent bits (bits 10-14)
272
+ const exponent = ( uint16 >> 10 ) & 0x1F ;
273
+
274
+ // Extract the mantissa bits (bits 0-9)
275
+ const mantissa = uint16 & 0x3FF ;
276
+
277
+ if ( exponent === 0 ) {
278
+ // If exponent is 0, it's a denormalized number or zero
279
+ if ( mantissa === 0 ) {
280
+ // Zero
281
+ return sign * 0.0 ;
282
+ } else {
283
+ // Denormalized number
284
+ // Calculate the value using the formula for denormalized numbers
285
+ return sign * Math . pow ( 2 , - 14 ) * ( mantissa / 1024 ) ;
286
+ }
287
+ } else if ( exponent === 31 ) {
288
+ // If exponent is 31, it's infinity or NaN
289
+ if ( mantissa === 0 ) {
290
+ // Positive or negative infinity
291
+ return ( sign === 1 ) ? Number . POSITIVE_INFINITY : Number . NEGATIVE_INFINITY ;
292
+ } else {
293
+ // NaN
294
+ return NaN ;
295
+ }
296
+ } else {
297
+ // Normalized number
298
+ // Calculate the value using the formula for normalized numbers
299
+ return sign * Math . pow ( 2 , exponent - 15 ) * ( 1 + mantissa / 1024 ) ;
300
+ }
301
+ } ;
302
+ }
303
+
304
+ if ( ! DataView . prototype . setFloat16 ) {
305
+ // #################################################################################################
306
+ /// Function: setFloat16
307
+ /// Description:
308
+ /// Encode and write a 16-bit floating-point number (float16) to a DataView.
309
+ ///
310
+ /// Parameters:
311
+ /// offset - The offset where the float16 will be written in the DataView.
312
+ /// value - The float16 value to encode and write.
313
+ /// littleEndian - Optional. Specifies the endianness of the data (true for little-endian, false for big-endian).
314
+ ///
315
+ /// Returns:
316
+ /// None.
317
+ ///
318
+ /// Throws:
319
+ /// - RangeError if the provided float16 value is out of the representable range for float16.
320
+ ///
321
+ /// Details:
322
+ /// The function encodes the provided float16 value as per IEEE 754-2008 standard for half-precision
323
+ /// floating-point numbers and writes it to the specified offset in the DataView. If the value is
324
+ /// outside the representable range for float16, a RangeError is thrown.
325
+ ///
326
+ /// Special cases:
327
+ /// - If the value is 0, it is written as a positive zero.
328
+ /// - If the value is NaN, it is written as the NaN representation.
329
+ ///
330
+ /// Example Usage:
331
+ /// const dataView = new DataView(new ArrayBuffer(2));
332
+ /// dataView.setFloat16(0, 1.0, true); // Write float16 value 1.0 in little-endian
333
+ // #################################################################################################
334
+ DataView . prototype . setFloat16 = function ( offset , value , littleEndian = true ) {
335
+ // Define a custom setFloat16 method if it doesn't exist
336
+ // offset: The offset where the 16-bit float will be written
337
+ // value: The float16 value to write
338
+ // littleEndian: Specifies the endianness of the data (true for little-endian, false for big-endian)
339
+
340
+ // Ensure the value is within the representable range of float16
341
+ if ( value < - 65504.0 || value > 65504.0 ) {
342
+ throw new RangeError ( "Float16 value is out of range." ) ;
343
+ }
344
+
345
+ // Handle special cases for zero and NaN
346
+ if ( value === 0 ) {
347
+ // Zero
348
+ this . setUint16 ( offset , 0 , littleEndian ) ;
349
+ } else if ( isNaN ( value ) ) {
350
+ // NaN
351
+ this . setUint16 ( offset , 0x7E00 , littleEndian ) ; // NaN representation
352
+ } else {
353
+ // For non-zero, non-NaN values:
354
+ const sign = value < 0 ? 0x8000 : 0 ; // Determine the sign bit
355
+ const absValue = Math . abs ( value ) ;
356
+ const exponent = Math . floor ( Math . log2 ( absValue ) ) + 15 ; // Calculate the exponent
357
+ const mantissa = Math . round ( absValue * Math . pow ( 2 , 10 - exponent ) ) ; // Calculate the mantissa
358
+ const uint16Value = sign | ( exponent << 10 ) | mantissa ; // Combine sign, exponent, and mantissa
359
+ this . setUint16 ( offset , uint16Value , littleEndian ) ; // Write the uint16 representation
360
+ }
361
+ } ;
362
+ }
363
+
246
364
247
365
// #############################################################################################
248
366
/// Function:<summary>
@@ -470,6 +588,11 @@ yyBuffer.prototype.yyb_read = function(_type) {
470
588
res = new Long ( this . m_DataView . getUint32 ( this . m_BufferIndex , true ) , 0 ) ;
471
589
this . m_BufferIndex += 4 ;
472
590
break ;
591
+
592
+ case eBuffer_F16 :
593
+ res = this . m_DataView . getFloat16 ( this . m_BufferIndex , true ) ;
594
+ this . m_BufferIndex += 2 ;
595
+ break ;
473
596
case eBuffer_F32 :
474
597
res = this . m_DataView . getFloat32 ( this . m_BufferIndex , true ) ;
475
598
this . m_BufferIndex += 4 ;
@@ -478,6 +601,7 @@ yyBuffer.prototype.yyb_read = function(_type) {
478
601
res = this . m_DataView . getFloat64 ( this . m_BufferIndex , true ) ;
479
602
this . m_BufferIndex += 8 ;
480
603
break ;
604
+
481
605
case eBuffer_U64 :
482
606
var low = this . m_DataView . getUint32 ( this . m_BufferIndex , true ) ;
483
607
this . m_BufferIndex += 4 ;
@@ -1260,6 +1384,11 @@ yyBuffer.prototype.yyb_write = function(_type, _value) {
1260
1384
this . m_DataView . setUint32 ( this . m_BufferIndex , _value , true ) ;
1261
1385
this . m_BufferIndex += 4 ;
1262
1386
break ;
1387
+
1388
+ case eBuffer_F16 :
1389
+ this . m_DataView . setFloat16 ( this . m_BufferIndex , _value , true ) ;
1390
+ this . m_BufferIndex += 2 ;
1391
+ break ;
1263
1392
case eBuffer_F32 :
1264
1393
this . m_DataView . setFloat32 ( this . m_BufferIndex , _value , true ) ;
1265
1394
this . m_BufferIndex += 4 ;
@@ -1268,6 +1397,7 @@ yyBuffer.prototype.yyb_write = function(_type, _value) {
1268
1397
this . m_DataView . setFloat64 ( this . m_BufferIndex , _value , true ) ;
1269
1398
this . m_BufferIndex += 8 ;
1270
1399
break ;
1400
+
1271
1401
case eBuffer_U64 :
1272
1402
var int64Val = yyGetInt64 ( _value ) ;
1273
1403
this . m_DataView . setUint32 ( this . m_BufferIndex , int64Val . low , true ) ;
@@ -1336,12 +1466,17 @@ yyBuffer.prototype.yyb_peek = function(_type, _offset) {
1336
1466
case eBuffer_U32 :
1337
1467
res = this . m_DataView . getUint32 ( _offset , true ) ;
1338
1468
break ;
1469
+
1470
+ case eBuffer_F16 :
1471
+ res = this . m_DataView . getFloat16 ( _offset , true ) ;
1472
+ break ;
1339
1473
case eBuffer_F32 :
1340
1474
res = this . m_DataView . getFloat32 ( _offset , true ) ;
1341
1475
break ;
1342
1476
case eBuffer_F64 :
1343
1477
res = this . m_DataView . getFloat64 ( _offset , true ) ;
1344
1478
break ;
1479
+
1345
1480
case eBuffer_U64 :
1346
1481
var low = this . m_DataView . getUint32 ( _offset , true ) ;
1347
1482
var high = this . m_DataView . getUint32 ( _offset + 4 , true ) ;
0 commit comments