data ConInt32 {
int4 value
}
const byte NEG_CHK_FLAG = 128
component provides SignedInt4 requires data.IntUtil iu {
ConInt32 con = new ConInt32()
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
int4 complement2(int4 val)
{
ConInt32 conX = new ConInt32(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 int4 v)
{
bool negative = false
if (isset v)
{
ConInt32 conX = new ConInt32(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
}
SignedInt4:SignedInt4(opt int4 val, opt int4 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)
}
}
int4 SignedInt4:subtract(int4 val)
{
con.value = con.value - val
return con.value
}
int4 SignedInt4:add(int4 val)
{
con.value = con.value + val
return con.value
}
int4 SignedInt4:multiply(int4 val)
{
con.value = con.value * val
return con.value
}
int4 SignedInt4:divide(int4 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
}
int4 SignedInt4:getValue()
{
return con.value
}
void SignedInt4:setValue(int4 v)
{
con.value = v
}
bool SignedInt4:isNegative()
{
return isNegativeV()
}
void SignedInt4:invert()
{
con.value = complement2(con.value)
}
byte[] SignedInt4:getBytes()
{
return clone conBytes
}
char[] SignedInt4:toString()
{
if (isNegative())
{
int4 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.SignedInt4 -m "reason for update" -u yourUsername
Version 1 (this version) by barry
Notes for this version: New compiler components