/* 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; }
// 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; }