英文:
How to take command argument in Go?
问题
我刚开始学习Go语言,我使用ProbablyPrime
库编写了一个素数测试程序。
package main
import (
"fmt"
"math/big"
"math"
"os"
"strconv"
)
func prime_test(n int64, certainty int)(bool,float64){
var probobility float64
i := big.NewInt(n)
isPrime := i.ProbablyPrime(certainty)
probobility = 1 - 1/math.Pow(4,10)
return isPrime, probobility
}
func why_not_prime(n int64)(int64){
var i int64
for i=2 ; i<n/2; i++ {
if n%i == 0 {return i}
}
return i
}
func main() {
var n int64
var certainty int
var isPrime bool
var probobility float64
if len(os.Args) > 1 {
n,_ = strconv.ParseInt(os.Args[1],64,64)
certainty,_ = strconv.Atoi(os.Args[2])
}
isPrime, probobility = prime_test(n,certainty)
if isPrime {
fmt.Printf("%d 可能是素数,概率为 %0.8f%%。", n, probobility*100)
} else {
var i int64
i = why_not_prime(n)
fmt.Printf("%d 是合数,因为它可以被 %d 整除。", n, i)
}
}
代码可以成功编译。当我运行它时,它总是返回0 是合数,因为它可以被 2 整除
。
我猜测命令行参数解析有问题。如何修复它?
英文:
I just start to learn Go, and I wrote a prime test program using the ProbablyPrime
library.
package main
import (
"fmt"
"math/big"
"math"
"os"
"strconv"
)
func prime_test(n int64, certainty int)(bool,float64){
var probobility float64
i := big.NewInt(n)
isPrime := i.ProbablyPrime(certainty)
probobility = 1 - 1/math.Pow(4,10)
return isPrime, probobility
}
func why_not_prime(n int64)(int64){
var i int64
for i=2 ; i<n/2; i++ {
if n%i == 0 {return i}
}
return i
}
func main() {
var n int64
var certainty int
var isPrime bool
var probobility float64
if len(os.Args) > 1 {
n,_ = strconv.ParseInt(os.Args[1],64,64)
certainty,_ = strconv.Atoi(os.Args[2])
}
isPrime, probobility = prime_test(n,certainty)
if isPrime {
fmt.Printf("%d is probably %0.8f%% a prime.", n, probobility*100)
} else {
var i int64
i = why_not_prime(n)
fmt.Printf("%d is a composite because it can be divided by %d", n, i)
}
}
The code could be successfully compiled. When I run it, it always return 0 is a composite because it can be divided by 2
.
I guess there's something wrong with the command line argument parsing. How to fix it?
答案1
得分: 6
问题出在这一行代码上:
n,_ = strconv.ParseInt(os.Args[1],64,64)
ParseInt(s string, base int, bitSize int) (i int64, err error)
的文档说明如下:
> ParseInt将给定基数(2到36)中的字符串s解释为相应的值i并返回。
基数最大可以是**36
**,而你传递的是64
。在这种情况下,会返回一个错误(你通过使用空白标识符_
来丢弃该错误),并且n
将具有零值,即0
,因此你会看到输出为
> 0是一个合数,因为它可以被2整除
解决方案:
将问题行改为:
n, _ = strconv.ParseInt(os.Args[1], 10, 64)
这样应该就可以正常工作了。此外,你不应该丢弃错误,因为你可能会遇到类似的情况。而是应该像这样正确处理错误:
var err error
n, err = strconv.ParseInt(os.Args[1], 10, 64)
if err != nil {
log.Fatal(err)
}
注意:
还要注意第一个参数(os.Args[0]
是可执行文件的名称),并且由于你期望并使用了2个额外的参数,你应该检查os.Args
的长度是否大于2,而不是1:
if len(os.Args) > 2 {
// os.Args[1] 和 os.Args[2] 是有效的
}
英文:
The problem is with this line:
n,_ = strconv.ParseInt(os.Args[1],64,64)
The documentation of ParseInt(s string, base int, bitSize int) (i int64, err error)
states:
> ParseInt interprets a string s in the given base (2 to 36) and returns the corresponding value i.
The base can be 36
at the most and you pass 64
. In this case an error will be returned (which you discard by using the blank identifier _
), and n
will have the zero value which is 0
hence you see the output as
> 0 is a composite because it can be divided by 2
Solution:
Change the line in question to this:
n, _ = strconv.ParseInt(os.Args[1], 10, 64)
and it should work. Also you should not discard errors because you will run into cases like this. Instead handle them properly like this:
var err error
n, err = strconv.ParseInt(os.Args[1], 10, 64)
if err != nil {
log.Fatal(err)
}
Note:
Also note that the first argument (os.Args[0]
is the name of the executable), and since you expect and work with 2 extra arguments, you should check if the length of os.Args
is greater than 2 not 1:
if len(os.Args) > 2 {
// os.Args[1] and os.Args[2] is valid
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论