请教java运算原理的一个问题

Leon_winter 2019-08-01 10:03:45
class Untitled {
public static void main(String[] args) {
long rt1 = 1;
int rt2 = 1;
int rt3 = 1;
int n = 19;
for(int i=0; i<n; i++){
rt1 = 2*(2*i+1)*rt1/(i+2);
rt2 = 2*(2*i+1)*rt2/(i+2);
rt3 = 2*(2*i+1)/(i+2)*rt3;
System.out.println("----");
System.out.println(i);
System.out.println((int)rt1);
System.out.println(rt2);
System.out.println(rt3);
}
}
}


输出中,只有rt1是正确的;rt2在i=16时,疑似发生了溢出,但是经过除法应该还在界限内;rt3仅仅把乘rt3的顺序改一下就发生了问题,这在python中是不存在的。
请教这是java中的哪一块知识呢?为何会这样呢?

输出结果

----
i:0
rt1:1
rt2:1
rt3:1
----
i:1
rt1:2
rt2:2
rt3:2
----
i:2
rt1:5
rt2:5
rt3:4
----
i:3
rt1:14
rt2:14
rt3:8
----
i:4
rt1:42
rt2:42
rt3:24
----
i:5
rt1:132
rt2:132
rt3:72
----
i:6
rt1:429
rt2:429
rt3:216
----
i:7
rt1:1430
rt2:1430
rt3:648
----
i:8
rt1:4862
rt2:4862
rt3:1944
----
i:9
rt1:16796
rt2:16796
rt3:5832
----
i:10
rt1:58786
rt2:58786
rt3:17496
----
i:11
rt1:208012
rt2:208012
rt3:52488
----
i:12
rt1:742900
rt2:742900
rt3:157464
----
i:13
rt1:2674440
rt2:2674440
rt3:472392
----
i:14
rt1:9694845
rt2:9694845
rt3:1417176
----
i:15
rt1:35357670
rt2:35357670
rt3:4251528
----
i:16
rt1:129644790
rt2:-108964504
rt3:12754584
----
i:17
rt1:477638700
rt2:50653648
rt3:38263752
----
i:18
rt1:1767263190
rt2:-27329867
rt3:114791256
...全文
73 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
guishuanglin 2019-08-01
  • 打赏
  • 举报
回复
1, 首先, 楼主你不能这么想, rt2 = 2*(2*i+1)*rt2/(i+2) != rt2 = 2*(2*i+1) * (rt2/(i+2) ); 因为你是整数相除, 尾数是去掉的, 如果 i = 0 rt2 = 2*(2*i+1) * (rt2/(i+2) ) = 0 rt2 = 2*(2*i+1)*rt2/(i+2) = 1 结果是不相同的. 2, 然后 溢出就改类型 你说第一个为什么正确? 因为你第一个是 long类型! 你把其它的改成 long类型, 保证你没有问题:

long rt1 = 1;
		long rt2 = 1;
		long rt3 = 1;
        int n = 19;
        for(int i=0; i < n; i++){
            rt1 = 2*(2*i+1)*rt1/(i+2);
            rt2 = 2*(2*i+1)*rt2/(i+2);
            rt3 = 2*(2*i+1)/(i+2)*rt3;
            System.out.println("--------");
            System.out.println("i = "+ i);
            System.out.println("rt1 = "+ rt1);
            System.out.println("rt2 = "+ rt2);
            System.out.println("rt3 = "+ rt3);
        }
结果:
--------
i = 0
rt1 = 1
rt2 = 1
rt3 = 1
--------
i = 1
rt1 = 2
rt2 = 2
rt3 = 2
--------
i = 2
rt1 = 5
rt2 = 5
rt3 = 4
--------
i = 3
rt1 = 14
rt2 = 14
rt3 = 8
--------
i = 4
rt1 = 42
rt2 = 42
rt3 = 24
--------
i = 5
rt1 = 132
rt2 = 132
rt3 = 72
--------
i = 6
rt1 = 429
rt2 = 429
rt3 = 216
--------
i = 7
rt1 = 1430
rt2 = 1430
rt3 = 648
--------
i = 8
rt1 = 4862
rt2 = 4862
rt3 = 1944
--------
i = 9
rt1 = 16796
rt2 = 16796
rt3 = 5832
--------
i = 10
rt1 = 58786
rt2 = 58786
rt3 = 17496
--------
i = 11
rt1 = 208012
rt2 = 208012
rt3 = 52488
--------
i = 12
rt1 = 742900
rt2 = 742900
rt3 = 157464
--------
i = 13
rt1 = 2674440
rt2 = 2674440
rt3 = 472392
--------
i = 14
rt1 = 9694845
rt2 = 9694845
rt3 = 1417176
--------
i = 15
rt1 = 35357670
rt2 = 35357670
rt3 = 4251528
--------
i = 16
rt1 = 129644790
rt2 = 129644790
rt3 = 12754584
--------
i = 17
rt1 = 477638700
rt2 = 477638700
rt3 = 38263752
--------
i = 18
rt1 = 1767263190
rt2 = 1767263190
rt3 = 114791256
qq_39936465 2019-08-01
  • 打赏
  • 举报
回复
引用 楼主 Leon_winter 的回复:
输出中,只有rt1是正确的;rt2在i=16时,疑似发生了溢出,但是经过除法应该还在界限内;rt3仅仅把乘rt3的顺序改一下就发生了问题,这在python中是不存在的。 请教这是java中的哪一块知识呢?为何会这样呢?
你不能只看结果,在运算过程中,int就溢出了,当然会出错 基本类型:int 二进制位数:32 包装类:java.lang.Integer 最小值:Integer.MIN_VALUE= -2147483648 (-2的31次方) 最大值:Integer.MAX_VALUE= 2147483647  (2的31次方-1) 当i=16时 2*(2*16+1)*35357670=66*35357670>2147483647 先溢出然后再做的除法。编程要注意中间运算过程中的溢出情况。

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