//
//Author			: walk.ly  
//Time			: 2009-05-08
//Version		: 1.0.0
//Description	: 单进双不进 	
//

#ifndef __ROUND5_
#define __ROUND5_

#ifdef _VS_WALK
#include "wkClassDefine.h"
#endif

/* ***********************************************************

	引出函数：

	转为 double
double Double(double a);

	按 "四舍六入、逢五单进双不进" 处理浮点值：
double round5(double v, int dec);

	分配凑整误差（按权分配）
void AdjRoundError(array &power, array &vs, double fr, int dec);

	求数组的合计
double Sum(array &a);

*********************************************************** */


double Double(double a){ return a; }

//按 "四舍六入、逢五单进双不进" 处理浮点值：
//	dec 为数值小数点后的有效位数
double round5(double v, int dec)
{
	double dec10=pow(10,dec);
	//将值乘以有效位（v×10^dec），并多保留2位
	string s; s.format("%.2lf", v*dec10);
	v=atof(s);

	//得到小数位后的值
	int d=atoi(s.right(2));

	//按 "单进双不进" 处理
	if (d==50)
	{
		//取小数点前的个数位值
		int d1=atoi(s.right(4).left(1));
		if ((d1%2)==1)//单进
			s.format("%.0lf", v>0? v+0.5: v-0.5);
		else//双不进
			s.format("%.0lf", v>0? v-0.5: v+0.5);
	}else
		s.format("%.0lf", v);

	//除以有效位
	return atof(s)/dec10;
}

//分配凑整误差（按权分配）
//	power ：计算改正数的权
//	v	：  改正数
//	fr	：	round error 凑整误差
//	dec ：	数值小数点后的有效位数
void AdjRoundError(array &power, array &vs, double fr, int dec)
{
	int i;
	//凑整误差个数
	int rN=(abs(fr)*pow(10,dec)+0.1);
	//一个凑整误差
	double fr1=1.0/pow(10,dec);

	array mk;	//凑整误差分配标识
	for (i=0; i<vs.getSize(); i++)
		mk.add(0);

	for (i=0; i<rN; i++)
	{
		//找到最大权的位置
		double maxPwr;
		int find=-1;
		for (int j=0; j<vs.getSize(); j++)
		{
			int k=mk[j];
			double p=power[j];
			if (k==1)//已分配了凑整误差的改正项不再分配
				continue;
			if (find==-1)
			{
				find=j;
				maxPwr=p;
			}else if (p>maxPwr)
			{
				find=j;
				maxPwr=p;
			}
		}
		if (find>=0)
		{
			mk.setAt(find,1);
			//将改正数加上凑整误差
			double v=vs[find];
			vs.setAt(find, round5(v-(fr>0.0? fr1:-fr1), dec));
		}
	}
}

//求数组的合计
double Sum(array &a)
{
	double s=0;
	for (int i=0; i<a.getSize(); i++)
	{
		double t=a[i];
		s+=t;
	}
	return s;
}

#endif //__ROUND5_
