1

我正在尝试将一个数字限制为一系列数字的较低值。例如,如果我有一个系列(抱歉记号不好)

[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

4

3 回答 3

2

如果您想要一种纯粹的数学方式,而不考虑计算效率,您可以p通过添加一个大于或等于|p|并且是 的倍数的正整数来将输入转换为正整数范围q,然后将其移回之后减去。p^2*q满足这一点。

这给出了: ((p + p^2*q) / q) * q - p^2*q

于 2018-02-21T04:19:25.933 回答
2

您只需使用整数欧几里得除法y进行q除法,然后再将结果乘以q

f(y) = (y / q) * q

其中/代表欧几里得划分。

在不立即支持欧几里得除法的编程语言中,您将不得不手动实现它或调整语言支持的任何除法的结果。

例如,在 C 和 C++ 中,正除数的欧几里得除法q可以通过本机“Fortran 风格”除法实现为

 (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
于 2018-02-21T04:38:37.083 回答
1

一旦你确定它是正数,你就可以减去模数结果。在某些语言中,它总是积极的,但如果不是:

mod = p % q
positive_mod = (mod + q) % q
answer = p - positive_mod

C++ 中的结果:https ://ideone.com/kIuit8

Python 中的结果:https ://ideone.com/w6wUgZ

于 2018-02-21T04:18:11.980 回答