local int64 = require("../init")

local PADDING_STRING = "\a\b\f\n\r\t\v\255\69\127"

-- Constants

assert(int64.ZERO.x == 0, "int64.ZERO x component was wrong")
assert(int64.ZERO.y == 0, "int64.ZERO y component was wrong")
assert(int64.ZERO.z == 0, "int64.ZERO z component was wrong")

assert(int64.ONE.x == 0, "int64.ONE x component was wrong")
assert(int64.ONE.y == 0, "int64.ONE y component was wrong")
assert(int64.ONE.z == 1, "int64.ONE z component was wrong")

assert(int64.TWO.x == 0, "int64.TWO x component was wrong")
assert(int64.TWO.y == 0, "int64.TWO y component was wrong")
assert(int64.TWO.z == 2, "int64.TWO z component was wrong")

assert(int64.MAX.x == 2 ^ 22 - 1, "int64.MAX x component was wrong")
assert(int64.MAX.y == 2 ^ 20 - 1, "int64.MAX y component was wrong")
assert(int64.MAX.z == 2 ^ 22 - 1, "int64.MAX z component was wrong")

assert(int64.MAX_U32.x == 0, "int64.MAX_U32 x component was wrong")
assert(int64.MAX_U32.y == 2 ^ 10 - 1, "int64.MAX_U32 y component was wrong")
assert(int64.MAX_U32.z == 2 ^ 22 - 1, "int64.MAX_U32 z component was wrong")

assert(int64.MAX_F64.x == 0b0000000000100000000000, "int64.MAX_F64 x component was wrong")
assert(int64.MAX_F64.y == 0b00000000000000000000, "int64.MAX_F64 y component was wrong")
assert(int64.MAX_F64.z == 0b0000000000000000000000, "int64.MAX_F64 z component was wrong")

assert(int64.MAX_F32.x == 0b0000000000000000000000, "int64.MAX_F32 x component was wrong")
assert(int64.MAX_F32.y == 0b00000000000000000100, "int64.MAX_F32 y component was wrong")
assert(int64.MAX_F32.z == 0b0000000000000000000000, "int64.MAX_F32 z component was wrong")

-- Constructors

local from_pair_1 = int64.from_pair(0, 0)
assert(from_pair_1.x == 0, "from_pair(0, 0) x component was wrong")
assert(from_pair_1.y == 0, "from_pair(0, 0) y component was wrong")
assert(from_pair_1.z == 0, "from_pair(0, 0) z component was wrong")

local from_pair_2 = int64.from_pair(0, 10)
assert(from_pair_2.x == 0, "from_pair(0, 10) x component was wrong")
assert(from_pair_2.y == 0, "from_pair(0, 10) y component was wrong")
assert(from_pair_2.z == 10, "from_pair(0, 10) z component was wrong")

local from_pair_3 = int64.from_pair(0xffffffff, 0xffffffff)
assert(from_pair_3.x == 2 ^ 22 - 1, "from_pair(0xffffffff, 0xffffffff) x component was wrong")
assert(from_pair_3.y == 2 ^ 20 - 1, "from_pair(0xffffffff, 0xffffffff) y component was wrong")
assert(from_pair_3.z == 2 ^ 22 - 1, "from_pair(0xffffffff, 0xffffffff) z component was wrong")

local from_pair_4 = int64.from_pair(0xdeadbeef, 0x98765432)
assert(from_pair_4.x == 0b1101111010101101101111, "from_pair(0xdeadbeef, 0x98765432) x component was wrong")
assert(from_pair_4.y == 0b10111011111001100001, "from_pair(0xdeadbeef, 0x98765432) y component was wrong")
assert(from_pair_4.z == 0b1101100101010000110010, "from_pair(0xdeadbeef, 0x98765432) z component was wrong")

local from_pair_5 = int64.from_pair(0x100000000, 0x100000000)
assert(from_pair_5.x == 0, "from_pair(0x100000000, 0x100000000) x component was wrong")
assert(from_pair_5.y == 0, "from_pair(0x100000000, 0x100000000) y component was wrong")
assert(from_pair_5.z == 0, "from_pair(0x100000000, 0x100000000) z component was wrong")

local from_u32_1 = int64.from_u32(0)
assert(from_u32_1.x == 0, "from_u32(0) x component was wrong")
assert(from_u32_1.y == 0, "from_u32(0) y component was wrong")
assert(from_u32_1.z == 0, "from_u32(0) z component was wrong")

local from_u32_2 = int64.from_u32(10)
assert(from_u32_2.x == 0, "from_u32(10) x component was wrong")
assert(from_u32_2.y == 0, "from_u32(10) y component was wrong")
assert(from_u32_2.z == 10, "from_u32(10) z component was wrong")

local from_u32_3 = int64.from_u32(0xffffffff)
assert(from_u32_3.x == 0, "from_u32(0xffffffff) x component was wrong")
assert(from_u32_3.y == 2 ^ 10 - 1, "from_u32(0xffffffff) y component was wrong")
assert(from_u32_3.z == 2 ^ 22 - 1, "from_u32(0xffffffff) z component was wrong")

local from_u32_4 = int64.from_u32(0xdeadbeef)
assert(from_u32_4.x == 0b0000000000000000000000, "from_u32(0xdeadbeef) x component was wrong")
assert(from_u32_4.y == 0b00000000001101111010, "from_u32(0xdeadbeef) y component was wrong")
assert(from_u32_4.z == 0b1011011011111011101111, "from_u32(0xdeadbeef) z component was wrong")

local from_u32_5 = int64.from_u32(0x100000000)
assert(from_u32_5.x == 0, "from_u32(0x100000000) x component was wrong")
assert(from_u32_5.y == 0, "from_u32(0x100000000) y component was wrong")
assert(from_u32_5.z == 0, "from_u32(0x100000000) z component was wrong")

local from_f64_1 = int64.from_f64(0)
assert(from_f64_1 == from_u32_1, "from_f64(0) was not correct")

local from_f64_2 = int64.from_f64(10)
assert(from_f64_2 == from_u32_2, "from_f64(10) was not correct")

local from_f64_3 = int64.from_f64(0xffffffff)
assert(from_f64_3 == from_u32_3, "from_f64(0xffffffff) was not correct")

local from_f64_4 = int64.from_f64(0xdeadbeef)
assert(from_f64_4 == from_u32_4, "from_f64(0xdeadbeef) was not correct")

local from_f64_5 = int64.from_f64(0x100000000)
assert(from_f64_5.x == 0b000000000000000000000, "from_f64(0x100000000) x component was wrong")
assert(from_f64_5.y == 0b00000000010000000000, "from_f64(0x100000000) y component was wrong")
assert(from_f64_5.z == 0b0000000000000000000000, "from_f64(0x100000000) z component was wrong")

local from_f64_6 = int64.from_f64(0x1337_deadbeef)
assert(from_f64_6.x == 0b0000000000000000000100, "from_f64(0x1337deadbeef) x component was wrong")
assert(from_f64_6.y == 0b11001101111101111010, "from_f64(0x1337deadbeef) y component was wrong")
assert(from_f64_6.z == 0b1011011011111011101111, "from_f64(0x1337deadbeef) z component was wrong")

local from_f64_7 = int64.from_f64(0x20000000000000)
assert(from_f64_7.x == 0b0000000000100000000000, "from_f64(0x20000000000000) x component was wrong")
assert(from_f64_7.y == 0b00000000000000000000, "from_f64(0x20000000000000) y component was wrong")
assert(from_f64_7.z == 0b0000000000000000000000, "from_f64(0x20000000000000) z component was wrong")

local from_f64_8 = int64.from_f64(math.pi)
assert(from_f64_8.x == 0, "from_f64(math.pi) x component was wrong")
assert(from_f64_8.y == 0, "from_f64(math.pi) y component was wrong")
assert(from_f64_8.z == 3, "from_f64(math.pi) z component was wrong")

local from_byte_string_1_input = "\0\0\0\0\0\0\0\0"
local from_byte_string_1 = int64.from_byte_string(from_byte_string_1_input)
assert(
	int64.from_byte_string(PADDING_STRING .. from_byte_string_1_input, 11) == from_byte_string_1,
	"offset did not work for from_byte_string_1"
)
assert(from_byte_string_1.x == 0, "from_byte_string_1 x component was wrong")
assert(from_byte_string_1.y == 0, "from_byte_string_1 y component was wrong")
assert(from_byte_string_1.z == 0, "from_byte_string_1 z component was wrong")

local from_byte_string_2_input = "\x01\0\0\0\0\0\0\0"
local from_byte_string_2 = int64.from_byte_string(from_byte_string_2_input)
assert(
	int64.from_byte_string(PADDING_STRING .. from_byte_string_2_input, 11) == from_byte_string_2,
	"offset did not work for from_byte_string_2"
)
assert(from_byte_string_2.x == 0, "from_byte_string_2 x component was wrong")
assert(from_byte_string_2.y == 0, "from_byte_string_2 y component was wrong")
assert(from_byte_string_2.z == 1, "from_byte_string_2 z component was wrong")

local from_byte_string_3_input = "\x80\x80\x80\x80\x80\x80\x80\x80"
local from_byte_string_3 = int64.from_byte_string(from_byte_string_3_input)
assert(
	int64.from_byte_string(PADDING_STRING .. from_byte_string_3_input, 11) == from_byte_string_3,
	"offset did not work for from_byte_string_3"
)
assert(from_byte_string_3.x == 0b1000000010000000100000, "from_byte_string_3 x component was wrong")
assert(from_byte_string_3.y == 0b00100000001000000010, "from_byte_string_3 y component was wrong")
assert(from_byte_string_3.z == 0b0000001000000010000000, "from_byte_string_3 z component was wrong")

local from_buffer_1 = buffer.fromstring(from_byte_string_1_input)
local from_buffer_1_offset = buffer.fromstring(PADDING_STRING .. from_byte_string_1_input)
assert(int64.from_buffer(from_buffer_1) == from_byte_string_1, "from_buffer_1 was not correct")
assert(int64.from_buffer(from_buffer_1_offset, 10) == from_byte_string_1, "offset did not work for from_buffer_1")

