这几天在开发公司项目中,由于属于期货产品,所以在此过程中遇到价格和最小单位价格的除法计算。
众所周知浮点数在计算机中为近视值。比如价格,客户端输入的价格为145.5,但是我的服务端断点显示为145.49999999999998。
当然从CTP服务器(期货那边的服务器)最小单位价格实为0.5,但是断点显示为0.50000000000003。所以利用fomd()函数的方法
变落空了。
这里提一下
函数名: fmod
功 能: 计算x对y的模, 即x/y的余数
用 法: double fmod(double x, double y);
我的本意利用这个函数验证值是否为零来判断是否整除。但是由于精度问题无法实现。
所以,首先我想到了一个方法,就是取浮点的小数点后6位有效数字,后面的四舍五入。
算法是这样的:
double sswr(double x, int n)
{
double temp = x * pow(10.0,-n);
temp = floor(temp +0.5);
return (temp * pow(10.0,n));
}
这样算法的原理是浮点数先乘于10的n次方 然后加0.5 然后取整数部分 再除以10的n次方。
按理我的想法这个原理可行,随后我进行了判断代码如下:
if((fabs(fmod(sswr(fabs(orderfield.Order_Field.LimitPrice - it_DepthMarket->second.AskPrice1),-7),sswr(it_InstrumentField->second.PriceTick,-7))) > FLT_EPSILON)
按道理说这个方法可行,但是当我测试的时候 发现却不是这样 发现符合条件的LimitPrice却无法通过条件验证 ,这个问题我一直很纠结,找不到问题。希望大神可以帮我解惑。
既然这个方法行不通。最后我利用了一个简单粗暴的方法,就是浮点数转换成整数,进行处理这样就简单多了。代码如下
unsigned long long Limit_Price = (orderfield.Order_Field.LimitPrice*100000 + 0.9);
unsigned long long Prcie_Tick = (it_InstrumentField->second.PriceTick*100000 + 0.9);
if (0 != Limit_Price % Prcie_Tick)
这样浮点数转成整数时 自动取整数部分并且实现了四舍五入,由于浮点数为五位数 六位数(再乘于100000) 为了防止整数类型溢出,所以我用了 long long 类型。这样就简单的解决了这个问题。