Add i64 remainder operation

This commit is contained in:
Rerumu 2022-07-02 05:04:39 -04:00
parent d351920a51
commit 971ac382a5
3 changed files with 66 additions and 55 deletions

View File

@ -69,22 +69,6 @@ function Numeric.subtract(lhs, rhs)
return from_u32(data_1, data_2)
end
local function set_absolute(lhs, rhs)
local has_negative = false
if num_is_negative(lhs) then
lhs = num_negate(lhs)
has_negative = not has_negative
end
if num_is_negative(rhs) then
rhs = num_negate(rhs)
has_negative = not has_negative
end
return has_negative, lhs, rhs
end
function Numeric.multiply(lhs, rhs)
if num_is_zero(lhs) or num_is_zero(rhs) then
return NUM_ZERO
@ -140,9 +124,12 @@ function Numeric.divide_unsigned(lhs, rhs)
if num_is_zero(rhs) then
error("division by zero")
elseif num_is_zero(lhs) then
return NUM_ZERO
return NUM_ZERO, NUM_ZERO
elseif num_is_less_unsigned(lhs, NUM_BIT_52) and num_is_less_unsigned(rhs, NUM_BIT_52) then
return from_u64(into_u64(lhs) / into_u64(rhs))
local lhs_u = into_u64(lhs)
local rhs_u = into_u64(rhs)
return from_u64(lhs_u / rhs_u), from_u64(lhs_u % rhs_u)
end
local quotient = NUM_ZERO
@ -170,17 +157,28 @@ function Numeric.divide_unsigned(lhs, rhs)
end
function Numeric.divide_signed(lhs, rhs)
local has_negative
local left_negative = num_is_negative(lhs)
local right_negative = num_is_negative(rhs)
has_negative, lhs, rhs = set_absolute(lhs, rhs)
local result = num_divide_unsigned(lhs, rhs)
if has_negative then
result = num_negate(result)
if left_negative then
lhs = num_negate(lhs)
end
return result
if right_negative then
rhs = num_negate(rhs)
end
local quotient, remainder = num_divide_unsigned(lhs, rhs)
if left_negative ~= right_negative then
quotient = num_negate(quotient)
end
if left_negative then
remainder = num_negate(remainder)
end
return quotient, remainder
end
function Numeric.negate(value)

View File

@ -85,22 +85,6 @@ function Numeric.subtract(lhs, rhs)
return from_u32(data_1, data_2)
end
local function set_absolute(lhs, rhs)
local has_negative = false
if num_is_negative(lhs) then
lhs = num_negate(lhs)
has_negative = not has_negative
end
if num_is_negative(rhs) then
rhs = num_negate(rhs)
has_negative = not has_negative
end
return has_negative, lhs, rhs
end
function Numeric.multiply(lhs, rhs)
if num_is_zero(lhs) or num_is_zero(rhs) then
return NUM_ZERO
@ -159,9 +143,12 @@ function Numeric.divide_unsigned(lhs, rhs)
if num_is_zero(rhs) then
error("division by zero")
elseif num_is_zero(lhs) then
return NUM_ZERO
return NUM_ZERO, NUM_ZERO
elseif num_is_less_unsigned(lhs, NUM_BIT_52) and num_is_less_unsigned(rhs, NUM_BIT_52) then
return from_u64(into_u64(lhs) / into_u64(rhs))
local lhs_u = into_u64(lhs)
local rhs_u = into_u64(rhs)
return from_u64(lhs_u / rhs_u), from_u64(lhs_u % rhs_u)
end
local quotient = NUM_ZERO
@ -191,17 +178,28 @@ function Numeric.divide_unsigned(lhs, rhs)
end
function Numeric.divide_signed(lhs, rhs)
local has_negative
local left_negative = num_is_negative(lhs)
local right_negative = num_is_negative(rhs)
has_negative, lhs, rhs = set_absolute(lhs, rhs)
local result = num_divide_unsigned(lhs, rhs)
if has_negative then
result = num_negate(result)
if left_negative then
lhs = num_negate(lhs)
end
return result
if right_negative then
rhs = num_negate(rhs)
end
local quotient, remainder = num_divide_unsigned(lhs, rhs)
if left_negative ~= right_negative then
quotient = num_negate(quotient)
end
if left_negative then
remainder = num_negate(remainder)
end
return quotient, remainder
end
function Numeric.negate(value)

View File

@ -40,7 +40,6 @@ do
local math_abs = math.abs
local math_fmod = math.fmod
local math_floor = math.floor
local math_round = math.round
local math_sign = math.sign
local math_min = math.min
@ -49,6 +48,9 @@ do
local string_byte = string.byte
local string_pack = string.pack
local num_divide_signed = Integer.divide_signed
local num_divide_unsigned = Integer.divide_unsigned
function add.i32(lhs, rhs)
return to_u32(lhs + rhs)
end
@ -100,8 +102,21 @@ do
add.i64 = Integer.add
sub.i64 = Integer.subtract
mul.i64 = Integer.multiply
div.i64 = Integer.divide_signed
div.u64 = Integer.divide_unsigned
div.i64 = num_divide_signed
function rem.i64(lhs, rhs)
local _, remainder = num_divide_signed(lhs, rhs)
return remainder
end
div.u64 = num_divide_unsigned
function rem.u64(lhs, rhs)
local _, remainder = num_divide_unsigned(lhs, rhs)
return remainder
end
function neg.f32(num)
return -num