Math 计算两个区间的模
我想了解模运算符在应用于两个区间时是如何工作的。两个区间的加、减和乘在代码中实现起来很简单,但如何实现模数呢 如果有人能给我看公式、示例代码或解释其工作原理的链接,我会很高兴 背景信息:您有两个整数Math 计算两个区间的模,math,intervals,modulo,integer-arithmetic,Math,Intervals,Modulo,Integer Arithmetic,我想了解模运算符在应用于两个区间时是如何工作的。两个区间的加、减和乘在代码中实现起来很简单,但如何实现模数呢 如果有人能给我看公式、示例代码或解释其工作原理的链接,我会很高兴 背景信息:您有两个整数x\u-lo
x\u-lo
和y\u-lo
。mod(x,y)
的上下限是多少
编辑:我不确定是否有可能以有效的方式得出最小边界(不计算所有x或所有y的mod)。如果是这样,那么我将接受一个精确但非最优的边界答案。显然,[-inf,+inf]是正确的答案:)但我想要一个大小更有限的边界。让我们看看mod(x,y)=mod。
一般来说,这是一个有趣的问题。假设对于整数区间,模是相对于截断除法定义的(四舍五入到0) 因此,
mod(-a,m)==-mod(a,m)
用于所有a,m。此外,符号(mod(a,m))==符号(a)
定义,在我们开始之前
从a到b的关闭间隔:[a,b]
空间隔:
[]:=[+Inf,-Inf]
否定:
-[a,b]:=[-b,-a]
联合:
[a,b]u[c,d]:=[min(a,c),max(b,d)]
绝对值:
|m |::=最大值(m,-m)
更简单的情况:固定模量m
从固定的m
开始更容易。稍后我们将把它推广到两个区间的模。定义以递归方式建立。用您最喜欢的编程语言实现这一点应该没有问题。伪代码:
def mod1([a,b], m):
// (1): empty interval
if a > b || m == 0:
return []
// (2): compute modulo with positive interval and negate
else if b < 0:
return -mod1([-b,-a], m)
// (3): split into negative and non-negative interval, compute and join
else if a < 0:
return mod1([a,-1], m) u mod1([0,b], m)
// (4): there is no k > 0 such that a < k*m <= b
else if b-a < |m| && a % m <= b % m:
return [a % m, b % m]
// (5): we can't do better than that
else
return [0,|m|-1]
玩得开心!:) 一个区间的模是如何定义的?它不是。我要做的运算是两个区间的模,就像你可以对两个区间进行除法一样。如果y是固定的,你可以通过查看mod(x_-lo,y)和mod(x_-hi,y)来计算范围。但是随着y的变化,mod值中没有简单的模式。我认为这里除了计算每个y的mod(x_lo,y)和mod(x_hi,y)并取它们所绑定的区间的并集之外,没有太多的工作要做。但在
mod([2,2],-3,-3])=[2,2]
中,则y_lo
不正确。y€[2,4],x€[2,4]->取x=3,y=3,结果:0。查看上面的语句并填入值,得到1<0<1。。。这显然不是真的。
def mod1([a,b], m):
// (1): empty interval
if a > b || m == 0:
return []
// (2): compute modulo with positive interval and negate
else if b < 0:
return -mod1([-b,-a], m)
// (3): split into negative and non-negative interval, compute and join
else if a < 0:
return mod1([a,-1], m) u mod1([0,b], m)
// (4): there is no k > 0 such that a < k*m <= b
else if b-a < |m| && a % m <= b % m:
return [a % m, b % m]
// (5): we can't do better than that
else
return [0,|m|-1]
def mod2([a,b], [m,n]):
// (1): empty interval
if a > b || m > n:
return []
// (2): compute modulo with positive interval and negate
else if b < 0:
return -mod2([-b,-a], [m,n])
// (3): split into negative and non-negative interval, compute, and join
else if a < 0:
return mod2([a,-1], [m,n]) u mod2([0,b], [m,n])
// (4): use the simpler function from before
else if m == n:
return mod1([a,b], m)
// (5): use only non-negative m and n
else if n <= 0:
return mod2([a,b], [-n,-m])
// (6): similar to (5), make modulus non-negative
else if m <= 0:
return mod2([a,b], [1, max(-m,n)])
// (7): compare to (4) in mod1, check b-a < |modulus|
else if b-a >= n:
return [0,n-1]
// (8): similar to (7), split interval, compute, and join
else if b-a >= m:
return [0, b-a-1] u mod2([a,b], [b-a+1,n])
// (9): modulo has no effect
else if m > b:
return [a,b]
// (10): there is some overlapping of [a,b] and [n,m]
else if n > b:
return [0,b]
// (11): either compute all possibilities and join, or be imprecise
else:
return [0,n-1] // imprecise