local from_buffer_2 = buffer.fromstring(from_byte_string_2_input)
local from_buffer_2_offset = buffer.fromstring(PADDING_STRING .. from_byte_string_2_input)
assert(int64.from_buffer(from_buffer_2) == from_byte_string_2, "from_buffer_1 was not correct")
assert(int64.from_buffer(from_buffer_2_offset, 10) == from_byte_string_2, "offset did not work for from_buffer_2")

local from_buffer_3 = buffer.fromstring(from_byte_string_3_input)
local from_buffer_3_offset = buffer.fromstring(PADDING_STRING .. from_byte_string_3_input)
assert(int64.from_buffer(from_buffer_3) == from_byte_string_3, "from_buffer_3 was not correct")
assert(int64.from_buffer(from_buffer_3_offset, 10) == from_byte_string_3, "offset did not work for from_buffer_3")

-- Deconstructors

local to_pair_1 = { int64.to_pair(from_pair_1) }
assert(to_pair_1[1] == 0, "to_pair_1 first result is wrong")
assert(to_pair_1[2] == 0, "to_pair_1 second result is wrong")

local to_pair_2 = { int64.to_pair(from_pair_2) }
assert(to_pair_2[1] == 0, "to_pair_2 first result is wrong")
assert(to_pair_2[2] == 10, "to_pair_2 second result is wrong")

local to_pair_3 = { int64.to_pair(from_pair_3) }
assert(to_pair_3[1] == 0xffffffff, "to_pair_3 first result is wrong")
assert(to_pair_3[2] == 0xffffffff, "to_pair_3 second result is wrong")

local to_pair_4 = { int64.to_pair(from_pair_4) }
assert(to_pair_4[1] == 0xdeadbeef, "to_pair_4 first result is wrong")
assert(to_pair_4[2] == 0x98765432, "to_pair_4 second result is wrong")

local to_pair_5 = { int64.to_pair(from_pair_5) }
assert(to_pair_5[1] == 0, "to_pair_5 first result is wrong")
assert(to_pair_5[1] == 0, "to_pair_5 second result is wrong")

local to_quartet_1 = { int64.to_quartet(from_pair_1) }
assert(to_quartet_1[1] == 0, "to_quartet_1 first result is wrong")
assert(to_quartet_1[2] == 0, "to_quartet_1 second result is wrong")
assert(to_quartet_1[3] == 0, "to_quartet_1 third result is wrong")
assert(to_quartet_1[4] == 0, "to_quartet_1 fourth result is wrong")

local to_quartet_2 = { int64.to_quartet(from_pair_2) }
assert(to_quartet_2[1] == 0, "to_quartet_2 first result is wrong")
assert(to_quartet_2[2] == 0, "to_quartet_2 second result is wrong")
assert(to_quartet_2[3] == 0, "to_quartet_2 third result is wrong")
assert(to_quartet_2[4] == 10, "to_quartet_2 fourth result is wrong")

local to_quartet_3 = { int64.to_quartet(from_pair_3) }
assert(to_quartet_3[1] == 0xffff, "to_quartet_3 first result is wrong")
assert(to_quartet_3[2] == 0xffff, "to_quartet_3 second result is wrong")
assert(to_quartet_3[3] == 0xffff, "to_quartet_3 third result is wrong")
assert(to_quartet_3[4] == 0xffff, "to_quartet_3 fourth result is wrong")

local to_quartet_4 = { int64.to_quartet(from_pair_4) }
assert(to_quartet_4[1] == 0xdead, "to_quartet_4 first result is wrong")
assert(to_quartet_4[2] == 0xbeef, "to_quartet_4 second result is wrong")
assert(to_quartet_4[3] == 0x9876, "to_quartet_4 third result is wrong")
assert(to_quartet_4[4] == 0x5432, "to_quartet_4 fourth result is wrong")

local to_quartet_5 = { int64.to_quartet(from_pair_5) }
assert(to_quartet_5[1] == 0, "to_quartet_5 first result is wrong")
assert(to_quartet_5[1] == 0, "to_quartet_5 second result is wrong")
assert(to_quartet_5[3] == 0, "to_quartet_5 third result is wrong")
assert(to_quartet_5[4] == 0, "to_quartet_5 fourth result is wrong")

local to_f64_1 = int64.to_f64(from_f64_1)
assert(to_f64_1 == 0, "to_f64_1 was not correct")

local to_f64_2 = int64.to_f64(from_f64_2)
assert(to_f64_2 == 10, "to_f64_2 was not correct")

local to_f64_3 = int64.to_f64(from_f64_3)
assert(to_f64_3 == 0xffffffff, "to_f64_3 was not correct")

local to_f64_4 = int64.to_f64(from_f64_4)
assert(to_f64_4 == 0xdeadbeef, "to_f64_4 was not correct")

local to_f64_5 = int64.to_f64(from_f64_5)
assert(to_f64_5 == 0x100000000, "to_f64_5 was not correct")

local to_f64_6 = int64.to_f64(from_f64_6)
assert(to_f64_6 == 0x1337_deadbeef, "to_f64_6 was not correct")

local to_f64_7 = int64.to_f64(from_f64_7)
assert(to_f64_7 == 0x20000000000000, "to_f64_7 was not correct")

local to_f64_8 = int64.to_f64(from_f64_8)
assert(to_f64_8 == 3, "to_f64_8 was not correct")

-- Stringifiers

