golang – modulus using math big package

huangapple go评论86阅读模式
英文:

golang - modulus using math big package

问题

阅读文档 - http://golang.org/pkg/math/big/

Mod 将 z 设置为 x%y 的模数,其中 y != 0,并返回 z。如果 y == 0,则会发生除以零的运行时恐慌。Mod 实现了欧几里德模数(与 Go 不同);有关更多详细信息,请参阅 DivMod。

10%4 = 2,但是使用 math/big 包时我得到了 8 - http://play.golang.org/p/_86etDvLYq

package main

import "fmt"
import "math/big"
import "strconv"

func main() {
    ten := new(big.Int)
	ten.SetBytes([]byte(strconv.Itoa(10)))
	
	four := new(big.Int)
	four.SetBytes([]byte(strconv.Itoa(4)))
	
	tenmodfour := new(big.Int)
	tenmodfour = tenmodfour.Mod(ten, four)
	
	fmt.Println("mod", tenmodfour)
		
}

我很可能弄错了什么。哪里出错了?

英文:

Reading up the documentation - http://golang.org/pkg/math/big/

Mod sets z to the modulus x%y for y != 0 and returns z. If y == 0, a division-by-zero run-time panic occurs. Mod implements Euclidean modulus (unlike Go); see DivMod for more details.

10%4 = 2 but I get 8 with this (using the math/big package to do the same thing) - http://play.golang.org/p/_86etDvLYq

package main

import "fmt"
import "math/big"
import "strconv"

func main() {
    ten := new(big.Int)
	ten.SetBytes([]byte(strconv.Itoa(10)))
	
	four := new(big.Int)
	four.SetBytes([]byte(strconv.Itoa(4)))
	
	tenmodfour := new(big.Int)
	tenmodfour = tenmodfour.Mod(ten, four)
	
	fmt.Println("mod", tenmodfour)
		
}

I most likely got something wrong. Where's the mistake?

答案1

得分: 7

这是要翻译的内容:

这是因为SetBytes并不是你想象中的那样!请使用SetInt64代替。

ten := new(big.Int)
ten.SetBytes([]byte(strconv.Itoa(10)))

four := new(big.Int)
four.SetBytes([]byte(strconv.Itoa(4)))

fmt.Println(ten, four)

结果:

12592 52

确实,12592%52 == 8

如果你想使用比int64允许操作的数字更大的数值,你也可以使用SetString函数:

n := new(big.Int)
n.SetString("456135478645413786350", 10)
英文:

It's because SetBytes is not doing what you think! Use SetInt64 instead.

ten := new(big.Int)
ten.SetBytes([]byte(strconv.Itoa(10)))

four := new(big.Int)
four.SetBytes([]byte(strconv.Itoa(4)))

fmt.Println(ten, four)

Result:

12592 52

And indeed, 12592%52 == 8

If you want to use numbers bigger than what int64 lets you manipulate, you can also use the SetString function:

n := new(big.Int)
n.SetString("456135478645413786350", 10)

答案2

得分: 4

julienc的答案中有一个补充,如果你想使用SetBytes,你需要将数字转换为字节,就像这样

func int2bytes(num int) (b []byte) {
    b = make([]byte, 4)
    binary.BigEndian.PutUint32(b, uint32(num))
    return
}
func main() {
    ten := new(big.Int)
    ten.SetBytes(int2bytes(10))

    four := new(big.Int)
    four.SetBytes(int2bytes(4))

    fmt.Println(ten, four)
    
    tenmodfour := new(big.Int)
    tenmodfour = tenmodfour.Mod(ten, four)
    
    fmt.Println("mod", tenmodfour)
}
英文:

Just an addition to julienc's answer, if you were to use SetBytes, you have to convert the number to bytes like this :

func int2bytes(num int) (b []byte) {
	b = make([]byte, 4)
	binary.BigEndian.PutUint32(b, uint32(num))
	return
}
func main() {
	ten := new(big.Int)
	ten.SetBytes(int2bytes(10))

	four := new(big.Int)
	four.SetBytes(int2bytes(4))

	fmt.Println(ten, four)
	
	tenmodfour := new(big.Int)
	tenmodfour = tenmodfour.Mod(ten, four)
	
	fmt.Println("mod", tenmodfour)
}

huangapple
  • 本文由 发表于 2014年6月7日 23:53:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/24098959.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定