data ConInt {
int value
}
const byte NEG_CHK_FLAG = 128
component provides SignedInt requires data.IntUtil iu {
ConInt con = new ConInt()
byte conBytes[]
//perform a two's complement inversion to get the positive number
// - invert all bits using binary NOT, then add 1 to the result
int complement2(int val)
{
ConInt conX = new ConInt(val)
byte conBytesX[] = dana.serial(conX)
for (int i = 0; i < conBytesX.arrayLength; i++)
{
conBytesX[i] = ~conBytesX[i]
}
conX.value += 1
return conX.value
}
//check for the sign bit
bool isNegativeV(opt int v)
{
bool negative = false
if (isset v)
{
ConInt conX = new ConInt(v)
byte conBytesX[] = dana.serial(conX)
if ((conBytesX[0] & NEG_CHK_FLAG) == NEG_CHK_FLAG)
{
negative = true
}
}
else
{
if ((conBytes[0] & NEG_CHK_FLAG) == NEG_CHK_FLAG)
{
negative = true
}
}
return negative
}
SignedInt:SignedInt(opt int val, opt int neg)
{
if (isset val && isset neg)
{
throw new Exception("absolute and negative values cannot both be set (choose one)")
}
conBytes = dana.serial(con)
if (isset val)
{
con.value = val
}
else if (isset neg)
{
subtract(neg)
}
}
int SignedInt:subtract(int val)
{
con.value = con.value - val
return con.value
}
int SignedInt:add(int val)
{
con.value = con.value + val
return con.value
}
int SignedInt:multiply(int val)
{
con.value = con.value * val
return con.value
}
int SignedInt:divide(int val)
{
bool negA = isNegativeV()
bool negB = isNegativeV(val)
if (negA != negB)
{
//this implies one number is negative; the result will be negative
if (negA) con.value = complement2(con.value)
if (negB) val = complement2(val)
con.value = con.value / val
if (!isNegativeV()) con.value = complement2(con.value)
}
else if (negA)
{
//this implies both numbers are negative; the result will be positive
if (negA) con.value = complement2(con.value)
if (negB) val = complement2(val)
con.value = con.value / val
}
else
{
//both numbers are positive
con.value = con.value / val
}
return con.value
}
int SignedInt:getValue()
{
return con.value
}
void SignedInt:setValue(int v)
{
con.value = v
}
bool SignedInt:isNegative()
{
return isNegativeV()
}
void SignedInt:invert()
{
con.value = complement2(con.value)
}
byte[] SignedInt:getBytes()
{
return clone conBytes
}
char[] SignedInt:toString()
{
if (isNegative())
{
int val = complement2(con.value)
return "-$(val)"
}
else
{
return "$(con.value)"
}
}
}
To propose a new revision to this entity, use dana source put -uc your/new/version.dn -n data.SignedInt -m "reason for update" -u yourUsername
Version 1 (this version) by barry
Notes for this version: New compiler components