@@ -244,6 +244,141 @@ function yyBuffer( _size, _type, _alignment, _srcbytebuff ) {
244
244
}
245
245
}
246
246
247
+
248
+ // #################################################################################################
249
+ /// Function: yygetFloat16
250
+ /// Description:
251
+ /// Retrieve and decode a 16-bit floating-point number from a DataView.
252
+ ///
253
+ /// Parameters:
254
+ /// byteOffset - The offset where the 16-bit float is stored.
255
+ /// littleEndian - Specifies the endianness of the data (true for little-endian, false for big-endian).
256
+ ///
257
+ /// Returns:
258
+ /// The decoded 16-bit floating-point number.
259
+ /// If the input data is invalid or out of range, NaN is returned.
260
+ // #################################################################################################
261
+ DataView . prototype . yygetFloat16 = function ( byteOffset , littleEndian ) {
262
+ // byteOffset: The offset where the 16-bit float is stored
263
+ // littleEndian: Specifies the endianness of the data
264
+
265
+ // Used references: https://en.wikipedia.org/wiki/Half-precision_floating-point_format
266
+
267
+ // Read the 16-bit float as an unsigned integer
268
+ const uint16 = this . getUint16 ( byteOffset , littleEndian ) ;
269
+
270
+ // Extract the sign bit (bit 15)
271
+ const sign = ( uint16 & 0x8000 ) ? - 1 : 1 ;
272
+
273
+ // Extract the exponent bits (bits 10-14)
274
+ const exponent = ( uint16 >> 10 ) & 0x1F ;
275
+
276
+ // Extract the mantissa bits (bits 0-9)
277
+ const mantissa = uint16 & 0x3FF ;
278
+
279
+ if ( exponent === 0 ) {
280
+ // If exponent is 0, it's a denormalized number or zero
281
+ if ( mantissa === 0 ) {
282
+ // Zero
283
+ return sign * 0.0 ;
284
+ } else {
285
+ // Denormalized number
286
+ // Calculate the value using the formula for denormalized numbers
287
+ return sign * Math . pow ( 2 , - 14 ) * ( mantissa / 1024 ) ;
288
+ }
289
+ } else if ( exponent === 31 ) {
290
+ // If exponent is 31, it's infinity or NaN
291
+ if ( mantissa === 0 ) {
292
+ // Positive or negative infinity
293
+ return ( sign === 1 ) ? Infinity : - Infinity ;
294
+ } else {
295
+ // NaN
296
+ return NaN ;
297
+ }
298
+ } else {
299
+ // Normalized number
300
+ // Calculate the value using the formula for normalized numbers
301
+ return sign * Math . pow ( 2 , exponent - 15 ) * ( 1 + mantissa / 1024 ) ;
302
+ }
303
+ } ;
304
+
305
+ // #################################################################################################
306
+ /// Function: yysetFloat16
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
+ /// Details:
319
+ /// The function encodes the provided float16 value as per IEEE 754-2008 standard for half-precision
320
+ /// floating-point numbers and writes it to the specified offset in the DataView. If the value is
321
+ /// outside the representable range for float16, a RangeError is thrown.
322
+ ///
323
+ /// Special cases:
324
+ /// - If the value is 0, it is written as a positive zero.
325
+ /// - If the value is NaN, it is written as the NaN representation.
326
+ ///
327
+ /// Example Usage:
328
+ /// const dataView = new DataView(new ArrayBuffer(2));
329
+ /// dataView.yysetFloat16(0, 1.0, true); // Write float16 value 1.0 in little-endian
330
+ // #################################################################################################
331
+ DataView . prototype . yysetFloat16 = function ( offset , value , littleEndian = true ) {
332
+ let sign = 0 ;
333
+ let exponent = 0 ;
334
+ let mantissa = 0 ;
335
+
336
+ // Used references: https://en.wikipedia.org/wiki/Half-precision_floating-point_format
337
+ if ( isNaN ( value ) ) {
338
+ // If the value is NaN, use the standard NaN representation for float16.
339
+ mantissa = 0x200 ;
340
+ exponent = 0x1F ;
341
+ } else if ( value === Infinity || value === - Infinity ) {
342
+ // Handling Infinity.
343
+ exponent = 0x1F ;
344
+ } else if ( value === 0 ) {
345
+ // Handling zero (both positive and negative).
346
+ sign = ( 1 / value === - Infinity ) ? 0x8000 : 0 ;
347
+ } else {
348
+ sign = value < 0 ? 0x8000 : 0 ;
349
+ value = Math . abs ( value ) ;
350
+
351
+ if ( value >= Math . pow ( 2 , - 14 ) ) {
352
+ // Handle normal numbers.
353
+ let exponentAndMantissa = Math . floor ( Math . log2 ( value ) + 15 ) ;
354
+ exponent = exponentAndMantissa ;
355
+ mantissa = Math . floor ( ( value / Math . pow ( 2 , exponent - 15 ) - 1 ) * 1024 ) ;
356
+
357
+ if ( mantissa === 1024 ) {
358
+ // We might end in an exponent overflow state.
359
+ exponentAndMantissa += 1 ;
360
+ exponent = exponentAndMantissa ;
361
+ mantissa = 0 ;
362
+ }
363
+
364
+ // Check if we overflow into Infinity.
365
+ if ( exponentAndMantissa > 30 ) {
366
+ // Handle overflow to Infinity.
367
+ exponent = 0x1F ;
368
+ mantissa = 0 ;
369
+ }
370
+ } else {
371
+ // Handle subnormal numbers.
372
+ mantissa = Math . floor ( value / Math . pow ( 2 , - 24 ) ) ;
373
+ }
374
+ }
375
+
376
+ const float16 = sign | ( exponent << 10 ) | mantissa ;
377
+ this . setUint16 ( offset , float16 , littleEndian ) ;
378
+ } ;
379
+
380
+
381
+
247
382
// #############################################################################################
248
383
/// Function:<summary>
249
384
/// Return the size of a "type"
@@ -470,6 +605,11 @@ yyBuffer.prototype.yyb_read = function(_type) {
470
605
res = new Long ( this . m_DataView . getUint32 ( this . m_BufferIndex , true ) , 0 ) ;
471
606
this . m_BufferIndex += 4 ;
472
607
break ;
608
+
609
+ case eBuffer_F16 :
610
+ res = this . m_DataView . yygetFloat16 ( this . m_BufferIndex , true ) ;
611
+ this . m_BufferIndex += 2 ;
612
+ break ;
473
613
case eBuffer_F32 :
474
614
res = this . m_DataView . getFloat32 ( this . m_BufferIndex , true ) ;
475
615
this . m_BufferIndex += 4 ;
@@ -478,6 +618,7 @@ yyBuffer.prototype.yyb_read = function(_type) {
478
618
res = this . m_DataView . getFloat64 ( this . m_BufferIndex , true ) ;
479
619
this . m_BufferIndex += 8 ;
480
620
break ;
621
+
481
622
case eBuffer_U64 :
482
623
var low = this . m_DataView . getUint32 ( this . m_BufferIndex , true ) ;
483
624
this . m_BufferIndex += 4 ;
@@ -1260,6 +1401,11 @@ yyBuffer.prototype.yyb_write = function(_type, _value) {
1260
1401
this . m_DataView . setUint32 ( this . m_BufferIndex , _value , true ) ;
1261
1402
this . m_BufferIndex += 4 ;
1262
1403
break ;
1404
+
1405
+ case eBuffer_F16 :
1406
+ this . m_DataView . yysetFloat16 ( this . m_BufferIndex , _value , true ) ;
1407
+ this . m_BufferIndex += 2 ;
1408
+ break ;
1263
1409
case eBuffer_F32 :
1264
1410
this . m_DataView . setFloat32 ( this . m_BufferIndex , _value , true ) ;
1265
1411
this . m_BufferIndex += 4 ;
@@ -1268,6 +1414,7 @@ yyBuffer.prototype.yyb_write = function(_type, _value) {
1268
1414
this . m_DataView . setFloat64 ( this . m_BufferIndex , _value , true ) ;
1269
1415
this . m_BufferIndex += 8 ;
1270
1416
break ;
1417
+
1271
1418
case eBuffer_U64 :
1272
1419
var int64Val = yyGetInt64 ( _value ) ;
1273
1420
this . m_DataView . setUint32 ( this . m_BufferIndex , int64Val . low , true ) ;
@@ -1336,12 +1483,17 @@ yyBuffer.prototype.yyb_peek = function(_type, _offset) {
1336
1483
case eBuffer_U32 :
1337
1484
res = this . m_DataView . getUint32 ( _offset , true ) ;
1338
1485
break ;
1486
+
1487
+ case eBuffer_F16 :
1488
+ res = this . m_DataView . yygetFloat16 ( _offset , true ) ;
1489
+ break ;
1339
1490
case eBuffer_F32 :
1340
1491
res = this . m_DataView . getFloat32 ( _offset , true ) ;
1341
1492
break ;
1342
1493
case eBuffer_F64 :
1343
1494
res = this . m_DataView . getFloat64 ( _offset , true ) ;
1344
1495
break ;
1496
+
1345
1497
case eBuffer_U64 :
1346
1498
var low = this . m_DataView . getUint32 ( _offset , true ) ;
1347
1499
var high = this . m_DataView . getUint32 ( _offset + 4 , true ) ;
0 commit comments