钳位到系列中的下一个最低值
Clamping to next lowest value in a series
我正在尝试将一个数字限定为一系列数字中的较低值。例如,如果我有一个系列(抱歉符号错误)
[pq]
其中 p
是任何整数,q
是任何正数。
假设 q is 50
我的系列会是 ...-150, -100, -50, 0, 50, 100, 150...
现在我想要的是有一个函数 f(y)
可以将任何数字限制在系列中的下一个最小数字。
例如,如果我有号码 37
,我会期待 f(37) = 0
,我会期待 f(-37) = -50
。
我尝试了很多涉及模数和整数除法的算法,但我似乎无法弄明白。我试过的最新版本是
(37 / q) * q
这对正数很有效,但对 -50 和 0 之间的任何数字都不起作用。
我也试过 ((37 - q) / q) * q
但这不适用于正好落在系列中的负面案例。
编辑
假设我没有整个系列,只有系列的乘数 p
。
您可以在确定模数结果为正后减去模数结果。在某些语言中,它 总是 是正数,但如果不是:
mod = p % q
positive_mod = (mod + q) % q
answer = p - positive_mod
C++ 结果:https://ideone.com/kIuit8
结果Python:https://ideone.com/w6wUgZ
如果你想要纯数学的方式,不考虑计算效率,你可以将输入p
移到正整数范围内,加上一个大于或等于[=的正整数11=] 是 q
的倍数,然后再减去。 p^2*q
满足这个。
这给出:
((p + p^2*q) / q) * q - p^2*q
您只需使用整数欧氏除法将 y
除以 q
,然后再将结果乘以 q
。
f(y) = (y / q) * q
其中 /
表示欧氏除法。
在不立即支持欧氏除法的编程语言中,您将不得不手动实现它或调整该语言支持的任何除法的结果。
例如,在 C 和 C++ 中,正除数的欧几里德除法 q
可以通过本机 "Fortran-style" 除法实现为
(y >= 0 ? y : y - q + 1) / q
所以在 C 或 C++ 中,整个表达式看起来像
f(y) = (y >= 0 ? y : y - q + 1) / q * q
37
你得到
f(37) = 37 / 50 * 50 = 0
-37
你得到
f(-37) = (-37 - 50 + 1) / 50 * 50 = -86 / 50 * 50 = -50
我正在尝试将一个数字限定为一系列数字中的较低值。例如,如果我有一个系列(抱歉符号错误)
[pq]
其中 p
是任何整数,q
是任何正数。
假设 q is 50
我的系列会是 ...-150, -100, -50, 0, 50, 100, 150...
现在我想要的是有一个函数 f(y)
可以将任何数字限制在系列中的下一个最小数字。
例如,如果我有号码 37
,我会期待 f(37) = 0
,我会期待 f(-37) = -50
。
我尝试了很多涉及模数和整数除法的算法,但我似乎无法弄明白。我试过的最新版本是
(37 / q) * q
这对正数很有效,但对 -50 和 0 之间的任何数字都不起作用。
我也试过 ((37 - q) / q) * q
但这不适用于正好落在系列中的负面案例。
编辑
假设我没有整个系列,只有系列的乘数 p
。
您可以在确定模数结果为正后减去模数结果。在某些语言中,它 总是 是正数,但如果不是:
mod = p % q
positive_mod = (mod + q) % q
answer = p - positive_mod
C++ 结果:https://ideone.com/kIuit8
结果Python:https://ideone.com/w6wUgZ
如果你想要纯数学的方式,不考虑计算效率,你可以将输入p
移到正整数范围内,加上一个大于或等于[=的正整数11=] 是 q
的倍数,然后再减去。 p^2*q
满足这个。
这给出:
((p + p^2*q) / q) * q - p^2*q
您只需使用整数欧氏除法将 y
除以 q
,然后再将结果乘以 q
。
f(y) = (y / q) * q
其中 /
表示欧氏除法。
在不立即支持欧氏除法的编程语言中,您将不得不手动实现它或调整该语言支持的任何除法的结果。
例如,在 C 和 C++ 中,正除数的欧几里德除法 q
可以通过本机 "Fortran-style" 除法实现为
(y >= 0 ? y : y - q + 1) / q
所以在 C 或 C++ 中,整个表达式看起来像
f(y) = (y >= 0 ? y : y - q + 1) / q * q
37
你得到
f(37) = 37 / 50 * 50 = 0
-37
你得到
f(-37) = (-37 - 50 + 1) / 50 * 50 = -86 / 50 * 50 = -50