2929
3030--- Check if a value is an Int64 (created by bit64 functions).
3131--- @param value any Value to check
32- --- @return boolean isInt64 True if value is an Int64
33- function bit64 .isInt64 (value )
32+ --- @return boolean is_int64 True if value is an Int64
33+ function bit64 .is_int64 (value )
3434 return type (value ) == " table" and getmetatable (value ) == Int64Meta
3535end
3636
@@ -292,17 +292,28 @@ end
292292--- @param strict ? boolean If true , errors when value exceeds 53-bit precision.
293293--- @return number result The value as a Lua number (may lose precision for large values unless strict ).
294294function bit64 .to_number (value , strict )
295+ if type (value ) == " number" then
296+ return value
297+ end
298+ if not bit64 .is_int64 (value ) then
299+ error (" Value is not a valid Int64HighLow pair" , 2 )
300+ end
295301 if strict and value [1 ] > 0x001FFFFF then
296302 error (" Value exceeds 53-bit precision (max: 9007199254740991)" , 2 )
297303 end
298304 return value [1 ] * 0x100000000 + value [2 ]
299305end
300306
301307--- Creates a {high, low} pair from a Lua number.
302- --- @param value number The number to convert.
308+ --- @param value number | Int64HighLow The number to convert ( or Int64HighLow to pass through ) .
303309--- @return Int64HighLow pair The {high_32 , low_32 } pair.
304310function bit64 .from_number (value )
305- local low = value % 0x100000000
311+ if bit64 .is_int64 (value ) then
312+ --- @cast value Int64HighLow
313+ return value
314+ end
315+ --- @cast value - Int64HighLow
316+ local low = math.floor (value % 0x100000000 )
306317 local high = math.floor (value / 0x100000000 )
307318 return bit64 .new (high , low )
308319end
@@ -338,6 +349,9 @@ bit64.lsl = bit64.lshift
338349--- Alias for arshift (compatibility with older API).
339350bit64 .asr = bit64 .arshift
340351
352+ --- Alias for is_int64 (compatibility with older API).
353+ bit64 .isInt64 = bit64 .is_int64
354+
341355---- ----------------------------------------------------------------------------
342356-- Self-test
343357---- ----------------------------------------------------------------------------
@@ -653,19 +667,19 @@ function bit64.selftest()
653667 {
654668 name = " to_number({0x00000000, 0x00000001})" ,
655669 fn = bit64 .to_number ,
656- inputs = { { 0x00000000 , 0x00000001 } },
670+ inputs = { bit64 . new ( 0x00000000 , 0x00000001 ) },
657671 expected = 1 ,
658672 },
659673 {
660674 name = " to_number({0x00000000, 0xFFFFFFFF})" ,
661675 fn = bit64 .to_number ,
662- inputs = { { 0x00000000 , 0xFFFFFFFF } },
676+ inputs = { bit64 . new ( 0x00000000 , 0xFFFFFFFF ) },
663677 expected = 4294967295 ,
664678 },
665679 {
666680 name = " to_number({0x00000001, 0x00000000})" ,
667681 fn = bit64 .to_number ,
668- inputs = { { 0x00000001 , 0x00000000 } },
682+ inputs = { bit64 . new ( 0x00000001 , 0x00000000 ) },
669683 expected = 4294967296 ,
670684 },
671685
@@ -703,13 +717,13 @@ function bit64.selftest()
703717 {
704718 name = " to_number({0x001FFFFF, 0xFFFFFFFF}, true) -- max 53-bit" ,
705719 fn = bit64 .to_number ,
706- inputs = { { 0x001FFFFF , 0xFFFFFFFF } , true },
720+ inputs = { bit64 . new ( 0x001FFFFF , 0xFFFFFFFF ) , true },
707721 expected = 9007199254740991 ,
708722 },
709723 {
710724 name = " to_number({0, 1}, true)" ,
711725 fn = bit64 .to_number ,
712- inputs = { { 0 , 1 } , true },
726+ inputs = { bit64 . new ( 0 , 1 ) , true },
713727 expected = 1 ,
714728 },
715729 }
@@ -734,16 +748,21 @@ function bit64.selftest()
734748 print (" PASS: " .. test .name )
735749 passed = passed + 1
736750 else
737- local exp_hex , got_hex = " " , " "
738- for i = 1 , # test .expected do
739- exp_hex = exp_hex .. string.format (" %02X" , string.byte (test .expected , i ))
740- end
741- for i = 1 , # result do
742- got_hex = got_hex .. string.format (" %02X" , string.byte (result , i ))
743- end
744751 print (" FAIL: " .. test .name )
745- print (" Expected: " .. exp_hex )
746- print (" Got: " .. got_hex )
752+ if type (result ) ~= " string" then
753+ print (" Expected: string" )
754+ print (" Got: " .. type (result ))
755+ else
756+ local exp_hex , got_hex = " " , " "
757+ for i = 1 , # test .expected do
758+ exp_hex = exp_hex .. string.format (" %02X" , string.byte (test .expected , i ))
759+ end
760+ for i = 1 , # result do
761+ got_hex = got_hex .. string.format (" %02X" , string.byte (result , i ))
762+ end
763+ print (" Expected: " .. exp_hex )
764+ print (" Got: " .. got_hex )
765+ end
747766 end
748767 else
749768 if result == test .expected then
@@ -763,7 +782,7 @@ function bit64.selftest()
763782 -- Test bit64.new() creates Int64 values
764783 total = total + 1
765784 local new_val = bit64 .new (0x12345678 , 0x9ABCDEF0 )
766- if bit64 .isInt64 (new_val ) and new_val [1 ] == 0x12345678 and new_val [2 ] == 0x9ABCDEF0 then
785+ if bit64 .is_int64 (new_val ) and new_val [1 ] == 0x12345678 and new_val [2 ] == 0x9ABCDEF0 then
767786 print (" PASS: new() creates Int64 with correct values" )
768787 passed = passed + 1
769788 else
@@ -773,30 +792,30 @@ function bit64.selftest()
773792 -- Test bit64.new() with defaults
774793 total = total + 1
775794 local zero_val = bit64 .new ()
776- if bit64 .isInt64 (zero_val ) and zero_val [1 ] == 0 and zero_val [2 ] == 0 then
795+ if bit64 .is_int64 (zero_val ) and zero_val [1 ] == 0 and zero_val [2 ] == 0 then
777796 print (" PASS: new() with no args creates {0, 0}" )
778797 passed = passed + 1
779798 else
780799 print (" FAIL: new() with no args creates {0, 0}" )
781800 end
782801
783- -- Test isInt64 () returns false for regular tables
802+ -- Test is_int64 () returns false for regular tables
784803 total = total + 1
785804 local plain_table = { 0x12345678 , 0x9ABCDEF0 }
786- if not bit64 .isInt64 (plain_table ) then
787- print (" PASS: isInt64 () returns false for plain table" )
805+ if not bit64 .is_int64 (plain_table ) then
806+ print (" PASS: is_int64 () returns false for plain table" )
788807 passed = passed + 1
789808 else
790- print (" FAIL: isInt64 () returns false for plain table" )
809+ print (" FAIL: is_int64 () returns false for plain table" )
791810 end
792811
793- -- Test isInt64 () returns false for non-tables
812+ -- Test is_int64 () returns false for non-tables
794813 total = total + 1
795- if not bit64 .isInt64 (123 ) and not bit64 .isInt64 (" string" ) and not bit64 .isInt64 (nil ) then
796- print (" PASS: isInt64 () returns false for non-tables" )
814+ if not bit64 .is_int64 (123 ) and not bit64 .is_int64 (" string" ) and not bit64 .is_int64 (nil ) then
815+ print (" PASS: is_int64 () returns false for non-tables" )
797816 passed = passed + 1
798817 else
799- print (" FAIL: isInt64 () returns false for non-tables" )
818+ print (" FAIL: is_int64 () returns false for non-tables" )
800819 end
801820
802821 -- Test all operations return Int64 values
@@ -878,7 +897,7 @@ function bit64.selftest()
878897 for _ , op in ipairs (ops_returning_int64 ) do
879898 total = total + 1
880899 local result = op .fn ()
881- if bit64 .isInt64 (result ) then
900+ if bit64 .is_int64 (result ) then
882901 print (" PASS: " .. op .name .. " () returns Int64" )
883902 passed = passed + 1
884903 else
@@ -890,9 +909,9 @@ function bit64.selftest()
890909 print (" \n Running to_number strict mode tests..." )
891910 total = total + 1
892911 local ok , err = pcall (function ()
893- bit64 .to_number ({ 0x00200000 , 0x00000000 } , true ) -- 2^53, exceeds 53-bit
912+ bit64 .to_number (bit64 . new ( 0x00200000 , 0x00000000 ) , true ) -- 2^53, exceeds 53-bit
894913 end )
895- if not ok and string.find (err , " 53%-bit precision" ) then
914+ if not ok and type ( err ) == " string " and string.find (err , " 53%-bit precision" ) then
896915 print (" PASS: to_number strict mode errors on values > 53 bits" )
897916 passed = passed + 1
898917 else
0 commit comments