把一个范围的数映射到另一个范围

如何将一个范围的数映射到另一个范围,这是一个很简单的问题。

但是有时候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;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值