GCD-infinate循环的Java二进制方法
我用二进制方法来计算两个分数的GCD,这个方法非常好用,除了我从两个分数中减去某些数字 我假设这是因为,例如,当我从1/6中减去2/15时,GCD有一个重复的数字或类似的东西,尽管我可能是错的GCD-infinate循环的Java二进制方法,java,infinite-loop,greatest-common-divisor,Java,Infinite Loop,Greatest Common Divisor,我用二进制方法来计算两个分数的GCD,这个方法非常好用,除了我从两个分数中减去某些数字 我假设这是因为,例如,当我从1/6中减去2/15时,GCD有一个重复的数字或类似的东西,尽管我可能是错的 //The following lines calculate the GCD using the binary method if (holderNum == 0) { gcd = holderDem; }
//The following lines calculate the GCD using the binary method
if (holderNum == 0)
{
gcd = holderDem;
}
else if (holderDem == 0)
{
gcd = holderNum;
}
else if ( holderNum == holderDem)
{
gcd = holderNum;
}
// Make "a" and "b" odd, keeping track of common power of 2.
final int aTwos = Integer.numberOfTrailingZeros(holderNum);
holderNum >>= aTwos;
final int bTwos = Integer.numberOfTrailingZeros(holderDem);
holderDem >>= bTwos;
final int shift = Math.min(aTwos, bTwos);
// "a" and "b" are positive.
// If a > b then "gdc(a, b)" is equal to "gcd(a - b, b)".
// If a < b then "gcd(a, b)" is equal to "gcd(b - a, a)".
// Hence, in the successive iterations:
// "a" becomes the absolute difference of the current values,
// "b" becomes the minimum of the current values.
if (holderNum != gcd)
{
while (holderNum != holderDem)
{
//debuging
String debugv3 = "Beginning GCD binary method";
System.out.println(debugv3);
//debugging
final int delta = holderNum - holderDem;
holderNum = Math.min(holderNum, holderDem);
holderDem = Math.abs(delta);
// Remove any power of 2 in "a" ("b" is guaranteed to be odd).
holderNum >>= Integer.numberOfTrailingZeros(holderNum);
gcd = holderDem;
}
}
// Recover the common power of 2.
gcd <<= shift;
//以下几行使用二进制方法计算GCD
if(holderNum==0)
{
gcd=holderDem;
}
else if(holderDem==0)
{
gcd=holderNum;
}
else if(holderNum==holderDem)
{
gcd=holderNum;
}
//将“a”和“b”设为奇数,跟踪2的公共幂。
最终int aTwos=整数。跟踪零的数量(holderNum);
holderNum>>=aTwos;
final int bTwos=整数。跟踪零的数目(holderDem);
holderDem>>=bTwos;
最终整数移位=数学最小值(aTwos、bTwos);
//“a”和“b”是正的。
//如果a>b,那么“gdc(a,b)”等于“gcd(a-b,b)”。
//如果a>=整数。跟踪零的数目(holderNum);
gcd=holderDem;
}
}
//恢复2的公能。
gcd问题在于负值-当其中一个为负值时,holderNum
将始终采用负值(即最小值)holderDem
将变为正数,因此delta
等于负减去正等于负。然后,holderDem=abs(delta)
是一个更大的正值,并不断增加。在进入循环之前,您应该获取它们的绝对值
例如:
holderNum=-1
和holderDem=6
迭代1:
delta = holderNum - holderDem = -1 - 6 = -7
holderNum = Math.min(holderNum, holderDem) = Math.min(-1, 6) = -1
holderDem = Math.abs(delta) = Math.abs(-7) = 7
迭代2:
delta = holderNum - holderDem = -1 - 7 = -8
holderNum = Math.min(holderNum, holderDem) = Math.min(-1, 7) = -1
holderDem = Math.abs(delta) = Math.abs(-7) = 8
等等等等等等。你有没有试着打印出一些有用的东西,比如“holderNum”和“holderDem”的值?这样你就可以看到这些数字在做什么,而不是猜测。如何保证“b”是奇数?对于holderNum
和holderDem
的哪些值,它是否进入了无限循环?是的,当我打印这些值时,使用给定的示例,holderNum保持在-3,而holderDem不断增加,1195095是在我强制退出之前得到的值。对于哪些值?这对我很有效,举个例子,比如2/15减去1/6。或者1/1减去1/1。但是如果我在那里放一个断点,它工作得很好,我想它工作得很好?我可以看到那里的问题,但是即使我放进去取Num和Dem的abs值,在循环内或循环外,它仍然无限迭代。我不得不添加while(holderDem!=0&&holderNum!=holderDem&&holderNum!=0)
。holderNum
或holderDem
应该是0
的唯一原因是如果它们以该值开头-在这种情况下,它们应该在开头被捕获(现在我注意到,if(holderNum!=gcd)
行也应该测试holderDem
)-或者如果它们在循环开始时相等-在这种情况下,循环应停止。如果你在这段代码开始的时候取绝对值,我不明白为什么它会进入一个无限循环。我也不知道。这真的很奇怪,我认为一些Python进入了我的Java。