This commit is contained in:
Unknwon
2015-03-02 02:46:41 -05:00
parent 0d75fa5848
commit 677a08c61d
4 changed files with 32 additions and 26 deletions

View File

@@ -9,7 +9,7 @@
## 翻译进度
9.3 [锁和 sync](eBook/09.3.md)
9.4 [精密计算和 big](eBook/09.4.md)
## 支持本书

View File

@@ -1,15 +1,22 @@
# 精密计算和 big 包
202
我们知道有些时候通过编程的方式去进行计算是不精确的。如果你使用Go语言中的fload64类型进行浮点运算返回结果将精确到15位足以满足大多数的任务。当对超出in64或者uint64类型这样的大数进行计算时如果对精度没有要求float32或者float64可以胜任但如果对精度有严格要求的时候我们不能使用浮点数在内存中它们只能被近似的表示。
我们知道有些时候通过编程的方式去进行计算是不精确的。如果你使用 Go 语言中的 fload64 类型进行浮点运算,返回结果将精确到 15 位,足以满足大多数的任务。当对超出 int64 或者 uint64 类型这样的大数进行计算时如果对精度没有要求float32 或者 float64 可以胜任,但如果对精度有严格要求的时候,我们不能使用浮点数,在内存中它们只能被近似的表示。
对于整数的高精度计算Go语言中提供了big包。其中包含了math包有用来表示大整数的big.Int和表示大有理数的big.Rat类型(可以表示为2/53.1416这样的分数,而不是无理数或π)。这些类型可以实现任意位类型的数字,只要内存足够大。缺点是更大的内存和处理开销使它们使用起来要比内置的数字类型慢很多。
对于整数的高精度计算 Go 语言中提供了 big 包。其中包含了 math 包:有用来表示大整数的 `big.Int` 和表示大有理数的 `big.Rat` 类型可以表示为 2/53.1416 这样的分数,而不是无理数或 π)。这些类型可以实现任意位类型的数字,只要内存足够大。缺点是更大的内存和处理开销使它们使用起来要比内置的数字类型慢很多。
大的整型数字是通过big.NewInt(n)来构造的,其中n位int64类型整数。而大有理数是用过big.NewRat(N,D)方法构造.N(分子)和D(分母)都是int64型整数。因为Go语言不支持运算符重载所以所有大数字类型都有像是Add()Mul()这样的方法。它们作用于作为receiver的整数和有理数,大多数情况下它们修改receiver并以receiver作为返回结果。因为没有必要创建big.Int类型的临时变量来存放中间结果所以这样的运算可通过内存链式存储。
大的整型数字是通过 `big.NewInt(n)` 来构造的,其中 n 位 int64 类型整数。而大有理数是用过 `big.NewRat(N,D)` 方法构造。N分子和 D分母都是 int64 型整数。因为 Go 语言不支持运算符重载,所以所有大数字类型都有像是 Add()Mul() 这样的方法。它们作用于作为 receiver 的整数和有理数大多数情况下它们修改 receiver 并以 receiver 作为返回结果。因为没有必要创建 big.Int 类型的临时变量来存放中间结果,所以这样的运算可通过内存链式存储。
示例 9.2 [big.go](examples/chapter_9/big.go)
示例 9.2 [big.go](examples/chapter_9/big.go)
package main
```go
package main
import (
"fmt"
"math""
"math/big"
)
func main() {
// Here are some calculations with bigInts:
im := big.NewInt(math.MaxInt64)

View File

@@ -1,6 +1,6 @@
#B 自定义和外部包的使用,编译,测试,文档和安装
#9.5 自定义包和可见性
# 9.5 自定义包和可见性
203
包是Go语言中代码组成和代码编译的主要方式。很多关于它们的基本信息已经在4.2章节中给出,最引人注目的便是可见性。现在我们来看看具体如何来使用自己写的包。在下一节,我们将回顾一些标准库中的包,自定义的包和标准库以外的包。
当写自己包的时候要使用短小的不含有_(下划线)的小写单词来为文件命名。这里有个简单例子来说明包是如何相互调用以及可见性是如何实现的。
@@ -12,47 +12,47 @@
package pack1
var Pack1Int int = 42
var PackFloat = 3.14
func ReturnStr() string {
return "Hello main!"
}
它包含了一个整型变量PackInt和一个返回字符串的函数ReturnStr。这段程序在运行时不做任何的事情因为它不包含有一个main函数。
在主程序pack_test.go中这个包通过声明的方式被导入
import “./pack1/pack1”
import “./pack1/pack1”
import的一般格式如下:
import “包的路径或url地址“ 像 import "github.com/org1/pack1”
路径是指当前目录的相对路径。
示例 9.5 [package_test.go](examples/chapter_9/package_test.go)
package main
import (
import (
"fmt"
"./pack1/pack1"
)
func main() {
var test1 string
var test1 string
test1 = pack1.ReturnStr()
fmt.Printf("ReturnStr from package1: %s\n", test1)
fmt.Printf("ReturnStr from package1: %s\n", test1)
fmt.Printf(“Integer from package1: %d\n”, pack1.Pack1Int)
fmt.Printf(“Integer from package1: %d\n, pack1.Pack1Int)
// fmt.Printf(“Float from package1: %f\n”, pack1.pack1Float)
输出结果:
输出结果:
ReturnStr from package1: Hello main!
Integer from package1: 42
如果包pack1和我们的程序在统同一路径下我们可以通过"import ./pack1"这样的方式来引入,但这不被视为一个好的方法。
fmt.Printf(“Float from package1: %f\n”, pack1.pack1Float)这行代码试图访问一个未引用的变量或者函数,甚至没有编译。将会返回一个错误:
cannot refer to unexported name pack1.pack1Float
@@ -75,7 +75,7 @@ pack1包只导入其副作用只执行了它的init函数并初始化了其
如果你要在你的应用中使用一个或多个外部包首先你必须使用go install(参见9.7章节)在你的本地机器上安装它们。
假设你想使用http://codesite.ext/author/goExample/goex这种托管在googlecode, github,launchpad等代码网站上的包。
导入外部安装包:
你可以通过如下命令安装
go install codesite.ext/author/goExample/goex
@@ -103,7 +103,7 @@ init函数是不能被调用的。
在Linux/OSX下可以用类似4.3章节的Makefile脚本做到这一点
编译并安装一个包(参见9.7章节):
include $(GOROOT)/src/Make.inc
TARG=pack1
GOFILES=\
pack1.go\
@@ -132,8 +132,6 @@ go install(参见9.7章节从Go1的首选方式)同样复制pack1.a到本地
练习:
当第13章我们遇到使用测试工具进行测试的时候我们将重新回到自己的包的制作和编译这个话题。
问题9.1:
(a)一个包能分成多个源文件么?
问题9.1:

View File

@@ -77,6 +77,7 @@
- 9.2 [regexp 包](09.2.md)
- 9.3 [锁和 sync 包](09.3.md)
- 9.4 [精密计算和 big 包](09.4.md)
- 9.5 [自定义包和可见性](09.5.md)
- 第10章结构struct与方法method
- 第11章接口interface与反射reflection