将双精度的连续范围转换为离散的整数范围

Convert a continuous range of doubles to a discrete int range

提问人:zellidev0 提问时间:9/14/2021 最后编辑:zellidev0 更新时间:9/29/2021 访问量:207

问:

我想将双精度值 [10.0,20.0] 的连续范围映射到 [100,200] 范围内的字节;

必须满足以下条件(即使多次来回转换):

convertToByte(convertToDouble(y)) == y

谢谢。

飞镖 映射 四舍五入 浮动精度

评论

0赞 Eric Postpischil 9/14/2021
您是否知道 (20 - 10) / (200 - 100) (等效于 1/10) 不能以 Dart 使用的格式表示?它将四舍五入为 0.10000000000000000055511151231257827021181583404541015625。另一方面,当该倍数相加到 10 时,其中一些将高于目标(10.1、10.2、10.3 等),而另一些将低于目标。例如,对于 3 个步骤,结果将是 10.3000000000000000710542735760100185871124267578125。你真的希望它映射到 102 吗,即使它通过了 10.3?double
0赞 zellidev0 9/14/2021
我知道它会四舍五入。你提到的正是问题所在。我对另一种“映射逻辑”持开放态度,只要它始终如一地将相同的值映射到特定字节,并且多次来回转换它们,从而给出相同的可预测结果。
1赞 lrn 9/14/2021
你希望它如何四舍五入?只考虑convertToByte(double n) => (n * 10).round();
0赞 zellidev0 9/14/2021
这将是合适的。但最终数字正在发生变化,所以系数不会是 10,而是 .当我多次来回转换它们时,有些值没有正确映射。6/95
1赞 lrn 9/14/2021
因此,您要映射任意范围的双打 a。b 到字节范围 c..d. 我可能会试试.由于是一个相对较小的整数,是一个精确的值,具有结果的近似大小。这至少应该最大限度地减少舍入误差。convertToByte(double x) { var r = d - c; return c + (r * x - r * a)/(b-a).round(); }d-cr

答:

0赞 zellidev0 9/15/2021 #1

借助对问题的评论,我们使用以下代码:

int convertToByte(
    double initial,
    double minValue,
    double maxValue,
    int minByte,
    int maxByte,
  ) {
    double value = initial - minValue;
    double valueRange = maxValue - minValue;
    int byteRange = maxByte - minByte;
    double valueSteps = valueRange / byteRange;
    double byte = (value / valueSteps);
    return (minByte + byte.round()).clamp(minByte, maxByte);
  }

不会为指定的测试提供解决方案,而是为特定值提供确定性答案。 当将字节转换回值时,反之亦然,多次输出始终保持不变。 这就是我们的应用程序所需要的。

评论

1赞 Eric Postpischil 9/15/2021
您应该更新问题以说明条件:convertToByte(convertToDouble(y)) = y 是必需的,但问题中显示的测试用例不是必需的。