数太大了怎么办
- 浮点类型可以存储非常大的数值,但是精度不高
- 整型很精确,但是取值范围有限。
- 如果你需要很大的数,而且要求很精确,那么怎么办
- int64 可以容纳很大的数,如果还不行,那么:
- uint64 可以容纳更大的正数,如果还不行,那么:
- 也可以凑合用浮点类型,但是还有另外一种方法:
- 使用 big 包。
- 如果没有为指数形式的数值指定类型的话,那么 Go 将会将它视作 float64 类型
big包
- 对于较大的整数(超过1018):big.Int
- 对于任意精度的浮点类型,big.Float
- 对于分数,big.Rat
big.Int
- 一旦使用了 big.Int,那么等式里其它的部分也必须使用 big.Int
- NewInt() 函数可以把 int64 转化为 big.Int 类型
- 如何把 24 x 1018 转化为 big.Int 类型?
- 首先 new 一个 big.Int
- 再通过 SetString 函数把数值的字符串形式,和几进制传递进行即可。
- 缺点:用起来繁琐,且速度慢
测试:
用两种方式把 86400 转化为 big.Int 类型。
package main
import (
"fmt"
"math/big"
)
func main() {
num1 := big.NewInt(86400)
fmt.Println(num1)
num2 := new(big.Int)
num2.SetString("86400",10)
fmt.Println(num2)
}
较大数值的常量
- 在 Go 里面,可以为常量指明类型(这句话会报错):
- 也可以不指明常量的类型。。。
- 对于变量,Go 会使用类型推断;
- 而在 Go 里面,常量是可以无类型的(untyped),这句话就不会报错:
- 常量使用 const 关键字来声明,程序里的每个字面值都是常量。
- 这意味着:比较大的数值可以直接使用(作为字面值)
- 针对字面值和常量的计算是在编译阶段完成的。
- Go 的编译器是用 Go 编写的,这种无类型的数值字面值就是由 big 包所支持的。这使你可以操作很大的数(超过18的1018)
- 只要能够容纳得下,那么常量就可以赋值给变量。
- 尽管 Go 编译器使用 big 包来处理无类型的数值常量,但是常量和 big.Int 的值是不能互换的。
作业题
- 大矮星是已知的距离地球最近的星系,距离我们的太阳236000000000000000公里(尽管有人质疑它是一个星系)。使用常量将此距离转换为光年。
package main
import (
"fmt"
)
func main() {
const distance = 236000000000000000
const lightSpeed = 299792
const secondsPerDay = 86400
const daysPerYear = 365
const years = distance / lightSpeed / secondsPerDay / daysPerYear
fmt.Println("Canis Major Dwarf Galaxy is", years, "light years away.")
}