local to_byte_string_1 = int64.to_byte_string(from_byte_string_1)
assert(#to_byte_string_1 == 8, "to_byte_string_1 returned a string that is not 8 bytes")
assert(to_byte_string_1 == from_byte_string_1_input, "to_byte_string_1 is not correct")

local to_byte_string_2 = int64.to_byte_string(from_byte_string_2)
assert(#to_byte_string_2 == 8, "to_byte_string_2 returned a string that is not 8 bytes")
assert(to_byte_string_2 == from_byte_string_2_input, "to_byte_string_2 is not correct")

local to_byte_string_3 = int64.to_byte_string(from_byte_string_3)
assert(#to_byte_string_3 == 8, "to_byte_string_3 returned a string that is not 8 bytes")
assert(to_byte_string_3 == from_byte_string_3_input, "to_byte_string_3 is not correct")

local to_buffer_1 = int64.to_buffer(from_byte_string_1)
assert(buffer.len(to_buffer_1) == 8, "to_buffer_1 returned a buffer that is not 8 bytes")
assert(buffer.tostring(to_buffer_1) == from_byte_string_1_input, "to_buffer_1 is not correct")

local to_buffer_2 = int64.to_buffer(from_byte_string_2)
assert(buffer.len(to_buffer_2) == 8, "to_buffer_2 returned a buffer that is not 8 bytes")
assert(buffer.tostring(to_buffer_2) == from_byte_string_2_input, "to_buffer_2 is not correct")

local to_buffer_3 = int64.to_buffer(from_byte_string_3)
assert(buffer.len(to_buffer_3) == 8, "to_buffer_3 returned a buffer that is not 8 bytes")
assert(buffer.tostring(to_buffer_3) == from_byte_string_3_input, "to_buffer_3 is not correct")

local write_buffer = buffer.create(16)

int64.write_to_buffer(write_buffer, from_byte_string_1, 0)
int64.write_to_buffer(write_buffer, from_byte_string_3, 8)
assert(buffer.readstring(write_buffer, 0, 8) == from_byte_string_1_input, "write_to_buffer 1 was wrong")
assert(buffer.readstring(write_buffer, 8, 8) == from_byte_string_3_input, "write_to_buffer 1 offset by 8 was wrong")

int64.write_to_buffer(write_buffer, from_byte_string_2, 0)
int64.write_to_buffer(write_buffer, from_byte_string_2, 8)
assert(buffer.readstring(write_buffer, 0, 8) == from_byte_string_2_input, "write_to_buffer 2 was wrong")
assert(buffer.readstring(write_buffer, 8, 8) == from_byte_string_2_input, "write_to_buffer 2 offset by 8 was wrong")

int64.write_to_buffer(write_buffer, from_byte_string_3, 0)
int64.write_to_buffer(write_buffer, from_byte_string_1, 8)
assert(buffer.readstring(write_buffer, 0, 8) == from_byte_string_3_input, "write_to_buffer 3 was wrong")
assert(buffer.readstring(write_buffer, 8, 8) == from_byte_string_1_input, "write_to_buffer 3 offset by 8 was wrong")

local to_hex_string_1 = int64.to_hex_string(from_pair_1)
assert(to_hex_string_1 == "0000000000000000", "to_hex_string_1 did not return the expected result")

local to_hex_string_2 = int64.to_hex_string(from_pair_2)
assert(to_hex_string_2 == "000000000000000a", "to_hex_string_2 did not return the expected result")

local to_hex_string_3 = int64.to_hex_string(from_pair_3)
assert(to_hex_string_3 == "ffffffffffffffff", "to_hex_string_3 did not return the expected result")

local to_hex_string_4 = int64.to_hex_string(from_pair_4)
assert(to_hex_string_4 == "deadbeef98765432", "to_hex_string_4 did not return the expected result")

local to_hex_string_5 = int64.to_hex_string(from_pair_5)
assert(to_hex_string_5 == "0000000000000000", "to_hex_string_5 did not return the expected result")

local to_bin_string_1 = int64.to_bin_string(from_pair_1)
assert(
	to_bin_string_1 == "0000000000000000000000000000000000000000000000000000000000000000",
	"to_bin_string_1 did not return the expected result"
)

local to_bin_string_2 = int64.to_bin_string(from_pair_2)
assert(
	to_bin_string_2 == "0000000000000000000000000000000000000000000000000000000000001010",
	"to_bin_string_2 did not return the expected result"
)

local to_bin_string_3 = int64.to_bin_string(from_pair_3)
assert(
	to_bin_string_3 == "1111111111111111111111111111111111111111111111111111111111111111",
	"to_bin_string_3 did not return the expected result"
)

local to_bin_string_4 = int64.to_bin_string(from_pair_4)
assert(
	to_bin_string_4 == "1101111010101101101111101110111110011000011101100101010000110010",
	"to_bin_string_4 did not return the expected result"
)

local to_bin_string_5 = int64.to_bin_string(from_pair_5)
assert(
	to_bin_string_5 == "0000000000000000000000000000000000000000000000000000000000000000",
	"to_bin_string_5 did not return the expected result"
)

-- to_binary_string relies upon a mapping of hex characters to binary digits
-- and we should ensure they're correct.
for i = 0, 255 do
	local u64 = int64.from_u32(i)
	local hex_string = int64.to_hex_string(u64)
	local bin_string = int64.to_bin_string(u64)

	assert(tonumber(hex_string, 16) == i, `hex string produced by {i} was wrong`)
	assert(tonumber(bin_string, 2) == i, `binary string produced by {i} was wrong`)
end

-- LT/LTE

local lt_1 = int64.lt(int64.from_pair(0, 0), int64.from_pair(0, 0))
assert(not lt_1, "lt_1 returned the wrong result")

local lt_2 = int64.lt(int64.from_pair(0, 0), int64.from_pair(0, 1))
assert(lt_2, "lt_2 returned the wrong result")

local lt_3 = int64.lt(int64.from_pair(0, 1), int64.from_pair(0, 0))
assert(not lt_3, "lt_3 returned the wrong result")

local lt_4 = int64.lt(int64.from_pair(0, 0), int64.from_pair(0xffffffff, 0xffffffff))
assert(lt_4, "lt_4 returned the wrong result")

local lt_5 = int64.lt(int64.from_pair(0xffffffff, 0xffffffff), int64.from_pair(0, 0))
assert(not lt_5, "lt_5 returned the wrong result")

local lt_6 = int64.lt(int64.from_pair(0xffffffff, 0xfffffffe), int64.from_pair(0xffffffff, 0xffffffff))
assert(lt_6, "lt_6 returned the wrong result")

local lte_1 = int64.lt_equal(int64.from_pair(0, 0), int64.from_pair(0, 0))
assert(lte_1, "lte_1 returned the wrong result")

local lte_2 = int64.lt_equal(int64.from_pair(0, 0), int64.from_pair(0, 1))
assert(lte_2, "lte_2 returned the wrong result")

local lte_3 = int64.lt_equal(int64.from_pair(0, 1), int64.from_pair(0, 0))
assert(not lte_3, "lte_3 returned the wrong result")

local lte_4 = int64.lt_equal(int64.from_pair(0, 0), int64.from_pair(0xffffffff, 0xffffffff))
assert(lte_4, "lte_4 returned the wrong result")

local lte_5 = int64.lt_equal(int64.from_pair(0xffffffff, 0xffffffff), int64.from_pair(0, 0))
assert(not lte_5, "lte_5 returned the wrong result")

local lte_6 = int64.lt_equal(int64.from_pair(0xffffffff, 0xfffffffe), int64.from_pair(0xffffffff, 0xffffffff))
assert(lte_6, "lte_6 returned the wrong result")

local lte_7 = int64.lt_equal(int64.from_pair(0xffffffff, 0xffffffff), int64.from_pair(0xffffffff, 0xffffffff))
assert(lte_7, "lte_7 returned the wrong result")

local lte_8 = int64.lt_equal(int64.from_pair(0, 0x13371337), int64.from_pair(0, 0xdeadbeef))
assert(lte_8, "lte_8 returned the wrong result")

local lte_9 = int64.lt_equal(int64.from_pair(0, 0xdeadbeef), int64.from_pair(0, 0xdeadbeef))
assert(lte_9, "lte_9 returned the wrong result")

-- GT/GTE

local gt_1 = int64.gt(int64.from_pair(0, 0), int64.from_pair(0, 0))
assert(not gt_1, "gt_1 returned the wrong result")

local gt_2 = int64.gt(int64.from_pair(0, 1), int64.from_pair(0, 0))
assert(gt_2, "gt_2 returned the wrong result")

local gt_3 = int64.gt(int64.from_pair(0, 0), int64.from_pair(0, 1))
assert(not gt_3, "gt_3 returned the wrong result")

local gt_4 = int64.gt(int64.from_pair(0xffffffff, 0xffffffff), int64.from_pair(0, 0))
assert(gt_4, "gt_4 returned the wrong result")

local gt_5 = int64.gt(int64.from_pair(0, 0), int64.from_pair(0xffffffff, 0xffffffff))
assert(not gt_5, "gt_5 returned the wrong result")

local gt_6 = int64.gt(int64.from_pair(0xffffffff, 0xffffffff), int64.from_pair(0xffffffff, 0xfffffffe))
assert(gt_6, "gt_6 returned the wrong result")

local gte_1 = int64.gt_equal(int64.from_pair(0, 0), int64.from_pair(0, 0))
assert(gte_1, "gte_1 returned the wrong result")

local gte_2 = int64.gt_equal(int64.from_pair(0, 1), int64.from_pair(0, 0))
assert(gte_2, "gte_2 returned the wrong result")

local gte_3 = int64.gt_equal(int64.from_pair(0, 0), int64.from_pair(0, 1))
assert(not gte_3, "gte_3 returned the wrong result")

local gte_4 = int64.gt_equal(int64.from_pair(0xffffffff, 0xffffffff), int64.from_pair(0, 0))
assert(gte_4, "gte_4 returned the wrong result")

local gte_5 = int64.gt_equal(int64.from_pair(0, 0), int64.from_pair(0xffffffff, 0xffffffff))
assert(not gte_5, "gte_5 returned the wrong result")

local gte_6 = int64.gt_equal(int64.from_pair(0xffffffff, 0xffffffff), int64.from_pair(0xffffffff, 0xfffffffe))
assert(gte_6, "gte_6 returned the wrong result")

local gte_7 = int64.gt_equal(int64.from_pair(0xffffffff, 0xffffffff), int64.from_pair(0xffffffff, 0xffffffff))
assert(gte_7, "gte_7 returned the wrong result")

local gte_8 = int64.gt_equal(int64.from_pair(0, 0xdeadbeef), int64.from_pair(0, 0x13371337))
assert(gte_8, "gte_8 returned the wrong result")

local gte_9 = int64.gt_equal(int64.from_pair(0, 0xdeadbeef), int64.from_pair(0, 0xdeadbeef))
assert(gte_9, "gte_9 returned the wrong result")

assert(int64.is_zero(int64.ZERO), "is_zero was wrong for int64.ZERO")
assert(int64.is_zero(vector.zero), "is_zero was wrong for zero vector")

assert(not int64.is_zero(int64.ONE), "is_zero was wrong for int64.ONE")
assert(not int64.is_zero(int64.TWO), "is_zero was wrong for int64.TWO")
assert(not int64.is_zero(int64.MAX), "is_zero was wrong for int64.MAX")
assert(not int64.is_zero(int64.MAX_U32), "is_zero was wrong for int64.MAX_U32")
assert(not int64.is_zero(int64.MAX_F64), "is_zero was wrong for int64.MAX_F64")
assert(not int64.is_zero(int64.MAX_F32), "is_zero was wrong for int64.MAX_F32")

assert(int64.is_zero(from_pair_1), "is_zero was wrong for from_pair_1")
assert(not int64.is_zero(from_pair_2), "is_zero was wrong for from_pair_2")
assert(not int64.is_zero(from_pair_3), "is_zero was wrong for from_pair_3")
assert(not int64.is_zero(from_pair_4), "is_zero was wrong for from_pair_4")
assert(int64.is_zero(from_pair_5), "is_zero was wrong for from_pair_5")

assert(int64.is_zero(from_u32_1), "is_zero was wrong for from_u32_1")
assert(not int64.is_zero(from_u32_2), "is_zero was wrong for from_u32_2")
assert(not int64.is_zero(from_u32_3), "is_zero was wrong for from_u32_3")
assert(not int64.is_zero(from_u32_4), "is_zero was wrong for from_u32_4")
assert(int64.is_zero(from_u32_5), "is_zero was wrong for from_u32_5")

assert(int64.is_zero(from_f64_1), "is_zero was wrong for from_f64_1")
assert(not int64.is_zero(from_f64_2), "is_zero was wrong for from_f64_2")
assert(not int64.is_zero(from_f64_3), "is_zero was wrong for from_f64_3")
assert(not int64.is_zero(from_f64_4), "is_zero was wrong for from_f64_4")
assert(not int64.is_zero(from_f64_5), "is_zero was wrong for from_f64_5")
assert(not int64.is_zero(from_f64_6), "is_zero was wrong for from_f64_6")
assert(not int64.is_zero(from_f64_7), "is_zero was wrong for from_f64_7")
assert(not int64.is_zero(from_f64_8), "is_zero was wrong for from_f64_8")

assert(int64.is_zero(from_byte_string_1), "is_zero was wrong for from_byte_string_1")
assert(not int64.is_zero(from_byte_string_2), "is_zero was wrong for from_byte_string_2")
assert(not int64.is_zero(from_byte_string_3), "is_zero was wrong for from_byte_string_3")

local from_dec_string_1 = int64.from_dec_string("0")
assert(int64.to_hex_string(from_dec_string_1) == "0000000000000000", "from_dec_string_1 parsed wrong")

local from_dec_string_2 = int64.from_dec_string("42")
assert(int64.to_hex_string(from_dec_string_2) == "000000000000002a", "from_dec_string_2 parsed wrong")

local from_dec_string_3 = int64.from_dec_string("4294967295")
assert(int64.to_hex_string(from_dec_string_3) == "00000000ffffffff", "from_dec_string_3 parsed wrong")

local from_dec_string_4 = int64.from_dec_string("4294967296")
assert(int64.to_hex_string(from_dec_string_4) == "0000000100000000", "from_dec_string_4 parsed wrong")

local from_dec_string_5 = int64.from_dec_string("9007199254740991")
assert(int64.to_hex_string(from_dec_string_5) == "001fffffffffffff", "from_dec_string_5 parsed wrong")

local from_dec_string_6 = int64.from_dec_string("18446744073709551615")
assert(int64.to_hex_string(from_dec_string_6) == "ffffffffffffffff", "from_dec_string_6 parsed wrong")

local from_dec_string_7 = int64.from_dec_string("12345678901234567890")
assert(int64.to_hex_string(from_dec_string_7) == "ab54a98ceb1f0ad2", "from_dec_string_7 parsed wrong")

local from_dec_string_8 = int64.from_dec_string("18446744073709551557")
assert(int64.to_hex_string(from_dec_string_8) == "ffffffffffffffc5", "from_dec_string_8 parsed wrong")

local from_dec_string_9 = int64.from_dec_string("0000000000000000000001")
assert(int64.to_hex_string(from_dec_string_9) == "0000000000000001", "from_dec_string_9 parsed wrong")

local from_dec_string_10 = int64.from_dec_string("18446744078004518911")
assert(int64.to_hex_string(from_dec_string_10) == "00000000ffffffff", "from_dec_string_10 parsed wrong")

local to_dec_string_1 = int64.to_dec_string(from_dec_string_1)
assert(to_dec_string_1 == "0", "to_dec_string was wrong for '0'")

local to_dec_string_2 = int64.to_dec_string(from_dec_string_2)
assert(to_dec_string_2 == "42", "to_dec_string was wrong for '42'")

local to_dec_string_3 = int64.to_dec_string(from_dec_string_3)
assert(to_dec_string_3 == "4294967295", "to_dec_string was wrong for '4294967295'")

local to_dec_string_4 = int64.to_dec_string(from_dec_string_4)
assert(to_dec_string_4 == "4294967296", "to_dec_string was wrong for '4294967296'")

local to_dec_string_5 = int64.to_dec_string(from_dec_string_5)
assert(to_dec_string_5 == "9007199254740991", "to_dec_string was wrong for '9007199254740991'")

local to_dec_string_6 = int64.to_dec_string(from_dec_string_6)
assert(to_dec_string_6 == "18446744073709551615", "to_dec_string was wrong for '18446744073709551615'")

local to_dec_string_7 = int64.to_dec_string(from_dec_string_7)
assert(to_dec_string_7 == "12345678901234567890", "to_dec_string was wrong for '12345678901234567890'")

local to_dec_string_8 = int64.to_dec_string(from_dec_string_8)
assert(to_dec_string_8 == "18446744073709551557", "to_dec_string was wrong for '18446744073709551557'")

-- from_dec_string_9 and 10 are testing overflow and leading zeros, which we don't want.
-- but we do need to test more values above 2 ^ 53

local to_dec_string_9 = int64.to_dec_string(int64.from_pair(0xaaaaaaaa, 0xaaaaaaaa))
assert(to_dec_string_9 == "12297829382473034410", "to_dec_string was wrong for '12297829382473034410'")

local to_dec_string_10 = int64.to_dec_string(int64.from_pair(0x55555555, 0x55555555))
assert(to_dec_string_10 == "6148914691236517205", "to_dec_string was wrong for '6148914691236517205'")

local to_dec_string_11 = int64.to_dec_string(int64.from_pair(0x00200000, 0x00000000))
assert(to_dec_string_11 == "9007199254740992", "to_dec_string was wrong for '9007199254740992'")

local to_dec_string_12 = int64.to_dec_string(int64.from_pair(0x001fffff, 0xfffffffe))
assert(to_dec_string_12 == "9007199254740990", "to_dec_string was wrong for '9007199254740990'")

--stylua: ignore
local two_pows_above_53 = {
	[54] = "18014398509481984",
	[55] = "36028797018963968",
	[56] = "72057594037927936",
	[57] = "144115188075855872",
	[58] = "288230376151711744",
	[59] = "576460752303423488",
	[60] = "1152921504606846976",
	[61] = "2305843009213693952",
	[62] = "4611686018427387904",
	[63] = "9223372036854775808",
}

for i = 0, 63 do
	local expected = two_pows_above_53[i] or tostring(2 ^ i)
	local pow_2 = int64.from_dec_string(expected)
	assert(
		int64.to_bin_string(pow_2) == string.rep("0", 63 - i) .. "1" .. string.rep("0", i),
		`from_dec_string parsed '{expected}' wrong`
	)
	assert(int64.to_dec_string(pow_2) == expected, `to_dec_string was wrong for '{expected}`)
end

assert(int64.to_dec_string(int64.ZERO) == "0", "to_dec_string was wrong for ZERO")
assert(int64.to_dec_string(int64.ONE) == "1", "to_dec_string was wrong for ONE")
assert(int64.to_dec_string(int64.TWO) == "2", "to_dec_string was wrong for TWO")
assert(int64.to_dec_string(int64.MAX) == "18446744073709551615", "to_dec_string was wrong for MAX")
assert(int64.to_dec_string(int64.MAX_U32) == "4294967295", "to_dec_string was wrong for MAX_U32")
assert(int64.to_dec_string(int64.MAX_F64) == "9007199254740992", "to_dec_string was wrong for MAX_F64")
assert(int64.to_dec_string(int64.MAX_F32) == "16777216", "to_dec_string was wrong for MAX_F32")

return {}


local int64 = require("../../init")

local arshift_n = int64.from_pair(0x80000000, 0x00000000)
for i = 0, 63 do
	local new = int64.arshift(arshift_n, i)
	local expected_bin = string.rep("1", i) .. "1" .. string.rep("0", 63 - i)
	assert(int64.to_bin_string(new) == expected_bin, `{int64.to_hex_string(arshift_n)} >> {i} was wrong`)
end
assert(int64.arshift(arshift_n, 64) == int64.MAX, `{int64.to_hex_string(arshift_n)} >> 64 was wrong`)

local arshift_1 = int64.from_pair(0x80000000, 0xcccccccc)
assert(int64.arshift(arshift_1, 0) == arshift_1, "0x80000000cccccccc >> 0 was wrong")

assert(int64.to_hex_string(int64.arshift(arshift_1, 04)) == "f80000000ccccccc", "0xcccccccc >>  4 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 08)) == "ff80000000cccccc", "0xcccccccc >>  8 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 12)) == "fff80000000ccccc", "0xcccccccc >> 12 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 16)) == "ffff80000000cccc", "0xcccccccc >> 16 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 20)) == "fffff80000000ccc", "0xcccccccc >> 20 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 24)) == "ffffff80000000cc", "0xcccccccc >> 24 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 28)) == "fffffff80000000c", "0xcccccccc >> 28 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 32)) == "ffffffff80000000", "0xcccccccc >> 32 was wrong")

