如何将一个范围的数映射到另一个范围,这是一个很简单的问题。
但是有时候8位单片机对乘除法支持不是很好,会出现溢出,这样你就不能很好地得到你想要的数。
这里我提供一个简单的算法,可以对整型进行误差较小的映射。
在原目标范围相差太小时可能不是很准,误差来自小数变整数的误差。
/************************************
*目的:将200 - 1023 中的某个数映射到 20 - 160 上
*原范围:200 - 1023
*目标范围:20 - 160
*大数到小数的映射会出现精度的损失,所以先将小数的范围扩大,
*这里采用的是左移n位,(也可以使用乘n来扩大范围)
*扩大后必须使目标范围至少大于原范围
***********************************/
typedef unsigned int typeOriginal;
typedef unsigned int typeTarget;
#define ORIGINAL_DATA_MAX 1023
#define ORIGINAL_DATA_MIN 200
#define TARGET_DATA_MAX 160
#define TARGET_DATA_MIN 20
#define LEFT_SHIFT_N 3
typeTarget MAP(typeOriginal dat)
{
typeOriginal start,end,middle,target;
typeTarget start1,end1,middle1;
target = dat;
if(target >= ORIGINAL_DATA_MAX)
{
return TARGET_DATA_MAX;
}
if(target <= ORIGINAL_DATA_MIN)
{
return TARGET_DATA_MIN;
}
target -= ORIGINAL_DATA_MIN;
start = 0;
end = ORIGINAL_DATA_MAX-ORIGINAL_DATA_MIN;
start1 = 0;
end1= TARGET_DATA_MAX-TARGET_DATA_MIN;
end1 <<= LEFT_SHIFT_N;
while((start != end) && (start+1 < end))
{
middle = (start+end)>>1;
middle1 = (start1+end1)>>1;
if(middle <= target)
{
start = middle;
start1 = middle1;
}
else
{
end = middle;
end1 = middle1;
}
}
start1>>=LEFT_SHIFT_N;
return start1+TARGET_DATA_MIN;
}