# Conflicts:
#	eBook/09.5.md
This commit is contained in:
Unknwon
2015-08-07 16:42:00 +08:00
6 changed files with 165 additions and 16 deletions

View File

@@ -1 +1,54 @@
# 精密计算和 big 包
# 9.4 精密计算和 big 包
我们知道有些时候通过编程的方式去进行计算是不精确的。如果你使用 Go 语言中的 float64 类型进行浮点运算,返回结果将精确到 15 位,足以满足大多数的任务。当对超出 int64 或者 uint64 类型这样的大数进行计算时如果对精度没有要求float32 或者 float64 可以胜任,但如果对精度有严格要求的时候,我们不能使用浮点数,在内存中它们只能被近似的表示。
对于整数的高精度计算 Go 语言中提供了 big 包。其中包含了 math 包:有用来表示大整数的 `big.Int` 和表示大有理数的 `big.Rat` 类型(可以表示为 2/5 或 3.1416 这样的分数,而不是无理数或 π)。这些类型可以实现任意位类型的数字,只要内存足够大。缺点是更大的内存和处理开销使它们使用起来要比内置的数字类型慢很多。
大的整型数字是通过 `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)
``` go
// big.go
package main
import (
"fmt"
"math"
"math/big"
)
func main() {
// Here are some calculations with bigInts:
im := big.NewInt(math.MaxInt64)
in := im
io := big.NewInt(1956)
ip := big.NewInt(1)
ip.Mul(im, in).Add(ip, im).Div(ip, io)
fmt.Printf("Big Int: %v\n", ip)
// Here are some calculations with bigInts:
rm := big.NewRat(math.MaxInt64, 1956)
rn := big.NewRat(-1956, math.MaxInt64)
ro := big.NewRat(19, 56)
rp := big.NewRat(1111, 2222)
rq := big.NewRat(1, 1)
rq.Mul(rm, rn).Add(rq, ro).Mul(rq, rp)
fmt.Printf("Big Rat: %v\n", rq)
}
/* Output:
Big Int: 43492122561469640008497075573153004
Big Rat: -37/112
*/
```
输出结果:
Big Int: 43492122561469640008497075573153004
Big Rat: -37/112
## 链接
- [目录](directory.md)
- 上一节:[锁和 sync 包](09.3.md)
- 下一节:[自定义包和可见性](09.5.md)

View File

@@ -23,7 +23,7 @@ func ReturnStr() string {
在主程序 pack_test.go 中这个包通过声明的方式被导入
```go
import ./pack1/pack1
import "./pack1/pack1"
```
import 的一般格式如下:
@@ -36,7 +36,7 @@ import 的一般格式如下:
路径是指当前目录的相对路径。
示例 9.5 [package_test.go](examples/chapter_9/package_test.go)
示例 9.5 [package_test.go](examples/chapter_9/book/package_test.go)
```go
package main
@@ -50,8 +50,8 @@ func main() {
var test1 string
test1 = pack1.ReturnStr()
fmt.Printf("ReturnStr from package1: %s\n", test1)
fmt.Printf(Integer from package1: %d\n, pack1.Pack1Int)
// fmt.Printf(Float from package1: %f\n, pack1.pack1Float)
fmt.Printf("Integer from package1: %d\n", pack1.Pack1Int)
// fmt.Printf("Float from package1: %f\n", pack1.pack1Float)
}
```
@@ -76,13 +76,13 @@ fmt.Printf(“Float from package1: %f\n”, pack1.pack1Float)
因此,按照惯例子目录和包之间有着密切的联系:为了区分不同包存放在不同的目录,每个包(所有属于这个包中的 go 文件)都存放在和包名相同的子目录下:
**Import with .** : import . ./pack1
**Import with .** : import . "./pack1"
当使用.来做为包的别名时,你可以不通过包名来使用其中的项目。例如:`test := ReturnStr()`
在当前的命名空间导入 pack1 包,一般是为了具有更好的测试效果。
**Import with _** : import _ ./pack1/pack1
**Import with _** : import _ "./pack1/pack1"
pack1包只导入其副作用也就是说只执行它的init函数并初始化其中的全局变量。
@@ -100,7 +100,7 @@ pack1包只导入其副作用也就是说只执行它的init函数并初
通过以下方式,一次性安装,并导入到你的代码中:
import goex codesite.ext/author/goExample/goex
import goex "codesite.ext/author/goExample/goex"
因此该包的 URL 将用作导入路径。

View File

@@ -26,12 +26,67 @@ sort 包
```go
func Float64sAreSorted
type IntArray
func IntsAreSortedfunc IsSortedfunc Sort
type IntArray
func IntsAreSortedfunc IsSortedfunc Sort
func (IntArray) Len
func SortFloat64s
func (IntArray) Less
func SortInts
func (IntArray) Swap
func SortStrings type Interface
func StringsAreSorted type StringArray type Float64Array
func (StringArray) Len
func (Float64Array) Len
func (StringArray) Less
func (Float64Array) Less
func (StringArray) Swap
func SortFloat64s
func (Float64Array) Swap
Other packages
import "doc_example"
```
func (IntArray) Less
使用通用的接口排序:
```
func Float64sAreSorted[Top]
func Float64sAreSorted(a []float64) bool
func IntsAreSorted[Top]
func IntsAreSorted(a []int) bool
func IsSorted[Top]
func IsSorted(data Interface) bool
Test if data is sorted
func Sort[Top]
func Sort(data Interface)
General sort function
func SortInts[Top]
func SortInts(a []int)
Convenience wrappers for common cases: type IntArray[Top]
Convenience types for common cases: IntArray type IntArray []int
```
如果你在一个团队中工作,并在源代码树被存储在网络硬盘上,就可以使用 godoc 给所有团队成员连续文档的支持。通过设置 sync_minutes=n你甚至可以让它每 n 分钟自动更新您的文档!
## 链接
- [目录](directory.md)
- 上一节:[自定义包和可见性](09.5.md)
- 下一节:[使用 go install 安装自定义包](09.7.md)

View File

@@ -0,0 +1,23 @@
package uc
import "testing"
type ucTest struct {
in, out string
}
var ucTests = []ucTest{
ucTest{"abc", "ABC"},
ucTest{"cvo-az", "CVO-AZ"},
ucTest{"Antwerp", "ANTWERP"},
}
func TestUC(t *testing.T) {
for _, ut := range ucTests {
uc := UpperCase(ut.in)
if uc != ut.out {
t.Errorf("UpperCase(%s) = %s, must be %s", ut.in, uc,
ut.out)
}
}
}

View File

@@ -0,0 +1,7 @@
package uc
import "strings"
func UpperCase(str string) string {
return strings.ToUpper(str)
}

View File

@@ -0,0 +1,11 @@
package main
import (
"./uc/uc"
"fmt"
)
func main() {
str1 := "USING package uc"
fmt.Println(uc.UpperCase(str1))
}