示例#1
0
/* Convert float to string
 *   decimals must be >= 0
 *   if compact != 0, the trailing 0's will be truncated
 */
int
sys_double_to_chars_fast(double f, char *buffer, int buffer_size, int decimals,
			 int compact)
{
    #define SYS_DOUBLE_RND_CONST 0.5
    #define FRAC_SIZE            52
    #define EXP_SIZE             11
    #define EXP_MASK             (((Uint64)1 << EXP_SIZE) - 1)
    #define MAX_DECIMALS         (sizeof(pow10v) / sizeof(pow10v[0]))
    #define FRAC_MASK            (((Uint64)1 << FRAC_SIZE) - 1)
    #define FRAC_MASK2           (((Uint64)1 << (FRAC_SIZE + 1)) - 1)
    #define MAX_FLOAT            ((Uint64)1 << (FRAC_SIZE+1))

    static const double pow10v[] = {
        1e0,  1e1,  1e2,  1e3,  1e4,  1e5,  1e6,  1e7,  1e8, 1e9,
        1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18
    };

    double af;
    Uint64 int_part, frac_part;
    int neg;
    int  has_decimals = decimals != 0;
    char *p = buffer;

    if (decimals < 0)
        return -1;

    if (f < 0) {
        neg = 1;
        af = -f;
    }
    else {
        neg = 0;
        af = f;
    }

    /* Don't bother with optimizing too large numbers or too large precision */
    if (af > MAX_FLOAT || decimals >= MAX_DECIMALS) {
        int len = erts_snprintf(buffer, buffer_size, "%.*f", decimals, f);
        char* p = buffer + len;
        if (len >= buffer_size)
            return -1;
        /* Delete trailing zeroes */
        if (compact)
            p = find_first_trailing_zero(p);
        *p = '\0';
        return p - buffer;
    }

    if (decimals) {
        double int_f = floor(af);
        double frac_f = round((af - int_f) * pow10v[decimals]);

        int_part = (Uint64)int_f;
        frac_part = (Uint64)frac_f;

        if (frac_f >= pow10v[decimals]) {
            /* rounding overflow carry into int_part */
            int_part++;
            frac_part = 0;
        }

        do {
            Uint64 n;
            if (!frac_part) {
                do {
                    *p++ = '0';
                } while (--decimals);
                break;
            }
            n = frac_part / 10;
            *p++ = (char)((frac_part - n*10) + '0');
            frac_part = n;
        } while (--decimals);

        *p++ = '.';
    }
    else
        int_part = (Uint64)round_int64(af);

    if (!int_part) {
        *p++ = '0';
    } else {
        do {
            Uint64 n = int_part / 10;
            *p++ = (char)((int_part - n*10) + '0');
            int_part = n;
        } while (int_part);
    }
    if (neg)
        *p++ = '-';

    {/* Reverse string */
        int i = 0;
        int j = p - buffer - 1;
        for ( ; i < j; i++, j--) {
            char tmp = buffer[i];
            buffer[i] = buffer[j];
            buffer[j] = tmp;
        }
    }

    /* Delete trailing zeroes */
    if (compact && has_decimals)
        p = find_first_trailing_zero(p);
    *p = '\0';
    return p - buffer;
}
示例#2
0
// U型计费
bool FareCalc::QueryUTypeFare(FareQueryResultClass *pResult, const FareQueryConditionClass &Condition)
{
    bool bFree;
    const quint64 METERS_MAX=20000*1000;        //	最大里程限制在2万公里,以防止计算过程中溢出
    const quint64 METERS_SUSPECT_MAX=1000*1000; //	1000公里以上怀疑超出最大收费金额,按换卡车计费进行排查
    // 初始化查询结果,为计费进行准备
    pResult->clear();
    pResult->m_vehTollInfo=Condition.m_vehTollInfo;
    pResult->m_vehTollInfo.CalcOverweightInfo();
    // 计算车辆行驶时间(U型车不统计超速、超时时间设置为最大允许超时时间)
    pResult->m_dwMinSeconds=0;
    pResult->m_dwMaxSeconds=calcDriveTime(0, 0);
    //wumax 增加最远站查询
    updateFarthestStaAndMinimumFare();
    if (pResult->m_vehTollInfo.m_bIsFullFreeVeh)
    {
        // 对全免车,通行费为0,也不必统计免收金额
        return true;
    }
    // 计算收费里程
    if (0==Condition.m_dwTollMeters)
    {
        if (Condition.m_nDriveTimeInSeconds<=0)
        {
            pResult->m_dwTollMeters=0;
        }
        else
        {
            // 查询车型信息
            SVCCodeValue vehClassInfo;
            if (!QueryVehClassInfo(vehClassInfo, Condition.m_vehTollInfo.m_bVehClass))
            {
                return false;
            }
            quint64 llMeters=round_int64((double)vehClassInfo.wVUSpeed*Condition.m_nDriveTimeInSeconds/3600*1000);
            if (llMeters>METERS_MAX)
            {
                pResult->m_dwTollMeters=METERS_MAX;
            }
            else
            {
                pResult->m_dwTollMeters=(quint32)llMeters;
            }
        }
    }
    else
    {
        pResult->m_dwTollMeters=Condition.m_dwTollMeters;
    }
    // 根据U型车行驶里程、出口站仿制一个收费单元
    STollCellValue TollCell;
    if (!MakeTollCell(TollCell, Condition.m_nExSta, pResult->m_dwTollMeters))
    {
        return false;
    }
    CSectMoney SectMoney(0);
    if (!pResult->m_vehTollInfo.CalcMoney(SectMoney, TollCell,&bFree))
    {
        return false;
    }
    AddToSectMoneyList(pResult->m_SplitInfo, SectMoney);
    // 对分段计算结果进行汇总、取整,传入U型车最小收费金额
    pResult->SumSectMoney(0);
    // 如果有可能超出U型车最大收费金额,对收费金额进行调整
    if (pResult->m_dwTollMeters>METERS_SUSPECT_MAX)
    {
        FareQueryResultClass ChangeCardFareResult;
        VehTollInfoClass ChangeCardTollVehInfo=Condition.m_vehTollInfo;
        ChangeCardTollVehInfo.m_bIsFullFreeVeh=false;
        ChangeCardTollVehInfo.m_FreeRegion.clear();
        if (!QueryChangeCareFare(&ChangeCardFareResult, Condition.m_vehTollInfo, Condition.m_nExSta,Condition.m_nEnSta))
        {
            return false;
        }
        pResult->m_dwMoneyOverweightDue=ChangeCardFareResult.m_dwMoneyOverweightDue;
        if (pResult->m_dwMoneyDue>ChangeCardFareResult.m_dwMoneyDue)
        {
            pResult->m_dwMoneyDue=ChangeCardFareResult.m_dwMoneyDue;
        }
        if (pResult->m_dwMoneyFree>ChangeCardFareResult.m_dwMoneyDue)
        {
            pResult->m_dwMoneyFree=ChangeCardFareResult.m_dwMoneyDue;
        }
    }
    // 因U型车为特殊拆分,清空计算过程中产生的拆分信息
    pResult->m_SplitInfo.clear();
    // 进行折扣和拆分处理
    pResult->Discount(Condition.m_nDiscountRate);
    return true;
}