我制作了一个程序来执行(通常称为)hailstone序列,该程序基本上是这样做的:
创建int
(值)并为其赋值。
如果int是偶数,则除以2。
如果int是奇数,则将其乘以3并加1。继续此过程,直到n等于1。
它似乎与大多数数字一样正常,但这个数字99888769,应用程序挂起一个负整数。这是为什么?他们说没有人能够证明它停止了,我没想到我已经解决了这个问题。但知道为什么我的应用程序停止会很有趣。 -
private void hailStoneSequence(){
int value = 99888769;
int i = 0;
boolean trueOrFalse = isOddOrEven (value);
while (value != 1){
while (trueOrFalse == true && value != 1){
i++;
int previousValue = value;
value = value / 2;
println( previousValue +" is even, so I take half: "+value);
trueOrFalse = isOddOrEven (value); // returning true or false, and inserting the newly divided number. So that it breaks loop when nescesary.
}
while (trueOrFalse == false && value != 1){
i++;
int previousValue = value;
value = (value * 3) + 1;
println (previousValue +" is odd, so I make 3n+1: "+value);
trueOrFalse = isOddOrEven (value);
}
}
println ("\n\nThe process took "+i+" to reach "+value);
}
private boolean isOddOrEven(int value){
/*
* Takes an value and returns true, if that number is even.
* Else it returns false.
*/
if (value % 2 != 0){
return false;
}else{
return true;
}
}
}
答案 0 :(得分:7)
当你不断增加int
时,它们最终会(看起来像一个令人吃惊的行为)变成负数,因为你超过了int类型的最大值(2 ^ 31-1),即你最终改变用于存储数字符号的位(int的二进制表示)。请改用long
。
答案 1 :(得分:3)
你实际上选了一个有趣的起始号码。从那里开始,你最终得到的数字是:768879215。将它乘以3并加1超过了int可以存储的最大值(2 ^ 31-1),因此它“溢出”为负数。对于负数,冰雹序列并不总是收敛到1,事实上在这种情况下它会永远重复以下序列:
-122
-61
-182
-91
-272
-136
-68
-34
-17
-50
-25
-74
-37
-110
-55
-164
-82
-41
-122
您可以使用long
替代,您的代码最多可以使用(2 ^ 63-1),或者使用BigInteger
类,它适用于任何数字。
答案 2 :(得分:2)
因为整数溢出。改为使用“long”,代码运行正常,至少在序列超出longs范围之前。
答案 3 :(得分:2)
你的逻辑对我来说似乎很复杂。重新编写代码以使其更清晰,您应该能够看到发生了什么:
public class HailStoneSequence {
public void sequence() {
int value = 99888769;
int i = 0;
while (value != 1) {
int previousValue = value;
if (value % 2 == 0) {
value = value / 2;
System.out.println(previousValue + " is even, so I take half: " + value);
} else {
value = (value * 3) + 1;
System.out.println(previousValue + " is odd, so I make 3n+1: " + value);
}
}
i++;
System.out.println("\n\nThe process took " + i + " to reach " + value);
}
/**
* @param args
*/
public static void main(String[] args) {
HailStoneSequence instance = new HailStoneSequence();
instance.sequence();
}
}
现在,如果你运行它,你应该看到它不会停止,但它会重复。因此,它产生了一个无限的系列....
答案 4 :(得分:1)
您的初始种子值会导致您达到“int”数据类型的整数溢出。这导致重复的负值序列。您可以更改为使用“长”数据类型,也可以使用不同(较小)的种子值开始。
public class HailStoneSequence
{
public static void processSequence()
{
long value = 99888769; // works due to larger type range
// int value = 99888769; // causes negative repeating sequence
// int value = 81; // works with smaller seed
int i=0;
while(value != 1)
{
System.out.println("The value is:" + value);
i++;
if(value % 2 == 0)
{
value /= 2;
}
else
{
value = value * 3 + 1;
}
}
System.out.println("The process took " + i + " iterations to solve.");
}
public static void main(String[] args)
{
System.out.println("Begin Hailstorm:");
HailStoneSequence.processSequence();
System.out.println("End Hailstorm:");
}
}