Greatest Common Divisor

blov · · 549 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hello! So I&#39;m dipping my toes into Go and I thought I would try to translate Euclidian algorithm from Python:</p> <pre><code>def gcd(a, b): while b != 0: a, b = b, a % b return a </code></pre> <p>Here&#39;s what I have so far:</p> <pre><code>func GCD(a, b big.Int) big.Int { t := new(big.Int) zero := big.NewInt(0) for b.Cmp(&amp;zero) != 0 { t.Rem(&amp;a, &amp;b) a, b, t = b, t, a } return a } </code></pre> <p>But it complains &#34;cannot use x (type big.Int) as type *big.Int in argument to t.Rem&#34;. Please, can anyone tell me what is the canonical way to write GCD? Also how to properly test big.Int for zero?</p> <hr/>**评论:**<br/><br/>titpetric: <pre><p>Apart from some pointer assignments I guess you were pretty close?</p> <p><a href="https://play.golang.org/p/pcykcguK9T" rel="nofollow">https://play.golang.org/p/pcykcguK9T</a></p> <ol> <li>new(big.Int) returns a <code>*big.Int</code> (a pointer to a <code>big.Int</code>),</li> <li>big.NewInt(value) returns a <code>*big.Int</code> (a pointer to a <code>big.Int</code>)</li> </ol> <p>I&#39;m going to assume that this is correct, and that you should always use NewInt notation to create a bigint value. As such, I changed the parameters of GCD to accept a poiner.</p> <p>Functions like b.Cmp and t.Rem expect pointer values. Since zero, a and b variables are already pointers, you don&#39;t need to add <code>&amp;</code> in front of them. Having <code>&amp;a</code> produces a pointer to a pointer to big.Int (or <code>**big.Int</code>) and is incompatible with those functions.</p> <p>Finally, in order to return a <code>big.Int</code>, I changed the final return to <code>return *a</code>. This &#34;reads&#34; the <code>big.Int</code> value from the pointer and returns that, instead of the pointer.</p> <p>I think the big.Int test for zero is correct, godoc verifies:</p> <blockquote> <p>Cmp compares x and y and returns:</p> <p>-1 if x &lt; y</p> <p>0 if x == y</p> <p>+1 if x &gt; y</p> </blockquote> <p>Edit: there are some <code>Mod</code> and <code>DivMod</code> functions available in <a href="https://godoc.org/math/big#Int.Mod" rel="nofollow">math/big</a>, which I suppose you&#39;d want to use if you wanted to have a 1-1 <code>a % b</code> (modulo) reimplementation. I didn&#39;t dig into the math if using t.Rem is kosher here, but the result seems valid.</p></pre>mamemimu: <pre><p>Thank you, that&#39;s exactly what I needed to read!</p></pre>Mythiix: <pre><p>If dealing with standard int, couldn&#39;t you just implement the same logic? <a href="https://play.golang.org/p/GVPWXGjKj_" rel="nofollow">https://play.golang.org/p/GVPWXGjKj_</a></p> <pre><code>func gcd(x, y int) int { for y != 0 { fmt.Println(x, y) x, y = y, x%y } return x } </code></pre></pre>mamemimu: <pre><p>I just wanted to try to implement full Python equivalent.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

549 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传