assert(int64.to_hex_string(int64.arshift(arshift_1, 02)) == "e000000033333333", "0xcccccccc >>  2 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 06)) == "fe00000003333333", "0xcccccccc >>  6 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 10)) == "ffe0000000333333", "0xcccccccc >> 10 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 14)) == "fffe000000033333", "0xcccccccc >> 14 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 18)) == "ffffe00000003333", "0xcccccccc >> 18 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 22)) == "fffffe0000000333", "0xcccccccc >> 22 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 26)) == "ffffffe000000033", "0xcccccccc >> 26 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 30)) == "fffffffe00000003", "0xcccccccc >> 30 was wrong")

assert(int64.to_hex_string(int64.arshift(arshift_1, 01)) == "c000000066666666", "0xcccccccc >>  1 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 03)) == "f000000019999999", "0xcccccccc >>  3 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 05)) == "fc00000006666666", "0xcccccccc >>  5 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 07)) == "ff00000001999999", "0xcccccccc >>  7 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 09)) == "ffc0000000666666", "0xcccccccc >>  9 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 11)) == "fff0000000199999", "0xcccccccc >> 11 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 13)) == "fffc000000066666", "0xcccccccc >> 13 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 15)) == "ffff000000019999", "0xcccccccc >> 15 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 17)) == "ffffc00000006666", "0xcccccccc >> 17 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 19)) == "fffff00000001999", "0xcccccccc >> 19 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 21)) == "fffffc0000000666", "0xcccccccc >> 21 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 23)) == "ffffff0000000199", "0xcccccccc >> 23 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 25)) == "ffffffc000000066", "0xcccccccc >> 25 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 27)) == "fffffff000000019", "0xcccccccc >> 27 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 29)) == "fffffffc00000006", "0xcccccccc >> 29 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 31)) == "ffffffff00000001", "0xcccccccc >> 31 was wrong")

-- Here's a little ditty I like to call "you make me so sad"

assert(int64.to_hex_string(int64.arshift(arshift_1, 33)) == "ffffffffc0000000", "0xcccccccc >> 33 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 34)) == "ffffffffe0000000", "0xcccccccc >> 34 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 35)) == "fffffffff0000000", "0xcccccccc >> 35 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 36)) == "fffffffff8000000", "0xcccccccc >> 36 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 37)) == "fffffffffc000000", "0xcccccccc >> 37 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 38)) == "fffffffffe000000", "0xcccccccc >> 38 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 39)) == "ffffffffff000000", "0xcccccccc >> 39 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 40)) == "ffffffffff800000", "0xcccccccc >> 40 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 41)) == "ffffffffffc00000", "0xcccccccc >> 41 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 42)) == "ffffffffffe00000", "0xcccccccc >> 42 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 43)) == "fffffffffff00000", "0xcccccccc >> 43 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 44)) == "fffffffffff80000", "0xcccccccc >> 44 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 45)) == "fffffffffffc0000", "0xcccccccc >> 45 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 46)) == "fffffffffffe0000", "0xcccccccc >> 46 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 47)) == "ffffffffffff0000", "0xcccccccc >> 47 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 48)) == "ffffffffffff8000", "0xcccccccc >> 48 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 49)) == "ffffffffffffc000", "0xcccccccc >> 49 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 50)) == "ffffffffffffe000", "0xcccccccc >> 50 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 51)) == "fffffffffffff000", "0xcccccccc >> 51 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 52)) == "fffffffffffff800", "0xcccccccc >> 52 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 53)) == "fffffffffffffc00", "0xcccccccc >> 53 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 54)) == "fffffffffffffe00", "0xcccccccc >> 54 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 55)) == "ffffffffffffff00", "0xcccccccc >> 55 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 56)) == "ffffffffffffff80", "0xcccccccc >> 56 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 57)) == "ffffffffffffffc0", "0xcccccccc >> 57 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 58)) == "ffffffffffffffe0", "0xcccccccc >> 58 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 59)) == "fffffffffffffff0", "0xcccccccc >> 59 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 60)) == "fffffffffffffff8", "0xcccccccc >> 60 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 61)) == "fffffffffffffffc", "0xcccccccc >> 61 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 62)) == "fffffffffffffffe", "0xcccccccc >> 62 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 63)) == "ffffffffffffffff", "0xcccccccc >> 63 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_1, 64)) == "ffffffffffffffff", "0xcccccccc >> 64 was wrong")

