练习2.1
向tempconv包添加类型、常量和函数用来处理Kelvin绝对温度的转换,Kelvin 绝对零度是−273.15°C,Kelvin绝对温度1K和摄氏度1°C的单位间隔是一样的。
conv.go
package tempconv
// CToF converts a Celsius temperature to Fahrenheit.
func CToF(c Celsius) Fahrenheit { return Fahrenheit(c*9/5 + 32) }
// FToC converts a Fahrenheit temperature to Celsius.
func FToC(f Fahrenheit) Celsius { return Celsius((f - 32) * 5 / 9) }
func KToC(k Kelvin) Celsius { return Celsius(k + 273.15) }
func CToT(c Celsius) Kelvin { return Kelvin(c + 273.15) }
tempconv.go
package tempconv
import "fmt"
type Celsius float64
type Fahrenheit float64
type Kelvin float64
const (
AbsoluteZeroC Celsius = -273.15
FreezingC Celsius = 0
BoilingC Celsius = 100
)
func (c Celsius) String() string { return fmt.Sprintf("%g°C", c) }
func (f Fahrenheit) String() string { return fmt.Sprintf("%g°F", f) }
func (k Kelvin) String() string { return fmt.Sprintf("%g°K", k) }
练习2.2
写一个通用的单位转换程序,用类似cf程序的方式从命令行读取参数,如果缺省的话则是从标准输入读取参数,然后做类似Celsius和Fahrenheit的单位转换,长度单位可以对应英尺和米,重量单位可以对应磅和公斤等。
conv.go:
package lenthconv
func MToF(m Meter) Feet { return Feet(m / 0.3084) }
func FToM(f Feet) Meter { return Meter(f * 0.3084) }
lenthconv:
package lenthconv
import "fmt"
type Meter float64
type Feet float64
func (m Meter) String() string { return fmt.Sprintf("%g m", m) }
func (f Feet) String() string { return fmt.Sprintf("%g ft", f) }
test:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"gopl.io/ch2/lenthconv"
)
func main() {
if len(os.Args) == 1 {
input := bufio.NewScanner(os.Stdin)
for input.Scan() {
t, err := strconv.ParseFloat(input.Text(), 64)
if err != nil {
fmt.Fprintf(os.Stderr, "cf: %v\n", err)
os.Exit(1)
}
f := lenthconv.Feet(t)
m := lenthconv.Meter(t)
fmt.Printf("%s = %s, %s = %s\n",
f, lenthconv.FToM(f), m, lenthconv.MToF(m))
}
}
for _, arg := range os.Args[1:] {
t, err := strconv.ParseFloat(arg, 64)
if err != nil {
fmt.Fprintf(os.Stderr, "cf: %v\n", err)
os.Exit(1)
}
f := lenthconv.Feet(t)
m := lenthconv.Meter(t)
fmt.Printf("%s = %s, %s = %s\n",
f, lenthconv.FToM(f), m, lenthconv.MToF(m))
}
}
练习2.3
重写PopCount函数,用一个循环代替单一的表达式。比较两个版本的性能。
func PopCount(x uint64) int {
res := 0
for i := 0; i < 8; i++ {
res += int(pc[byte(x>>(i*8))])
}
return res
}
练习2.4
用移位算法重写PopCount函数,每次测试最右边的1bit,然后统计总数。比较和查表算法的性能差异。文章来源:https://www.toymoban.com/news/detail-674384.html
func PopCount(x uint64) int {
res := 0
for x != 0 {
res += x & 1
x >>= 1
}
return res
}
练习2.5
表达式x&(x-1)用于将x的最低的一个非零的bit位清零。使用这个算法重写PopCount函数,然后比较性能。文章来源地址https://www.toymoban.com/news/detail-674384.html
func PopCount(x uint64) int {
res := 0
for x != 0 {
res++
x &= x - 1
}
return res
}
到了这里,关于GO语言圣经 第二章习题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!