将数字四舍五入到同一范围内最接近的 5 或 10 的倍数,具体取决于第一个数
Rounding numbers to nearest multiple of 5 or 10 in the same range depending on what's first
我正在开发一个统计应用程序,但我遇到了舍入问题。
我想显示一个图表,该图表有多个点都连接到线。
为了能够自动调整比例,我想执行某种计算。我已经知道该怎么做,但我无法将其正确翻译成代码。
所以这就是我想要做的:
我查看我的值列表以找到最大值。
在我的图形中,我有 6 条参考线。因此,我将我的价值除以少于一个头寸数量,以确保我得到一个值(当乘以实际头寸数量时)将大于我的最大数量,这样我的线就不会'走出我的图形。
获得此值后,我需要在同一范围内获取最接近的整数 5 或 10(取决于先出现的)。
所以给你举几个例子:
example 1:
initial value = 685425
divided value = 685425/5 = 137085 => rounded value = 150000
example 2:
initial value = 53
divided value = 53/5 = 10.6 => rounded value = 15
example 3:
initial value = 8215
divided value = 8215/5 = 1643 => rounded value = 2000
所以我总是四舍五入到最接近的 5 或 10 的倍数,但在相同的范围内。
如何将其放入代码中?
谢谢,
肯尼斯
public static int GetLimit(int v)
{
int by5 = v / 5;
// for too small numbers we return early
if (by5 < 0) return 0;
if (by5 < 5) return 5;
if (by5 < 10) return 10;
int log = (int)Math.Log10(by5) - 1;
int scope = (int)Math.Pow(10, log);
int tmp = by5 / scope;
tmp = 5 * ((tmp/5) + 1);
return tmp * scope;
}
这使用十进制对数得到 "range" (scope
)。然后它将数字除以该范围以获得前两位数字,"rounds" 它们到下一个 5 的倍数 (5*((tmp/5) + 1)
) 并再次乘以范围以返回范围。
对于太小的数字(低于 50),它会提前 returns,因为 scope
会变成 0
,这会导致 DivideByZeroException
。
Console.WriteLine(GetLimit(685425));
Console.WriteLine(GetLimit(53));
Console.WriteLine(GetLimit(8215));
Console.WriteLine(GetLimit(11));
Console.WriteLine(GetLimit(2));
结果
150000
15
2000
5
5
使用 Math.Log
和 Math.Pow
的替代方法是将除数转换为具有前两位数字和长度的字符串。我没有测试这是否可以更快,但我不这么认为。如果这对性能至关重要,您需要对其进行测试。
我正在开发一个统计应用程序,但我遇到了舍入问题。 我想显示一个图表,该图表有多个点都连接到线。 为了能够自动调整比例,我想执行某种计算。我已经知道该怎么做,但我无法将其正确翻译成代码。
所以这就是我想要做的: 我查看我的值列表以找到最大值。 在我的图形中,我有 6 条参考线。因此,我将我的价值除以少于一个头寸数量,以确保我得到一个值(当乘以实际头寸数量时)将大于我的最大数量,这样我的线就不会'走出我的图形。
获得此值后,我需要在同一范围内获取最接近的整数 5 或 10(取决于先出现的)。
所以给你举几个例子:
example 1:
initial value = 685425
divided value = 685425/5 = 137085 => rounded value = 150000
example 2:
initial value = 53
divided value = 53/5 = 10.6 => rounded value = 15
example 3:
initial value = 8215
divided value = 8215/5 = 1643 => rounded value = 2000
所以我总是四舍五入到最接近的 5 或 10 的倍数,但在相同的范围内。
如何将其放入代码中?
谢谢, 肯尼斯
public static int GetLimit(int v)
{
int by5 = v / 5;
// for too small numbers we return early
if (by5 < 0) return 0;
if (by5 < 5) return 5;
if (by5 < 10) return 10;
int log = (int)Math.Log10(by5) - 1;
int scope = (int)Math.Pow(10, log);
int tmp = by5 / scope;
tmp = 5 * ((tmp/5) + 1);
return tmp * scope;
}
这使用十进制对数得到 "range" (scope
)。然后它将数字除以该范围以获得前两位数字,"rounds" 它们到下一个 5 的倍数 (5*((tmp/5) + 1)
) 并再次乘以范围以返回范围。
对于太小的数字(低于 50),它会提前 returns,因为 scope
会变成 0
,这会导致 DivideByZeroException
。
Console.WriteLine(GetLimit(685425));
Console.WriteLine(GetLimit(53));
Console.WriteLine(GetLimit(8215));
Console.WriteLine(GetLimit(11));
Console.WriteLine(GetLimit(2));
结果
150000
15
2000
5
5
使用 Math.Log
和 Math.Pow
的替代方法是将除数转换为具有前两位数字和长度的字符串。我没有测试这是否可以更快,但我不这么认为。如果这对性能至关重要,您需要对其进行测试。