📄 math32f.h
字号:
SET_SIGN:
if (!(sign & 0x80))
arg1f32.23 = 0;
return arg1f32;
}
float32 operator+ _fadd32( sharedM float32 arg1f32, sharedM float32 arg2f32)
// CYCLES: 6+21+11+5+ (A8)*13 +3 + A1*8 + 61 ++
{
char xtra, temp;
char expo = arg1f32.high8 - arg2f32.high8;
if (!Carry) {
expo = -expo;
temp = arg1f32.high8;
arg1f32.high8 = arg2f32.high8;
arg2f32.high8 = temp;
temp = arg1f32.midH8;
arg1f32.midH8 = arg2f32.midH8;
arg2f32.midH8 = temp;
temp = arg1f32.midL8;
arg1f32.midL8 = arg2f32.midL8;
arg2f32.midL8 = temp;
temp = arg1f32.low8;
arg1f32.low8 = arg2f32.low8;
arg2f32.low8 = temp;
}
if (expo > sizeof(arg1f32)*8-7)
goto RETURN;
if (!arg2f32.high8)
goto RETURN; // result is arg1f32
xtra = 0;
W = arg1f32.midH8;
temp = W;
char sign = arg2f32.midH8 ^ W;
arg1f32.23 = 1;
arg2f32.23 = 1;
while (1) {
W = 8;
expo -= W;
if (!Carry)
break;
xtra = arg2f32.low8;
arg2f32.low8 = arg2f32.midL8;
arg2f32.midL8 = arg2f32.midH8;
arg2f32.midH8 = 0;
}
expo += W;
if (expo) {
do {
Carry = 0;
arg2f32.low24 = rr( arg2f32.low24);
xtra = rr( xtra);
} while (--expo > 0);
}
if (sign & 0x80) {
// SUBTRACT
arg1f32.low8 -= arg2f32.low8;
genSub( arg1f32.midL8, arg2f32.midL8);
genSub( arg1f32.midH8, arg2f32.midH8);
if (!Carry) { // arg2f32 > arg1f32
arg1f32.low24 = -arg1f32.low24;
// xtra == 0 because arg1f32.exp == arg2f32.exp
temp ^= 0x80; // invert sign
}
xtra = -xtra;
if (xtra)
arg1f32.low24 --;
// adjust result left
#define counter expo
counter = 4;
while (!arg1f32.midH8) {
arg1f32.midH8 = arg1f32.midL8;
arg1f32.midL8 = arg1f32.low8;
arg1f32.low8 = xtra;
xtra = 0;
arg1f32.high8 -= 8;
if (!Carry)
goto RES0;
if (--counter == 0) // max 3 iterations
goto RES0;
}
#undef counter
while (!arg1f32.23) {
Carry = 0;
xtra = rl( xtra);
arg1f32.low24 = rl( arg1f32.low24);
arg1f32.high8 --;
if (!arg1f32.high8)
goto RES0; // UNDERFLOW?
}
#ifndef DISABLE_ROUNDING
if (FpRounding && (xtra & 0x80)) {
xtra = 0; // disable recursion
goto INCREMENT;
}
#endif
}
else {
// ADD arg1f32 and arg2f32
arg1f32.low8 += arg2f32.low8;
genAdd( arg1f32.midL8, arg2f32.midL8);
genAdd( arg1f32.midH8, arg2f32.midH8);
if (Carry) {
ADJUST_RIGHT:
arg1f32.low24 = rr( arg1f32.low24);
xtra = rr( xtra);
arg1f32.high8 += 1; // expo
if (!arg1f32.high8)
goto OVERFLOW;
}
#ifndef DISABLE_ROUNDING
if (FpRounding && (xtra & 0x80)) {
INCREMENT:
arg1f32.low8 += 1;
if (!arg1f32.low8) {
arg1f32.midL8 += 1;
if (!arg1f32.midL8) {
arg1f32.midH8 += 1;
if (!arg1f32.midH8) {
Carry = 1; // prepare for shift
arg1f32.0 = 0; // disable recursion
goto ADJUST_RIGHT;
}
}
}
}
#endif
}
goto SET_SIGN;
// UNDERFLOW:
// FpUnderFlow = 1;
RES0:
arg1f32.high8 = 0;
goto MANTISSA;
OVERFLOW:
FpOverflow = 1;
arg1f32.high8 = 0xFF;
MANTISSA:
arg1f32.low24 = 0x800000;
SET_SIGN:
if (!(temp & 0x80))
arg1f32.23 = 0;
RETURN:
return arg1f32;
}
// SUBTRACTION
float32 operator- _fsub32( sharedM float32 arg1f32, sharedM float32 arg2f32)
{
arg2f32.midH8 ^= 0x80;
arg1f32 += arg2f32;
return arg1f32;
}
float32 operator=( int8 arg) @
float32 operator=( uns8 arg) @
float32 operator=( int16 arg) @
float32 operator=( uns16 arg) @
float32 operator=( int24 arg) @
float32 operator=( uns24 arg) @
float32 operator= _int32ToFloat32( sharedM int32 arg1f32)
{
sharedM float32 arg2f32; // unused, but required
char expo = FpBIAS + 24 - 1;
char xtra = 0;
char sign = 0;
if (arg1f32 < 0) {
arg1f32 = -arg1f32;
sign |= 0x80;
}
if (arg1f32.high8) {
expo += 8;
xtra = arg1f32.low8;
arg1f32.low8 = arg1f32.midL8;
arg1f32.midL8 = arg1f32.midH8;
arg1f32.midH8 = arg1f32.high8;
}
else if (!arg1f32.midH8) {
expo -= 8;
W = arg1f32.midL8;
if (!W) {
expo -= 8;
W = arg1f32.low8;
if (!W)
goto RETURN;
arg1f32.low8 = 0;
}
arg1f32.midH8 = W;
arg1f32.midL8 = arg1f32.low8;
arg1f32.low8 = 0;
}
// arg1f32.midH8 != 0
goto TEST_ARG1_B23;
do {
xtra = rl( xtra);
arg1f32.low24 = rl( arg1f32.low24);
expo --;
TEST_ARG1_B23:
} while (!arg1f32.23);
#ifndef DISABLE_ROUNDING
if (FpRounding && (xtra & 0x80)) {
arg1f32.low8 += 1;
if (!arg1f32.low8) {
arg1f32.midL8 += 1;
if (!arg1f32.midL8) {
arg1f32.midH8 += 1;
if (!arg1f32.midH8) {
Carry = 1;
arg1f32.high24 = rr( arg1f32.high24);
expo ++;
}
}
}
}
#endif
arg1f32.high8 = expo;
if (!(sign & 0x80))
arg1f32.23 = 0;
RETURN:
float32 rval @ arg1f32;
rval.low32 = arg1f32.low32;
return rval;
}
uns8 operator=( sharedM float32 arg1f32) @
int8 operator=( sharedM float32 arg1f32) @
uns16 operator=( sharedM float32 arg1f32) @
int16 operator=( sharedM float32 arg1f32) @
uns24 operator=( sharedM float32 arg1f32) @
int24 operator=( sharedM float32 arg1f32) @
int32 operator= _float32ToInt32( sharedM float32 arg1f32)
{
sharedM float32 arg2f32; // unused, but required
char sign = arg1f32.midH8;
char expo = arg1f32.high8 - (FpBIAS-1);
if (!Carry)
goto RES0;
arg1f32.23 = 1;
arg1f32.high8 = 0;
#ifndef DISABLE_ROUNDING
char xtra = 0;
#endif
// (a): expo = 0..8 : shift 2 byte to the right
// (b): expo = 9..16: shift 1 byte to the right
// (c): expo = 17..24: shift 0 byte
// (d): expo = 25..32: shift 1 byte to the left
#if __CoreSet__ / 100 == 12
expo -= 25;
expo = 0xFF - expo; // COMF (Carry unchanged)
if (Carry) { // (d)
#else
expo = 24 - expo;
if (!Carry) { // (d)
#endif
expo += 8;
if (!Carry)
goto OVERFLOW;
arg1f32.high8 = arg1f32.midH8;
arg1f32.midH8 = arg1f32.midL8;
arg1f32.midL8 = arg1f32.low8;
arg1f32.low8 = 0;
}
else { // (a) (b) (c)
// expo = 0 .. 24
while (1) {
W = 8;
expo -= W;
if (!Carry)
break;
#ifndef DISABLE_ROUNDING
xtra = arg1f32.low8;
#endif
arg1f32.low8 = arg1f32.midL8;
arg1f32.midL8 = arg1f32.midH8;
arg1f32.midH8 = 0;
}
expo += W;
}
if (expo) {
do {
Carry = 0;
arg1f32.high8 = rr( arg1f32.high8);
arg1f32.low24 = rr( arg1f32.low24);
#ifndef DISABLE_ROUNDING
xtra = rr( xtra);
#endif
} while (--expo);
}
if (arg1f32.31) {
OVERFLOW:
FpOverflow = 1;
W = 0xFF;
goto ASSIGNW;
RES0:
W = 0;
ASSIGNW:
arg1f32.low8 = W;
arg1f32.midL8 = W;
arg1f32.midH8 = W;
arg1f32.high8 = W;
arg1f32.31 = 0;
}
else {
#ifndef DISABLE_ROUNDING
if (FpRounding && (xtra & 0x80)) {
arg1f32.low8 += 1;
if (!arg1f32.low8) {
arg1f32.midL8 += 1;
if (!arg1f32.midL8)
arg1f32.midH8 += 1;
}
}
#endif
if (sign & 0x80)
arg1f32.low32 = -arg1f32.low32;
}
int32 rval @ arg1f32;
rval = arg1f32.low32;
return rval;
}
bit operator< _f32_LT_f32( sharedM float32 arg1f32, sharedM float32 arg2f32)
{
Carry = 0;
if (!(arg1f32.high8 | arg2f32.high8))
return Carry;
if (!arg1f32.23) {
if (arg2f32.23)
return Carry;
W = arg1f32.low8 - arg2f32.low8;
genSubW( arg1f32.midL8, arg2f32.midL8);
genSubW( arg1f32.midH8, arg2f32.midH8);
genSubW( arg1f32.high8, arg2f32.high8);
goto RETURN;
}
if (!arg2f32.23)
goto RETURN;
W = arg2f32.low8 - arg1f32.low8;
genSubW( arg2f32.midL8, arg1f32.midL8);
genSubW( arg2f32.midH8, arg1f32.midH8);
genSubW( arg2f32.high8, arg1f32.high8);
RETURN:
if (Carry)
return 0;
return 1;
}
bit operator>= _f32_GE_f32( sharedM float32 arg1f32, sharedM float32 arg2f32)
{
Carry = 1;
if (!(arg1f32.high8 | arg2f32.high8))
return Carry;
if (!arg1f32.23) {
if (arg2f32.23)
return Carry;
W = arg1f32.low8 - arg2f32.low8;
genSubW( arg1f32.midL8, arg2f32.midL8);
genSubW( arg1f32.midH8, arg2f32.midH8);
genSubW( arg1f32.high8, arg2f32.high8);
return Carry;
}
Carry = 0;
if (!arg2f32.23)
return Carry;
W = arg2f32.low8 - arg1f32.low8;
genSubW( arg2f32.midL8, arg1f32.midL8);
genSubW( arg2f32.midH8, arg1f32.midH8);
genSubW( arg2f32.high8, arg1f32.high8);
return Carry;
}
bit operator> _f32_GT_f32( sharedM float32 arg1f32, sharedM float32 arg2f32)
{
Carry = 0;
if (!(arg1f32.high8 | arg2f32.high8))
return Carry;
if (!arg1f32.23) {
if (arg2f32.23)
goto RETURN;
W = arg2f32.low8 - arg1f32.low8;
genSubW( arg2f32.midL8, arg1f32.midL8);
genSubW( arg2f32.midH8, arg1f32.midH8);
genSubW( arg2f32.high8, arg1f32.high8);
goto RETURN;
}
if (!arg2f32.23)
return Carry;
W = arg1f32.low8 - arg2f32.low8;
genSubW( arg1f32.midL8, arg2f32.midL8);
genSubW( arg1f32.midH8, arg2f32.midH8);
genSubW( arg1f32.high8, arg2f32.high8);
RETURN:
if (Carry)
return 0;
return 1;
}
bit operator<= _f32_LE_f32( sharedM float32 arg1f32, sharedM float32 arg2f32)
{
Carry = 1;
if (!(arg1f32.high8 | arg2f32.high8))
return Carry;
if (!arg1f32.23) {
Carry = 0;
if (arg2f32.23)
return Carry;
W = arg2f32.low8 - arg1f32.low8;
genSubW( arg2f32.midL8, arg1f32.midL8);
genSubW( arg2f32.midH8, arg1f32.midH8);
genSubW( arg2f32.high8, arg1f32.high8);
return Carry;
}
if (!arg2f32.23)
return Carry;
W = arg1f32.low8 - arg2f32.low8;
genSubW( arg1f32.midL8, arg2f32.midL8);
genSubW( arg1f32.midH8, arg2f32.midH8);
genSubW( arg1f32.high8, arg2f32.high8);
return Carry;
}
#undef genAdd
#undef genSub
#undef genAddW
#undef genSubW
#pragma library 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -