我继承了一个函数的维护,该函数将 0
和 65535
(含)之间的值作为参数:
MyClass::mappingFunction(无符号短标题索引);
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
背后的意图是什么?我知道它本质上是将最大输入范围划分为离散的 block ,但然后将其添加到headingIndex
似乎是一件奇怪的事情。roundedIndex
那么原始值现在偏移或顺时针方向旋转了一些偏移量吗?
该算法产生的结果如下:
headingIndex of 0 --> symbol 0
headingIndex of 100 --> symbol 1
headingIndex of 65500 --> symbol 35
我想一定有更好的方法来做到这一点?
最佳答案
显示的代码看起来非常复杂(这可能是为了防止整数溢出)。确定符号编号的一种更简单的方法是使用如下代码:
symbol = (headingIndex * 36u) / 65536u;
但是,如果这确实出现整数溢出问题,则可以以双
精度进行计算,将结果转换回int
四舍五入后:
symbol = static_cast<int>( ((headindIndex * 36.0) / 65536.0) + 0.5 ); // Add 0.5 for rounding.
关于c++ - 在 C++ 中将连续范围映射到离散区间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64770824/