@@ -242,12 +242,21 @@ class KaitaiStream {
242242 }
243243
244244 /**
245- * Reads a 64-bit big-endian unsigned int from the stream. Note that
246- * JavaScript does not support 64-bit integers natively, so it will
247- * automatically upgrade internal representation to use IEEE 754
248- * double precision float.
245+ * Reads a 64-bit big-endian signed int from the stream and returns it as
246+ * a {@link Number}.
249247 *
250- * @returns The read number.
248+ * Note that the {@link Number} type in JavaScript cannot accurately represent
249+ * 64-bit integers, as it is an IEEE 754 double-precision floating-point
250+ * number, which has a precision of only 53 bits. Therefore, integers greater
251+ * than {@link Number.MAX_SAFE_INTEGER} (`2**53 - 1` or
252+ * `0x001f_ffff_ffff_ffff`) or less than {@link Number.MIN_SAFE_INTEGER}
253+ * (`-2**53 + 1` or `-0x001f_ffff_ffff_ffff`) will be rounded, with a maximum
254+ * rounding error of +- 512 for values above `2**62` or below `-2**62`. If
255+ * this loss of precision is unacceptable, use {@link readS8beAsBigInt}
256+ * instead.
257+ *
258+ * @returns The 64-bit signed integer read from the stream, potentially rounded.
259+ * @see {@link readS8beAsBigInt }
251260 */
252261 public readS8be ( ) : number {
253262 this . alignToByte ( ) ;
@@ -263,6 +272,24 @@ class KaitaiStream {
263272 }
264273 }
265274
275+ /**
276+ * Reads a 64-bit big-endian signed int from the stream and returns it as
277+ * a {@link BigInt}.
278+ *
279+ * Unlike {@link readS8be}, this method returns the exact value without any
280+ * loss of precision. This is made possible by the {@link BigInt} type.
281+ *
282+ * @returns The exact 64-bit signed integer read from the stream.
283+ * @see {@link readS8be }
284+ */
285+ public readS8beAsBigInt ( ) : bigint {
286+ this . alignToByte ( ) ;
287+ this . ensureBytesLeft ( 8 ) ;
288+ const v = this . _dataView . getBigInt64 ( this . pos ) ;
289+ this . pos += 8 ;
290+ return v ;
291+ }
292+
266293 // ........................................................................
267294 // Little-endian
268295 // ........................................................................
@@ -294,12 +321,21 @@ class KaitaiStream {
294321 }
295322
296323 /**
297- * Reads a 64-bit little-endian unsigned int from the stream. Note that
298- * JavaScript does not support 64-bit integers natively, so it will
299- * automatically upgrade internal representation to use IEEE 754
300- * double precision float.
324+ * Reads a 64-bit little-endian signed int from the stream and returns it as
325+ * a {@link Number}.
301326 *
302- * @returns The read number.
327+ * Note that the {@link Number} type in JavaScript cannot accurately represent
328+ * 64-bit integers, as it is an IEEE 754 double-precision floating-point
329+ * number, which has a precision of only 53 bits. Therefore, integers greater
330+ * than {@link Number.MAX_SAFE_INTEGER} (`2**53 - 1` or
331+ * `0x001f_ffff_ffff_ffff`) or less than {@link Number.MIN_SAFE_INTEGER}
332+ * (`-2**53 + 1` or `-0x001f_ffff_ffff_ffff`) will be rounded, with a maximum
333+ * rounding error of +- 512 for values above `2**62` or below `-2**62`. If
334+ * this loss of precision is unacceptable, use {@link readS8leAsBigInt}
335+ * instead.
336+ *
337+ * @returns The 64-bit signed integer read from the stream, potentially rounded.
338+ * @see {@link readS8leAsBigInt }
303339 */
304340 public readS8le ( ) : number {
305341 this . alignToByte ( ) ;
@@ -315,6 +351,24 @@ class KaitaiStream {
315351 }
316352 }
317353
354+ /**
355+ * Reads a 64-bit little-endian signed int from the stream and returns it as
356+ * a {@link BigInt}.
357+ *
358+ * Unlike {@link readS8le}, this method returns the exact value without any
359+ * loss of precision. This is made possible by the {@link BigInt} type.
360+ *
361+ * @returns The exact 64-bit signed integer read from the stream.
362+ * @see {@link readS8le }
363+ */
364+ public readS8leAsBigInt ( ) : bigint {
365+ this . alignToByte ( ) ;
366+ this . ensureBytesLeft ( 8 ) ;
367+ const v = this . _dataView . getBigInt64 ( this . pos , true ) ;
368+ this . pos += 8 ;
369+ return v ;
370+ }
371+
318372 // ------------------------------------------------------------------------
319373 // Unsigned
320374 // ------------------------------------------------------------------------
@@ -363,12 +417,19 @@ class KaitaiStream {
363417 }
364418
365419 /**
366- * Reads a 64-bit big-endian unsigned int from the stream. Note that
367- * JavaScript does not support 64-bit integers natively, so it will
368- * automatically upgrade internal representation to use IEEE 754
369- * double precision float.
420+ * Reads a 64-bit big-endian unsigned int from the stream and returns it as
421+ * a {@link Number}.
370422 *
371- * @returns The read number.
423+ * Note that the {@link Number} type in JavaScript cannot accurately represent
424+ * 64-bit integers, as it is an IEEE 754 double-precision floating-point
425+ * number, which has a precision of only 53 bits. Therefore, integers greater
426+ * than {@link Number.MAX_SAFE_INTEGER} (`2**53 - 1` or
427+ * `0x001f_ffff_ffff_ffff`) will be rounded, with a maximum rounding error of
428+ * +- 1024 for values above `2**63`. If this loss of precision is
429+ * unacceptable, use {@link readU8beAsBigInt} instead.
430+ *
431+ * @returns The 64-bit unsigned integer read from the stream, potentially rounded.
432+ * @see {@link readU8beAsBigInt }
372433 */
373434 public readU8be ( ) : number {
374435 this . alignToByte ( ) ;
@@ -378,6 +439,24 @@ class KaitaiStream {
378439 return 0x100000000 * v1 + v2 ;
379440 }
380441
442+ /**
443+ * Reads a 64-bit big-endian unsigned int from the stream and returns it as
444+ * a {@link BigInt}.
445+ *
446+ * Unlike {@link readU8be}, this method returns the exact value without any
447+ * loss of precision. This is made possible by the {@link BigInt} type.
448+ *
449+ * @returns The exact 64-bit unsigned integer read from the stream.
450+ * @see {@link readU8be }
451+ */
452+ public readU8beAsBigInt ( ) : bigint {
453+ this . alignToByte ( ) ;
454+ this . ensureBytesLeft ( 8 ) ;
455+ const v = this . _dataView . getBigUint64 ( this . pos ) ;
456+ this . pos += 8 ;
457+ return v ;
458+ }
459+
381460 // ........................................................................
382461 // Little-endian
383462 // ........................................................................
@@ -409,12 +488,19 @@ class KaitaiStream {
409488 }
410489
411490 /**
412- * Reads a 64-bit little-endian unsigned int from the stream. Note that
413- * JavaScript does not support 64-bit integers natively, so it will
414- * automatically upgrade internal representation to use IEEE 754
415- * double precision float.
491+ * Reads a 64-bit little-endian unsigned int from the stream and returns it as
492+ * a {@link Number}.
416493 *
417- * @returns The read number.
494+ * Note that the {@link Number} type in JavaScript cannot accurately represent
495+ * 64-bit integers, as it is an IEEE 754 double-precision floating-point
496+ * number, which has a precision of only 53 bits. Therefore, integers greater
497+ * than {@link Number.MAX_SAFE_INTEGER} (`2**53 - 1` or
498+ * `0x001f_ffff_ffff_ffff`) will be rounded, with a maximum rounding error of
499+ * +- 1024 for values above `2**63`. If this loss of precision is
500+ * unacceptable, use {@link readU8leAsBigInt} instead.
501+ *
502+ * @returns The 64-bit unsigned integer read from the stream, potentially rounded.
503+ * @see {@link readU8leAsBigInt }
418504 */
419505 public readU8le ( ) : number {
420506 this . alignToByte ( ) ;
@@ -424,6 +510,24 @@ class KaitaiStream {
424510 return 0x100000000 * v2 + v1 ;
425511 }
426512
513+ /**
514+ * Reads a 64-bit little-endian unsigned int from the stream and returns it as
515+ * a {@link BigInt}.
516+ *
517+ * Unlike {@link readU8le}, this method returns the exact value without any
518+ * loss of precision. This is made possible by the {@link BigInt} type.
519+ *
520+ * @returns The exact 64-bit unsigned integer read from the stream.
521+ * @see {@link readU8le }
522+ */
523+ public readU8leAsBigInt ( ) : bigint {
524+ this . alignToByte ( ) ;
525+ this . ensureBytesLeft ( 8 ) ;
526+ const v = this . _dataView . getBigUint64 ( this . pos , true ) ;
527+ this . pos += 8 ;
528+ return v ;
529+ }
530+
427531 // ========================================================================
428532 // Floating point numbers
429533 // ========================================================================
0 commit comments