仅使用整数缩放值
Posted
技术标签:
【中文标题】仅使用整数缩放值【英文标题】:Scaling a value using integers only 【发布时间】:2018-02-20 18:06:17 【问题描述】:我正在用 C 编写代码 - 我尝试在微控制器上进行一些速度关键型计算,我想在不使用浮点变量的情况下找到数字的比率。
我有一个介于 0 和 255 之间的字节,我想找到它的百分比。 例如 - 如果我想找到 75% 的“价值”,我正在使用此代码。
float x = value * 0.75;
其中“值”是 0 到 255 之间的数字。
我可以执行一些巧妙的数学运算来进行此计算吗?有没有办法将值放大并仅使用整数除法计算?
【问题讨论】:
首先测量这确实是一个瓶颈!今天,一些现代微控制器具有浮点单元。并且编译器可能能够将其优化为您想要的操作。在继续之前测量并检查生成的代码。int pct = (value * 3) / 4
不起作用吗?
你在这里说的百分比是多少?任意整数百分比?某个子集(如 5% 的增量)?数学不是特别聪明,你只需要准确地决定你需要什么。但是,您确实需要谨慎。例如,您可以先乘以百分比数字(例如,在 75% 的情况下乘以整数 75),然后整数除以 100 来计算任意百分比。但是您必须处理可能整数溢出。如果您的值是 0 到 255,并且您在 micro 中的字长是 16 位,那应该不是问题。
“百分比缩放器”是什么意思?你的意思是255代表100%?或者 256 实际上是 100%,而 255 只是略低于 100%?那会让事情变得更容易。乘以缩放器值,然后除以 256,即向右移动 8 位。如果 255 为 100%,则乘以缩放器值,然后整数除以 255。
对于 0 到 100,您可以获得一个还不错的查找表。
【参考方案1】:
谢谢大家!我知道了。。
我的缩放值是 0 到 256 之间的数字 - 所以:
percent = (value * scaler) >> 8
【讨论】:
提示:既然您说value
是一个字节值,请先将其类型转换为更大的数据类型。否则,乘法可能会溢出字节大小的变量,您的结果将是错误的。不要相信编译器会自动执行此操作。
@bta value * scaler
至少使用 int
宽数学完成。 C 将 integer Promotions 指定为 *
的一部分。
@chux - 一般来说你是对的,但你必须小心使用微控制器。我不止一次被这个问题困扰过,尤其是在 16 位微控制器上。默认升级为常规int
,但您需要手动指定unsigned int
或uint16_t
以避免255 * 255
溢出。
我也使用 micros。使用更兼容的 C 编译器会更有效率。不过,Micros 的编译器经常会遇到这样无法避免的问题,希望您向其制造商提交错误报告。
@chux:标准只要求int
能够支持范围-32767..32767,所以有一个16位的int完全符合标准...以上是关于仅使用整数缩放值的主要内容,如果未能解决你的问题,请参考以下文章
如何仅在某些值上在管道内使用 StandardScaler?
三个js facevertex uv map三角形:如何仅缩放1个方向