在使用dotnetfiddle解决一些练习问题时,我遇到了一些非常奇怪的事情.我有一个应用数学序列的程序(每个步骤的不同计算取决于当前步骤是偶数还是奇数):
using System;
public class Program
{
public static void Main()
{
int ceiling = 1000000;
int maxMoves = 0;
int maxStart = 0;
int testNumber;
for(int i = 1; i <= ceiling; i++){
testNumber = i;
int moves = 1;
while(testNumber != 1){
if(testNumber % 2 == 0){
testNumber = testNumber / 2;
moves++;
} else {
testNumber = (3 * testNumber) + 1;
moves++;
}
}
if(moves > maxMoves){
maxMoves = moves;
maxStart = i;
}
}
Console.WriteLine(maxStart);
Console.WriteLine(maxMoves);
}
}
Run Code Online (Sandbox Code Playgroud)
如上所述,超出了执行时间限制.但是,如果我将测试编号的声明更改为long而不是int,则程序将运行:
int maxMoves = 0;
int maxStart = 0;
**long** testNumber;
Run Code Online (Sandbox Code Playgroud)
为什么要进行这种改变,需要i从for循环(at )int的long每个增量进行重构testNumber = i,要比将其作为一个int?是否在long数值上更快地执行数学运算?
原因似乎是溢出.如果你运行的代码包含在
checked
{
// your code
}
Run Code Online (Sandbox Code Playgroud)
你得到一个OverflowException与testNumberas一起跑步的时候int.
原因是最终3*testNumber+1超出了界限int.在一个unchecked方面,这并不抛出异常,但会造成负面的价值观testNumber.
此时你的序列(我认为它是Collatz,对吗?)不再起作用,计算需要(可能无限期)更长,因为你永远不会达到1(或者至少它需要你更多的迭代才能达到1).
| 归档时间: |
|
| 查看次数: |
101 次 |
| 最近记录: |