local arshift_2 = int64.from_u32(0x33333333) -- 00110011_00110011_00110011_00110011
assert(int64.arshift(arshift_2, 0) == arshift_2, "0x0000000033333333 >> 0 was wrong")

assert(int64.to_hex_string(int64.arshift(arshift_2, 04)) == "0000000003333333", "0x33333333 >>  4 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 08)) == "0000000000333333", "0x33333333 >>  8 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 12)) == "0000000000033333", "0x33333333 >> 12 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 16)) == "0000000000003333", "0x33333333 >> 16 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 20)) == "0000000000000333", "0x33333333 >> 20 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 24)) == "0000000000000033", "0x33333333 >> 24 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 28)) == "0000000000000003", "0x33333333 >> 28 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 32)) == "0000000000000000", "0x33333333 >> 32 was wrong")

assert(int64.to_hex_string(int64.arshift(arshift_2, 02)) == "000000000ccccccc", "0x33333333 >>  2 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 06)) == "0000000000cccccc", "0x33333333 >>  6 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 10)) == "00000000000ccccc", "0x33333333 >> 10 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 14)) == "000000000000cccc", "0x33333333 >> 14 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 18)) == "0000000000000ccc", "0x33333333 >> 18 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 22)) == "00000000000000cc", "0x33333333 >> 22 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 26)) == "000000000000000c", "0x33333333 >> 26 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 30)) == "0000000000000000", "0x33333333 >> 30 was wrong")

assert(int64.to_hex_string(int64.arshift(arshift_2, 01)) == "0000000019999999", "0x33333333 >>  1 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 03)) == "0000000006666666", "0x33333333 >>  3 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 05)) == "0000000001999999", "0x33333333 >>  5 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 07)) == "0000000000666666", "0x33333333 >>  7 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 09)) == "0000000000199999", "0x33333333 >>  9 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 11)) == "0000000000066666", "0x33333333 >> 11 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 13)) == "0000000000019999", "0x33333333 >> 13 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 15)) == "0000000000006666", "0x33333333 >> 15 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 17)) == "0000000000001999", "0x33333333 >> 17 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 19)) == "0000000000000666", "0x33333333 >> 19 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 21)) == "0000000000000199", "0x33333333 >> 21 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 23)) == "0000000000000066", "0x33333333 >> 23 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 25)) == "0000000000000019", "0x33333333 >> 25 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 27)) == "0000000000000006", "0x33333333 >> 27 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 29)) == "0000000000000001", "0x33333333 >> 29 was wrong")
assert(int64.to_hex_string(int64.arshift(arshift_2, 31)) == "0000000000000000", "0x33333333 >> 31 was wrong")

for i = 33, 64 do
	local shifted = int64.to_hex_string(int64.arshift(arshift_2, i))
	assert(shifted == "0000000000000000", `0x33333333 >> {i} was wrong`)
end

for i = -64, -1 do
	local shifted = pcall(int64.arshift, int64.ONE, i)
	assert(not shifted, "arshift allowed negative arguments when it shouldn't")
end

for i = 65, 128 do
	local shifted = int64.arshift(int64.MAX, i)
	assert(shifted == int64.MAX, "arshift did not work for values greater than 64 with MSB as 1")
end

for i = 65, 128 do
	local shifted = int64.arshift(int64.from_pair(0x7fffffff, 0xffffffff), i)
	assert(shifted == vector.zero, "arshift did not work for values greater than 64 with MSB as 0")
end

return {}


local int64 = require("../../init")

local lrotate_n = int64.from_pair(0x80000000, 0x00000000)
assert(int64.lrotate(lrotate_n, 0) == lrotate_n, `{int64.to_hex_string(lrotate_n)} LROT 0 was wrong`)

for i = 1, 63 do
	local new = int64.lrotate(lrotate_n, i)
	local expected_bin = string.rep("0", 64 - i) .. "1" .. string.rep("0", i - 1)
	assert(int64.to_bin_string(new) == expected_bin, `{int64.to_hex_string(lrotate_n)} LROT {i} was wrong`)
end
assert(int64.lrotate(lrotate_n, 64) == lrotate_n, `{int64.to_hex_string(lrotate_n)} LROT 64 was wrong`)

local lrotate_1 = int64.from_pair(0xcccccccc, 0xcccccccc)
assert(int64.lrotate(lrotate_1, 0) == lrotate_1, "0xcccccccccccccccc LROT 0 was wrong")

for i = 1, 64, 4 do
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_1, i)) == "9999999999999999",
		`0xcccccccccccccccc LROT {i} was wrong`
	)
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_1, i + 1)) == "3333333333333333",
		`0xcccccccccccccccc LROT {i + 1} was wrong`
	)
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_1, i + 2)) == "6666666666666666",
		`0xcccccccccccccccc LROT {i + 2} was wrong`
	)
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_1, i + 3)) == "cccccccccccccccc",
		`0xcccccccccccccccc LROT {i + 3} was wrong`
	)
end
for i = -64, 0, 4 do
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_1, i)) == "cccccccccccccccc",
		`0xcccccccccccccccc LROT {i} was wrong`
	)
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_1, i + 1)) == "9999999999999999",
		`0xcccccccccccccccc LROT {i + 1} was wrong`
	)
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_1, i + 2)) == "3333333333333333",
		`0xcccccccccccccccc LROT {i + 2} was wrong`
	)
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_1, i + 3)) == "6666666666666666",
		`0xcccccccccccccccc LROT {i + 3} was wrong`
	)
end

local lrotate_2 = int64.from_pair(0x33333333, 0x33333333)
assert(int64.lrotate(lrotate_2, 0) == lrotate_2, "0x3333333333333333 LROT 0 was wrong")

for i = 1, 64, 4 do
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_2, i)) == "6666666666666666",
		`0x3333333333333333 LROT {i} was wrong`
	)
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_2, i + 1)) == "cccccccccccccccc",
		`0x3333333333333333 LROT {i + 1} was wrong`
	)
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_2, i + 2)) == "9999999999999999",
		`0x3333333333333333 LROT {i + 2} was wrong`
	)
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_2, i + 3)) == "3333333333333333",
		`0x3333333333333333 LROT {i + 3} was wrong`
	)
end
for i = -64, 0, 4 do
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_2, i)) == "3333333333333333",
		`0x3333333333333333 LROT {i} was wrong`
	)
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_2, i + 1)) == "6666666666666666",
		`0x3333333333333333 LROT {i + 1} was wrong`
	)
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_2, i + 2)) == "cccccccccccccccc",
		`0x3333333333333333 LROT {i + 2} was wrong`
	)
	assert(
		int64.to_hex_string(int64.lrotate(lrotate_2, i + 3)) == "9999999999999999",
		`0x3333333333333333 LROT {i + 3} was wrong`
	)
end

local lrotate_3 = int64.from_pair(0xdeadbeef, 0x77c0ffee)
assert(int64.lrotate(lrotate_3, 0) == lrotate_3, "0xdeadbeef77c0ffee LROT 0 was wrong")

