数太大了怎么办

  • 浮点类型可以存储非常大的数值,但是精度不高
  • 整型很精确,但是取值范围有限。
  • 如果你需要很大的数,而且要求很精确,那么怎么办
    • 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 类型。

  1. package main
  2. import (
  3. "fmt"
  4. "math/big"
  5. )
  6. func main() {
  7. num1 := big.NewInt(86400)
  8. fmt.Println(num1)
  9. num2 := new(big.Int)
  10. num2.SetString("86400",10)
  11. fmt.Println(num2)
  12. }

较大数值的常量

  • 在 Go 里面,可以为常量指明类型(这句话会报错):

比较大的数 - 图1

  • 也可以不指明常量的类型。。。
  • 对于变量,Go 会使用类型推断;
  • 而在 Go 里面,常量是可以无类型的(untyped),这句话就不会报错:

比较大的数 - 图2

  • 常量使用 const 关键字来声明,程序里的每个字面值都是常量。
  • 这意味着:比较大的数值可以直接使用(作为字面值)
  • 针对字面值和常量的计算是在编译阶段完成的。
  • Go 的编译器是用 Go 编写的,这种无类型的数值字面值就是由 big 包所支持的。这使你可以操作很大的数(超过18的1018
  • 只要能够容纳得下,那么常量就可以赋值给变量。
  • 尽管 Go 编译器使用 big 包来处理无类型的数值常量,但是常量和 big.Int 的值是不能互换的。

作业题

  • 大矮星是已知的距离地球最近的星系,距离我们的太阳236000000000000000公里(尽管有人质疑它是一个星系)。使用常量将此距离转换为光年。
  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. const distance = 236000000000000000
  7. const lightSpeed = 299792
  8. const secondsPerDay = 86400
  9. const daysPerYear = 365
  10. const years = distance / lightSpeed / secondsPerDay / daysPerYear
  11. fmt.Println("Canis Major Dwarf Galaxy is", years, "light years away.")
  12. }