【发布时间】:2021-02-22 12:06:50
【问题描述】:
我继承了一个函数的维护,该函数将0 和65535(含)之间的值作为参数:
MyClass::mappingFunction(unsigned short headingIndex);
headingIndex 可以使用以下公式转换为度数:degrees = headingIndex * 360 / 65536
这个函数的作用是将headingIndex翻译成36个符号中的1个,代表不同的旋转度数,即有一个10度的符号,一个20度的符号等等,最多360度,以10为单位度数。
headingIndex 为 0 将转换为显示 0 (360) 度符号。
该函数执行以下我似乎无法理解的操作:
const int MAX_INTEGER = 65536;
const int NUM_SYMBOLS = 36;
int symbolRange = NUM_SYMBOLS - 1;
int roundAmount = MAX_INTEGER / (symbolRange + 1) - 1;
int roundedIndex = headingIndex + roundAmount;
int symbol = (symbolRange * roundedIndex) / MAX_INTEGER;
我对这里使用的算法感到困惑,特别是在以下方面:
-
roundAmount背后的意图?我知道它本质上是将最大输入范围划分为离散的块,但然后将其添加到headingIndex似乎是一件奇怪的事情。 -
roundedIndex那么原始值现在是偏移还是顺时针方向旋转了一些偏移量?
算法产生如下结果:
headingIndex of 0 --> symbol 0
headingIndex of 100 --> symbol 1
headingIndex of 65500 --> symbol 35
我在想一定有更好的方法来做到这一点?
【问题讨论】:
-
请注意,
symbolRange和roundAmmount也是常量表达式。roundAmount可以简化为(MAX_INTEGER / NUM_SYMBOLS) - 1。我不确定该值背后的原因是什么,但在我看来它是一个舍入因素。您添加到int的因子,以便小数截断产生的值等于对原始值进行不同舍入所获得的值。例如,在整数算术中,(x + 9) / 10在功能上是x / 10,同时向上取整而不是截断。我只是不确定roundAmount的用途。 -
尚不清楚 100 的
headingIndex如何给出 1 的符号。根据您的第一个公式,这将是100 * 360 / 65536= ~0.549 度,符号索引为 0。 -
除非我复制粘贴错误,否则 0-53 映射到 0,54-1925 映射到 1,1926-3798 映射到 2,以此类推。对我来说,这看起来像是一个有问题的映射,一个间隔只有 54 个元素,而其他间隔在 1872 和 1873 之间交替(而 655536/36 = 1820)。它似乎也与您的公式没有明显关系。
-
@molbdnilo 除非我们都复制错了! 0-53 给出 0,然后 54 给出 1。#confirmed。
-
@FrançoisAndrieux 我认为代码可能会混淆。它看起来像是某种“更圆的鞋面”。您添加以使截断四舍五入的东西。 (x+7)/8 截断向上取整!将该值添加到索引中,然后表达式(就像他们所做的那样)然后
(NUM_SYMBOLS*roundAmount)/MAX_INTEGER将显示一些类似舍入的行为。但它们乘以(NUM_SYMBOLS-1),结果有点好笑,反正我们也不想要一个回合!!!