assert(int64.to_hex_string(int64.lrotate(lrotate_3, 01)) == "bd5b7ddeef81ffdd", "0xdeadbeef77c0ffee LROT  1 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 02)) == "7ab6fbbddf03ffbb", "0xdeadbeef77c0ffee LROT  2 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 03)) == "f56df77bbe07ff76", "0xdeadbeef77c0ffee LROT  3 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 04)) == "eadbeef77c0ffeed", "0xdeadbeef77c0ffee LROT  4 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 05)) == "d5b7ddeef81ffddb", "0xdeadbeef77c0ffee LROT  5 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 06)) == "ab6fbbddf03ffbb7", "0xdeadbeef77c0ffee LROT  6 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 07)) == "56df77bbe07ff76f", "0xdeadbeef77c0ffee LROT  7 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 08)) == "adbeef77c0ffeede", "0xdeadbeef77c0ffee LROT  8 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 09)) == "5b7ddeef81ffddbd", "0xdeadbeef77c0ffee LROT  9 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 10)) == "b6fbbddf03ffbb7a", "0xdeadbeef77c0ffee LROT 10 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 11)) == "6df77bbe07ff76f5", "0xdeadbeef77c0ffee LROT 11 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 12)) == "dbeef77c0ffeedea", "0xdeadbeef77c0ffee LROT 12 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 13)) == "b7ddeef81ffddbd5", "0xdeadbeef77c0ffee LROT 13 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 14)) == "6fbbddf03ffbb7ab", "0xdeadbeef77c0ffee LROT 14 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 15)) == "df77bbe07ff76f56", "0xdeadbeef77c0ffee LROT 15 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 16)) == "beef77c0ffeedead", "0xdeadbeef77c0ffee LROT 16 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 17)) == "7ddeef81ffddbd5b", "0xdeadbeef77c0ffee LROT 17 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 18)) == "fbbddf03ffbb7ab6", "0xdeadbeef77c0ffee LROT 18 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 19)) == "f77bbe07ff76f56d", "0xdeadbeef77c0ffee LROT 19 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 20)) == "eef77c0ffeedeadb", "0xdeadbeef77c0ffee LROT 20 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 21)) == "ddeef81ffddbd5b7", "0xdeadbeef77c0ffee LROT 21 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 22)) == "bbddf03ffbb7ab6f", "0xdeadbeef77c0ffee LROT 22 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 23)) == "77bbe07ff76f56df", "0xdeadbeef77c0ffee LROT 23 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 24)) == "ef77c0ffeedeadbe", "0xdeadbeef77c0ffee LROT 24 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 25)) == "deef81ffddbd5b7d", "0xdeadbeef77c0ffee LROT 25 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 26)) == "bddf03ffbb7ab6fb", "0xdeadbeef77c0ffee LROT 26 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 27)) == "7bbe07ff76f56df7", "0xdeadbeef77c0ffee LROT 27 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 28)) == "f77c0ffeedeadbee", "0xdeadbeef77c0ffee LROT 28 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 29)) == "eef81ffddbd5b7dd", "0xdeadbeef77c0ffee LROT 29 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 30)) == "ddf03ffbb7ab6fbb", "0xdeadbeef77c0ffee LROT 30 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 31)) == "bbe07ff76f56df77", "0xdeadbeef77c0ffee LROT 31 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 32)) == "77c0ffeedeadbeef", "0xdeadbeef77c0ffee LROT 32 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 33)) == "ef81ffddbd5b7dde", "0xdeadbeef77c0ffee LROT 33 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 34)) == "df03ffbb7ab6fbbd", "0xdeadbeef77c0ffee LROT 34 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 35)) == "be07ff76f56df77b", "0xdeadbeef77c0ffee LROT 35 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 36)) == "7c0ffeedeadbeef7", "0xdeadbeef77c0ffee LROT 36 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 37)) == "f81ffddbd5b7ddee", "0xdeadbeef77c0ffee LROT 37 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 38)) == "f03ffbb7ab6fbbdd", "0xdeadbeef77c0ffee LROT 38 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 39)) == "e07ff76f56df77bb", "0xdeadbeef77c0ffee LROT 39 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 40)) == "c0ffeedeadbeef77", "0xdeadbeef77c0ffee LROT 40 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 41)) == "81ffddbd5b7ddeef", "0xdeadbeef77c0ffee LROT 41 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 42)) == "03ffbb7ab6fbbddf", "0xdeadbeef77c0ffee LROT 42 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 43)) == "07ff76f56df77bbe", "0xdeadbeef77c0ffee LROT 43 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 44)) == "0ffeedeadbeef77c", "0xdeadbeef77c0ffee LROT 44 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 45)) == "1ffddbd5b7ddeef8", "0xdeadbeef77c0ffee LROT 45 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 46)) == "3ffbb7ab6fbbddf0", "0xdeadbeef77c0ffee LROT 46 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 47)) == "7ff76f56df77bbe0", "0xdeadbeef77c0ffee LROT 47 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 48)) == "ffeedeadbeef77c0", "0xdeadbeef77c0ffee LROT 48 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 49)) == "ffddbd5b7ddeef81", "0xdeadbeef77c0ffee LROT 49 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 50)) == "ffbb7ab6fbbddf03", "0xdeadbeef77c0ffee LROT 50 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 51)) == "ff76f56df77bbe07", "0xdeadbeef77c0ffee LROT 51 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 52)) == "feedeadbeef77c0f", "0xdeadbeef77c0ffee LROT 52 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 53)) == "fddbd5b7ddeef81f", "0xdeadbeef77c0ffee LROT 53 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 54)) == "fbb7ab6fbbddf03f", "0xdeadbeef77c0ffee LROT 54 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 55)) == "f76f56df77bbe07f", "0xdeadbeef77c0ffee LROT 55 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 56)) == "eedeadbeef77c0ff", "0xdeadbeef77c0ffee LROT 56 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 57)) == "ddbd5b7ddeef81ff", "0xdeadbeef77c0ffee LROT 57 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 58)) == "bb7ab6fbbddf03ff", "0xdeadbeef77c0ffee LROT 58 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 59)) == "76f56df77bbe07ff", "0xdeadbeef77c0ffee LROT 59 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 60)) == "edeadbeef77c0ffe", "0xdeadbeef77c0ffee LROT 60 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 61)) == "dbd5b7ddeef81ffd", "0xdeadbeef77c0ffee LROT 61 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 62)) == "b7ab6fbbddf03ffb", "0xdeadbeef77c0ffee LROT 62 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 63)) == "6f56df77bbe07ff7", "0xdeadbeef77c0ffee LROT 63 was wrong")
assert(int64.to_hex_string(int64.lrotate(lrotate_3, 64)) == "deadbeef77c0ffee", "0xdeadbeef77c0ffee LROT 64 was wrong")

return {}


local int64 = require("../../init")

local lshift_n = int64.from_pair(0x00000000, 0x00000001)
for i = 0, 63 do
	local new = int64.lshift(lshift_n, i)
	local expected_bin = string.rep("0", 63 - i) .. "1" .. string.rep("0", i)
	assert(int64.to_bin_string(new) == expected_bin, `{int64.to_hex_string(lshift_n)} << {i} was wrong`)
end
assert(int64.lshift(lshift_n, 64) == vector.zero, `{int64.to_hex_string(lshift_n)} << 64 was wrong`)

local lshift_1 = int64.from_u32(0xcccccccc) -- 11001100_11001100_11001100_11001100
assert(int64.lshift(lshift_1, 0) == lshift_1, "0xcccccccc << 0 was wrong")

assert(int64.to_hex_string(int64.lshift(lshift_1, 01)) == "0000000199999998", "0xcccccccc <<  1 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 02)) == "0000000333333330", "0xcccccccc <<  2 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 03)) == "0000000666666660", "0xcccccccc <<  3 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 04)) == "0000000cccccccc0", "0xcccccccc <<  4 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 05)) == "0000001999999980", "0xcccccccc <<  5 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 06)) == "0000003333333300", "0xcccccccc <<  6 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 07)) == "0000006666666600", "0xcccccccc <<  7 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 08)) == "000000cccccccc00", "0xcccccccc <<  8 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 09)) == "0000019999999800", "0xcccccccc <<  9 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 10)) == "0000033333333000", "0xcccccccc << 10 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 11)) == "0000066666666000", "0xcccccccc << 11 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 12)) == "00000cccccccc000", "0xcccccccc << 12 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 13)) == "0000199999998000", "0xcccccccc << 13 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 14)) == "0000333333330000", "0xcccccccc << 14 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 15)) == "0000666666660000", "0xcccccccc << 15 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 16)) == "0000cccccccc0000", "0xcccccccc << 16 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 17)) == "0001999999980000", "0xcccccccc << 17 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 18)) == "0003333333300000", "0xcccccccc << 18 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 19)) == "0006666666600000", "0xcccccccc << 19 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 20)) == "000cccccccc00000", "0xcccccccc << 20 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 21)) == "0019999999800000", "0xcccccccc << 21 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 22)) == "0033333333000000", "0xcccccccc << 22 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 23)) == "0066666666000000", "0xcccccccc << 23 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 24)) == "00cccccccc000000", "0xcccccccc << 24 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 25)) == "0199999998000000", "0xcccccccc << 25 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 26)) == "0333333330000000", "0xcccccccc << 26 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 27)) == "0666666660000000", "0xcccccccc << 27 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 28)) == "0cccccccc0000000", "0xcccccccc << 28 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 29)) == "1999999980000000", "0xcccccccc << 29 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 30)) == "3333333300000000", "0xcccccccc << 30 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 31)) == "6666666600000000", "0xcccccccc << 31 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 32)) == "cccccccc00000000", "0xcccccccc << 32 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 33)) == "9999999800000000", "0xcccccccc << 33 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 34)) == "3333333000000000", "0xcccccccc << 34 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 35)) == "6666666000000000", "0xcccccccc << 35 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 36)) == "ccccccc000000000", "0xcccccccc << 36 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 37)) == "9999998000000000", "0xcccccccc << 37 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 38)) == "3333330000000000", "0xcccccccc << 38 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 39)) == "6666660000000000", "0xcccccccc << 39 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 40)) == "cccccc0000000000", "0xcccccccc << 40 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 41)) == "9999980000000000", "0xcccccccc << 41 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 42)) == "3333300000000000", "0xcccccccc << 42 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 43)) == "6666600000000000", "0xcccccccc << 43 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 44)) == "ccccc00000000000", "0xcccccccc << 44 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 45)) == "9999800000000000", "0xcccccccc << 45 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 46)) == "3333000000000000", "0xcccccccc << 46 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 47)) == "6666000000000000", "0xcccccccc << 47 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 48)) == "cccc000000000000", "0xcccccccc << 48 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 49)) == "9998000000000000", "0xcccccccc << 49 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 50)) == "3330000000000000", "0xcccccccc << 50 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 51)) == "6660000000000000", "0xcccccccc << 51 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 52)) == "ccc0000000000000", "0xcccccccc << 52 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 53)) == "9980000000000000", "0xcccccccc << 53 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 54)) == "3300000000000000", "0xcccccccc << 54 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 55)) == "6600000000000000", "0xcccccccc << 55 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 56)) == "cc00000000000000", "0xcccccccc << 56 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 57)) == "9800000000000000", "0xcccccccc << 57 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 58)) == "3000000000000000", "0xcccccccc << 58 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 59)) == "6000000000000000", "0xcccccccc << 59 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 60)) == "c000000000000000", "0xcccccccc << 60 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 61)) == "8000000000000000", "0xcccccccc << 61 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 62)) == "0000000000000000", "0xcccccccc << 62 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 63)) == "0000000000000000", "0xcccccccc << 63 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_1, 64)) == "0000000000000000", "0xcccccccc << 64 was wrong")

local lshift_2 = int64.from_u32(0x33333333) -- 00110011_00110011_00110011_00110011
assert(int64.lshift(lshift_2, 0) == lshift_2, "0x33333333 << 0 was wrong")

