Jas*_*ase 81 c# math integer integer-arithmetic
设a,b和c为非大正整数.a/b/c是否始终等于/(b*c)与C#整数运算?对我来说,在C#中它看起来像:
int a = 5126, b = 76, c = 14;
int x1 = a / b / c;
int x2 = a / (b * c);
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:x1 == x2
为所有a,b和c做什么?
Eri*_*ert 77
我非常喜欢这个问题,于2013年6月4日将其作为我博客的主题.谢谢你这个好问题!
大案件很容易找到.例如:
a = 1073741823;
b = 134217727;
c = 134217727;
Run Code Online (Sandbox Code Playgroud)
因为b * c
溢出为负数.
我想补充到这一事实,在检查算术,之间的差异a / (b * c)
,并(a / b) / c
可以是工作的程序和崩溃的程序之间的差异.如果产品b
和c
溢出的整数的范围那么前者将在检查范围内崩溃.
对于小的正整数,比如说小到足以适应短的整数,应该保持身份.
蒂莫西·希尔兹刚刚发布了证据; 我在这里提出另一种证据.假设这里的所有数字都是非负整数,并且没有任何操作溢出.
的整数除法x / y
发现值q
,使得q * y + r == x
,其中0 <= r < y
.
所以该师a / (b * c)
找到了q1
这样的价值
q1 * b * c + r1 == a
Run Code Online (Sandbox Code Playgroud)
哪里 0 <= r1 < b * c
划分( a / b ) / c
第一发现值qt
,使得
qt * b + r3 == a
Run Code Online (Sandbox Code Playgroud)
然后发现值q2
,使得
q2 * c + r2 == qt
Run Code Online (Sandbox Code Playgroud)
所以替换为in qt
,我们得到:
q2 * b * c + b * r2 + r3 == a
Run Code Online (Sandbox Code Playgroud)
在哪里0 <= r2 < c
和0 <= r3 < b
.
两个相同的东西彼此相等,所以我们有
q1 * b * c + r1 == q2 * b * c + b * r2 + r3
Run Code Online (Sandbox Code Playgroud)
假设q1 == q2 + x
某个整数x
.替换为和解决x
:
q2 * b * c + x * b * c + r1 = q2 * b * c + b * r2 + r3
x = (b * r2 + r3 - r1) / (b * c)
Run Code Online (Sandbox Code Playgroud)
哪里
0 <= r1 < b * c
0 <= r2 < c
0 <= r3 < b
Run Code Online (Sandbox Code Playgroud)
可以x
大于零吗?不,我们有不平等:
b * r2 + r3 - r1 <= b * r2 + r3 <= b * (c - 1) + r3 < b * (c - 1) + b == b * c
Run Code Online (Sandbox Code Playgroud)
因此该分数的分子总是小于b * c
,因此x
不能大于零.
可以x
小于零?不,通过类似的论点,留给读者.
因此整数x
为零,因此q1 == q2
.
Tim*_*lds 71
设\
表示整数除法(/
两个int
s 之间的C#运算符),并/
表示通常的数学除法.然后,如果x,y,z
是正整数而我们忽略溢出,
(x \ y) \ z
= floor(floor(x / y) / z) [1]
= floor((x / y) / z) [2]
= floor(x / (y * z))
= x \ (y * z)
Run Code Online (Sandbox Code Playgroud)
哪里
a \ b = floor(a / b)
Run Code Online (Sandbox Code Playgroud)
上面从一行[1]
到另一行的跳跃[2]
解释如下.假设您有两个整数a
和范围内b
的小数.很容易看出来f
[0, 1)
floor(a / b) = floor((a + f) / b) [3]
Run Code Online (Sandbox Code Playgroud)
如果在行中[1]
你识别a = floor(x / y)
,f = (x / y) - floor(x / y)
和b = z
,那么[3]
暗示[1]
并且[2]
相等.
您可以将此证明推广为负整数(仍然忽略溢出),但我会将其留给读者以保持简单.
关于溢出问题- 请参阅Eric Lippert的答案以获得一个很好的解释!他在博客文章中也采取了更加严谨的方法并回答,如果你觉得我太过手淫,你应该考虑一下.
归档时间: |
|
查看次数: |
3902 次 |
最近记录: |