⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 math32f.h

📁 FreeRTOS 是一个源码公开的免费的嵌入式实时操作系统
💻 H
📖 第 1 页 / 共 2 页
字号:

  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 + -