assert(int64.to_hex_string(int64.lshift(lshift_2, 01)) == "0000000066666666", "0x33333333 <<  1 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 02)) == "00000000cccccccc", "0x33333333 <<  2 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 03)) == "0000000199999998", "0x33333333 <<  3 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 04)) == "0000000333333330", "0x33333333 <<  4 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 05)) == "0000000666666660", "0x33333333 <<  5 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 06)) == "0000000cccccccc0", "0x33333333 <<  6 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 07)) == "0000001999999980", "0x33333333 <<  7 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 08)) == "0000003333333300", "0x33333333 <<  8 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 09)) == "0000006666666600", "0x33333333 <<  9 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 10)) == "000000cccccccc00", "0x33333333 << 10 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 11)) == "0000019999999800", "0x33333333 << 11 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 12)) == "0000033333333000", "0x33333333 << 12 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 13)) == "0000066666666000", "0x33333333 << 13 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 14)) == "00000cccccccc000", "0x33333333 << 14 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 15)) == "0000199999998000", "0x33333333 << 15 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 16)) == "0000333333330000", "0x33333333 << 16 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 17)) == "0000666666660000", "0x33333333 << 17 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 18)) == "0000cccccccc0000", "0x33333333 << 18 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 19)) == "0001999999980000", "0x33333333 << 19 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 20)) == "0003333333300000", "0x33333333 << 20 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 21)) == "0006666666600000", "0x33333333 << 21 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 22)) == "000cccccccc00000", "0x33333333 << 22 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 23)) == "0019999999800000", "0x33333333 << 23 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 24)) == "0033333333000000", "0x33333333 << 24 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 25)) == "0066666666000000", "0x33333333 << 25 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 26)) == "00cccccccc000000", "0x33333333 << 26 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 27)) == "0199999998000000", "0x33333333 << 27 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 28)) == "0333333330000000", "0x33333333 << 28 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 29)) == "0666666660000000", "0x33333333 << 29 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 30)) == "0cccccccc0000000", "0x33333333 << 30 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 31)) == "1999999980000000", "0x33333333 << 31 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 32)) == "3333333300000000", "0x33333333 << 32 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 33)) == "6666666600000000", "0x33333333 << 33 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 34)) == "cccccccc00000000", "0x33333333 << 34 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 35)) == "9999999800000000", "0x33333333 << 35 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 36)) == "3333333000000000", "0x33333333 << 36 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 37)) == "6666666000000000", "0x33333333 << 37 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 38)) == "ccccccc000000000", "0x33333333 << 38 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 39)) == "9999998000000000", "0x33333333 << 39 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 40)) == "3333330000000000", "0x33333333 << 40 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 41)) == "6666660000000000", "0x33333333 << 41 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 42)) == "cccccc0000000000", "0x33333333 << 42 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 43)) == "9999980000000000", "0x33333333 << 43 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 44)) == "3333300000000000", "0x33333333 << 44 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 45)) == "6666600000000000", "0x33333333 << 45 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 46)) == "ccccc00000000000", "0x33333333 << 46 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 47)) == "9999800000000000", "0x33333333 << 47 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 48)) == "3333000000000000", "0x33333333 << 48 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 49)) == "6666000000000000", "0x33333333 << 49 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 50)) == "cccc000000000000", "0x33333333 << 50 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 51)) == "9998000000000000", "0x33333333 << 51 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 52)) == "3330000000000000", "0x33333333 << 52 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 53)) == "6660000000000000", "0x33333333 << 53 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 54)) == "ccc0000000000000", "0x33333333 << 54 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 55)) == "9980000000000000", "0x33333333 << 55 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 56)) == "3300000000000000", "0x33333333 << 56 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 57)) == "6600000000000000", "0x33333333 << 57 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 58)) == "cc00000000000000", "0x33333333 << 58 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 59)) == "9800000000000000", "0x33333333 << 59 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 60)) == "3000000000000000", "0x33333333 << 60 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 61)) == "6000000000000000", "0x33333333 << 61 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 62)) == "c000000000000000", "0x33333333 << 62 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 63)) == "8000000000000000", "0x33333333 << 63 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_2, 64)) == "0000000000000000", "0x33333333 << 64 was wrong")

local lshift_3 = int64.from_pair(0xdeadbeef, 0x77c0ffee) -- 11011110_10101101_10111110_11101111_00000111_11000000_11111111_11101110
assert(int64.lshift(lshift_3, 0) == lshift_3, "0xdeadbeef77c0ffee << 0 was wrong")

assert(int64.to_hex_string(int64.lshift(lshift_3, 01)) == "bd5b7ddeef81ffdc", "0xdeadbeef77c0ffee <<  1 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 02)) == "7ab6fbbddf03ffb8", "0xdeadbeef77c0ffee <<  2 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 03)) == "f56df77bbe07ff70", "0xdeadbeef77c0ffee <<  3 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 04)) == "eadbeef77c0ffee0", "0xdeadbeef77c0ffee <<  4 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 05)) == "d5b7ddeef81ffdc0", "0xdeadbeef77c0ffee <<  5 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 06)) == "ab6fbbddf03ffb80", "0xdeadbeef77c0ffee <<  6 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 07)) == "56df77bbe07ff700", "0xdeadbeef77c0ffee <<  7 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 08)) == "adbeef77c0ffee00", "0xdeadbeef77c0ffee <<  8 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 09)) == "5b7ddeef81ffdc00", "0xdeadbeef77c0ffee <<  9 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 10)) == "b6fbbddf03ffb800", "0xdeadbeef77c0ffee << 10 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 11)) == "6df77bbe07ff7000", "0xdeadbeef77c0ffee << 11 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 12)) == "dbeef77c0ffee000", "0xdeadbeef77c0ffee << 12 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 13)) == "b7ddeef81ffdc000", "0xdeadbeef77c0ffee << 13 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 14)) == "6fbbddf03ffb8000", "0xdeadbeef77c0ffee << 14 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 15)) == "df77bbe07ff70000", "0xdeadbeef77c0ffee << 15 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 16)) == "beef77c0ffee0000", "0xdeadbeef77c0ffee << 16 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 17)) == "7ddeef81ffdc0000", "0xdeadbeef77c0ffee << 17 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 18)) == "fbbddf03ffb80000", "0xdeadbeef77c0ffee << 18 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 19)) == "f77bbe07ff700000", "0xdeadbeef77c0ffee << 19 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 20)) == "eef77c0ffee00000", "0xdeadbeef77c0ffee << 20 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 21)) == "ddeef81ffdc00000", "0xdeadbeef77c0ffee << 21 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 22)) == "bbddf03ffb800000", "0xdeadbeef77c0ffee << 22 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 23)) == "77bbe07ff7000000", "0xdeadbeef77c0ffee << 23 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 24)) == "ef77c0ffee000000", "0xdeadbeef77c0ffee << 24 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 25)) == "deef81ffdc000000", "0xdeadbeef77c0ffee << 25 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 26)) == "bddf03ffb8000000", "0xdeadbeef77c0ffee << 26 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 27)) == "7bbe07ff70000000", "0xdeadbeef77c0ffee << 27 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 28)) == "f77c0ffee0000000", "0xdeadbeef77c0ffee << 28 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 29)) == "eef81ffdc0000000", "0xdeadbeef77c0ffee << 29 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 30)) == "ddf03ffb80000000", "0xdeadbeef77c0ffee << 30 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 31)) == "bbe07ff700000000", "0xdeadbeef77c0ffee << 31 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 32)) == "77c0ffee00000000", "0xdeadbeef77c0ffee << 32 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 33)) == "ef81ffdc00000000", "0xdeadbeef77c0ffee << 33 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 34)) == "df03ffb800000000", "0xdeadbeef77c0ffee << 34 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 35)) == "be07ff7000000000", "0xdeadbeef77c0ffee << 35 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 36)) == "7c0ffee000000000", "0xdeadbeef77c0ffee << 36 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 37)) == "f81ffdc000000000", "0xdeadbeef77c0ffee << 37 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 38)) == "f03ffb8000000000", "0xdeadbeef77c0ffee << 38 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 39)) == "e07ff70000000000", "0xdeadbeef77c0ffee << 39 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 40)) == "c0ffee0000000000", "0xdeadbeef77c0ffee << 40 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 41)) == "81ffdc0000000000", "0xdeadbeef77c0ffee << 41 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 42)) == "03ffb80000000000", "0xdeadbeef77c0ffee << 42 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 43)) == "07ff700000000000", "0xdeadbeef77c0ffee << 43 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 44)) == "0ffee00000000000", "0xdeadbeef77c0ffee << 44 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 45)) == "1ffdc00000000000", "0xdeadbeef77c0ffee << 45 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 46)) == "3ffb800000000000", "0xdeadbeef77c0ffee << 46 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 47)) == "7ff7000000000000", "0xdeadbeef77c0ffee << 47 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 48)) == "ffee000000000000", "0xdeadbeef77c0ffee << 48 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 49)) == "ffdc000000000000", "0xdeadbeef77c0ffee << 49 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 50)) == "ffb8000000000000", "0xdeadbeef77c0ffee << 50 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 51)) == "ff70000000000000", "0xdeadbeef77c0ffee << 51 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 52)) == "fee0000000000000", "0xdeadbeef77c0ffee << 52 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 53)) == "fdc0000000000000", "0xdeadbeef77c0ffee << 53 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 54)) == "fb80000000000000", "0xdeadbeef77c0ffee << 54 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 55)) == "f700000000000000", "0xdeadbeef77c0ffee << 55 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 56)) == "ee00000000000000", "0xdeadbeef77c0ffee << 56 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 57)) == "dc00000000000000", "0xdeadbeef77c0ffee << 57 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 58)) == "b800000000000000", "0xdeadbeef77c0ffee << 58 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 59)) == "7000000000000000", "0xdeadbeef77c0ffee << 59 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 60)) == "e000000000000000", "0xdeadbeef77c0ffee << 60 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 61)) == "c000000000000000", "0xdeadbeef77c0ffee << 61 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 62)) == "8000000000000000", "0xdeadbeef77c0ffee << 62 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 63)) == "0000000000000000", "0xdeadbeef77c0ffee << 63 was wrong")
assert(int64.to_hex_string(int64.lshift(lshift_3, 64)) == "0000000000000000", "0xdeadbeef77c0ffee << 64 was wrong")

for i = -64, -1 do
	local shifted = pcall(int64.lshift, int64.ONE, i)
	assert(not shifted, "lshift allowed negative arguments when it shouldn't")
end

for i = 65, 128 do
	local shifted = int64.lshift(int64.MAX, i)
	assert(shifted == vector.zero, "lshift did not work for values greater than 64")
end

return {}


local int64 = require("../../init")

local rrotate_n = int64.from_pair(0x80000000, 0x00000000)
for i = 0, 63 do
	local new = int64.rrotate(rrotate_n, i)
	local expected_bin = string.rep("0", i) .. "1" .. string.rep("0", 63 - i)
	assert(int64.to_bin_string(new) == expected_bin, `{int64.to_hex_string(rrotate_n)} RROT {i} was wrong`)
end
assert(int64.rrotate(rrotate_n, 64) == rrotate_n, `{int64.to_hex_string(rrotate_n)} RROT 64 was wrong`)

local rrotate_1 = int64.from_pair(0xcccccccc, 0xcccccccc)
assert(int64.rrotate(rrotate_1, 0) == rrotate_1, "0xcccccccccccccccc RROT 0 was wrong")

for i = 1, 64, 4 do
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_1, i)) == "6666666666666666",
		`0xcccccccccccccccc RROT {i} was wrong`
	)
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_1, i + 1)) == "3333333333333333",
		`0xcccccccccccccccc RROT {i + 1} was wrong`
	)
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_1, i + 2)) == "9999999999999999",
		`0xcccccccccccccccc RROT {i + 2} was wrong`
	)
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_1, i + 3)) == "cccccccccccccccc",
		`0xcccccccccccccccc RROT {i + 3} was wrong`
	)
end

for i = -64, 0, 4 do
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_1, i)) == "cccccccccccccccc",
		`0xcccccccccccccccc RROT {i} was wrong`
	)
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_1, i + 1)) == "6666666666666666",
		`0xcccccccccccccccc RROT {i + 1} was wrong`
	)
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_1, i + 2)) == "3333333333333333",
		`0xcccccccccccccccc RROT {i + 2} was wrong`
	)
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_1, i + 3)) == "9999999999999999",
		`0xcccccccccccccccc RROT {i + 3} was wrong`
	)
end

local rrotate_2 = int64.from_pair(0x33333333, 0x33333333)
assert(int64.rrotate(rrotate_2, 0) == rrotate_2, "0x3333333333333333 RROT 0 was wrong")

for i = 1, 64, 4 do
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_2, i)) == "9999999999999999",
		`0x3333333333333333 RROT {i} was wrong`
	)
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_2, i + 1)) == "cccccccccccccccc",
		`0x3333333333333333 RROT {i + 1} was wrong`
	)
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_2, i + 2)) == "6666666666666666",
		`0x3333333333333333 RROT {i + 2} was wrong`
	)
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_2, i + 3)) == "3333333333333333",
		`0x3333333333333333 RROT {i + 3} was wrong`
	)
end
for i = -64, 0, 4 do
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_2, i)) == "3333333333333333",
		`0x3333333333333333 RROT {i} was wrong`
	)
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_2, i + 1)) == "9999999999999999",
		`0x3333333333333333 RROT {i + 1} was wrong`
	)
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_2, i + 2)) == "cccccccccccccccc",
		`0x3333333333333333 RROT {i + 2} was wrong`
	)
	assert(
		int64.to_hex_string(int64.rrotate(rrotate_2, i + 3)) == "6666666666666666",
		`0x3333333333333333 RROT {i + 3} was wrong`
	)
end

local rrotate_3 = int64.from_pair(0xdeadbeef, 0x77c0ffee)

assert(int64.to_hex_string(int64.rrotate(rrotate_3, 00)) == "deadbeef77c0ffee", "0xdeadbeef77c0ffee RROT 0 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 01)) == "6f56df77bbe07ff7", "0xdeadbeef77c0ffee RROT  1 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 02)) == "b7ab6fbbddf03ffb", "0xdeadbeef77c0ffee RROT  2 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 03)) == "dbd5b7ddeef81ffd", "0xdeadbeef77c0ffee RROT  3 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 04)) == "edeadbeef77c0ffe", "0xdeadbeef77c0ffee RROT  4 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 05)) == "76f56df77bbe07ff", "0xdeadbeef77c0ffee RROT  5 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 06)) == "bb7ab6fbbddf03ff", "0xdeadbeef77c0ffee RROT  6 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 07)) == "ddbd5b7ddeef81ff", "0xdeadbeef77c0ffee RROT  7 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 08)) == "eedeadbeef77c0ff", "0xdeadbeef77c0ffee RROT  8 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 09)) == "f76f56df77bbe07f", "0xdeadbeef77c0ffee RROT  9 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 10)) == "fbb7ab6fbbddf03f", "0xdeadbeef77c0ffee RROT 10 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 11)) == "fddbd5b7ddeef81f", "0xdeadbeef77c0ffee RROT 11 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 12)) == "feedeadbeef77c0f", "0xdeadbeef77c0ffee RROT 12 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 13)) == "ff76f56df77bbe07", "0xdeadbeef77c0ffee RROT 13 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 14)) == "ffbb7ab6fbbddf03", "0xdeadbeef77c0ffee RROT 14 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 15)) == "ffddbd5b7ddeef81", "0xdeadbeef77c0ffee RROT 15 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 16)) == "ffeedeadbeef77c0", "0xdeadbeef77c0ffee RROT 16 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 17)) == "7ff76f56df77bbe0", "0xdeadbeef77c0ffee RROT 17 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 18)) == "3ffbb7ab6fbbddf0", "0xdeadbeef77c0ffee RROT 18 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 19)) == "1ffddbd5b7ddeef8", "0xdeadbeef77c0ffee RROT 19 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 20)) == "0ffeedeadbeef77c", "0xdeadbeef77c0ffee RROT 20 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 21)) == "07ff76f56df77bbe", "0xdeadbeef77c0ffee RROT 21 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 22)) == "03ffbb7ab6fbbddf", "0xdeadbeef77c0ffee RROT 22 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 23)) == "81ffddbd5b7ddeef", "0xdeadbeef77c0ffee RROT 23 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 24)) == "c0ffeedeadbeef77", "0xdeadbeef77c0ffee RROT 24 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 25)) == "e07ff76f56df77bb", "0xdeadbeef77c0ffee RROT 25 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 26)) == "f03ffbb7ab6fbbdd", "0xdeadbeef77c0ffee RROT 26 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 27)) == "f81ffddbd5b7ddee", "0xdeadbeef77c0ffee RROT 27 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 28)) == "7c0ffeedeadbeef7", "0xdeadbeef77c0ffee RROT 28 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 29)) == "be07ff76f56df77b", "0xdeadbeef77c0ffee RROT 29 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 30)) == "df03ffbb7ab6fbbd", "0xdeadbeef77c0ffee RROT 30 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 31)) == "ef81ffddbd5b7dde", "0xdeadbeef77c0ffee RROT 31 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 32)) == "77c0ffeedeadbeef", "0xdeadbeef77c0ffee RROT 32 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 33)) == "bbe07ff76f56df77", "0xdeadbeef77c0ffee RROT 33 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 34)) == "ddf03ffbb7ab6fbb", "0xdeadbeef77c0ffee RROT 34 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 35)) == "eef81ffddbd5b7dd", "0xdeadbeef77c0ffee RROT 35 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 36)) == "f77c0ffeedeadbee", "0xdeadbeef77c0ffee RROT 36 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 37)) == "7bbe07ff76f56df7", "0xdeadbeef77c0ffee RROT 37 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 38)) == "bddf03ffbb7ab6fb", "0xdeadbeef77c0ffee RROT 38 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 39)) == "deef81ffddbd5b7d", "0xdeadbeef77c0ffee RROT 39 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 40)) == "ef77c0ffeedeadbe", "0xdeadbeef77c0ffee RROT 40 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 41)) == "77bbe07ff76f56df", "0xdeadbeef77c0ffee RROT 41 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 42)) == "bbddf03ffbb7ab6f", "0xdeadbeef77c0ffee RROT 42 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 43)) == "ddeef81ffddbd5b7", "0xdeadbeef77c0ffee RROT 43 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 44)) == "eef77c0ffeedeadb", "0xdeadbeef77c0ffee RROT 44 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 45)) == "f77bbe07ff76f56d", "0xdeadbeef77c0ffee RROT 45 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 46)) == "fbbddf03ffbb7ab6", "0xdeadbeef77c0ffee RROT 46 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 47)) == "7ddeef81ffddbd5b", "0xdeadbeef77c0ffee RROT 47 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 48)) == "beef77c0ffeedead", "0xdeadbeef77c0ffee RROT 48 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 49)) == "df77bbe07ff76f56", "0xdeadbeef77c0ffee RROT 49 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 50)) == "6fbbddf03ffbb7ab", "0xdeadbeef77c0ffee RROT 50 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 51)) == "b7ddeef81ffddbd5", "0xdeadbeef77c0ffee RROT 51 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 52)) == "dbeef77c0ffeedea", "0xdeadbeef77c0ffee RROT 52 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 53)) == "6df77bbe07ff76f5", "0xdeadbeef77c0ffee RROT 53 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 54)) == "b6fbbddf03ffbb7a", "0xdeadbeef77c0ffee RROT 54 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 55)) == "5b7ddeef81ffddbd", "0xdeadbeef77c0ffee RROT 55 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 56)) == "adbeef77c0ffeede", "0xdeadbeef77c0ffee RROT 56 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 57)) == "56df77bbe07ff76f", "0xdeadbeef77c0ffee RROT 57 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 58)) == "ab6fbbddf03ffbb7", "0xdeadbeef77c0ffee RROT 58 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 59)) == "d5b7ddeef81ffddb", "0xdeadbeef77c0ffee RROT 59 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 60)) == "eadbeef77c0ffeed", "0xdeadbeef77c0ffee RROT 60 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 61)) == "f56df77bbe07ff76", "0xdeadbeef77c0ffee RROT 61 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 62)) == "7ab6fbbddf03ffbb", "0xdeadbeef77c0ffee RROT 62 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 63)) == "bd5b7ddeef81ffdd", "0xdeadbeef77c0ffee RROT 63 was wrong")
assert(int64.to_hex_string(int64.rrotate(rrotate_3, 64)) == "deadbeef77c0ffee", "0xdeadbeef77c0ffee RROT 64 was wrong")

return {}