2.1 添加Kelvin绝对温度的转换
// 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) }
// 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) }
// CToK converts a Celsius temperature to Kelvin.
func CToK(c Celsius) Kelvin { return Kelvin(c + AbsoluteZeroC) }
// KToC converts a Kelvin temperature to Celsius.
func KToC(k Kelvin) Celsius { return Celsius(k) - AbsoluteZeroC }
// FToK converts a Celsius temperature to Kelvin.
func FToK(f Fahrenheit) Kelvin { return Kelvin(FToC(f) + AbsoluteZeroC) }
// KToF converts a Kelvin temperature to Fahrenheit.
func KToF(k Kelvin) Fahrenheit { return CToF(Celsius(k) - AbsoluteZeroC) }
// main.go
package main
import (
"ch2/tempconv"
"fmt"
"os"
"strconv"
)
// 添加Kelvin绝对温度的转换
func test_2_1() {
for _, arg := range os.Args[1:] {
temp, err := strconv.ParseFloat(arg, 64)
if err != nil {
fmt.Println("arguments have problems, try again.")
}
c := tempconv.Celsius(temp)
f := tempconv.Fahrenheit(temp)
k := tempconv.Kelvin(temp)
fmt.Printf("%s=%s=%s\n", c, tempconv.CToF(c), tempconv.CToK(c))
fmt.Printf("%s=%s=%s\n", tempconv.FToC(f), f, tempconv.FToK(f))
fmt.Printf("%s=%s=%s\n\n", tempconv.KToC(k), tempconv.KToF(k), k)
}
}
func main() {
test_2_1()
}
2.2 长度转换
// lenconv.go
package lenconv
import "fmt"
type Meter float64
type Foot float64
// Meter,Foot的输出方式
func (m Meter) String() string { return fmt.Sprintf("%fm", m) }
func (f Foot) String() string { return fmt.Sprintf("%fft", f) }
// Meter,Foot的转换方式
func MToF(m Meter) Foot { return Foot(m * 3.28084) }
func FToM(f Foot) Meter { return Meter(f * 0.3048) }
// main.go
func test_2_2() {
if len(os.Args) == 1 {
var l float64
fmt.Println("please input a number float64")
_, err := fmt.Scan(&l)
if err != nil {
fmt.Printf("arguments errors,error:%v\n", err)
return
}
m := lenconv.Meter(l)
f := lenconv.Foot(l)
fmt.Printf("%s=%s\n", m, lenconv.MToF(m))
fmt.Printf("%s=%s\n\n", f, lenconv.FToM(f))
return
}
for _, arg := range os.Args[1:] {
l, err := strconv.ParseFloat(arg, 64)
if err != nil {
fmt.Printf("arguments errors,error:%v\n", err)
}
m := lenconv.Meter(l)
f := lenconv.Foot(l)
fmt.Printf("%s=%s\n", m, lenconv.MToF(m))
fmt.Printf("%s=%s\n\n", f, lenconv.FToM(f))
}
}
2.3 2.4 重写PopCount函数,用一个循环代替单一的表达式
// 重写PopCount函数,用一个循环代替单一的表达式
var pc [256]byte
func init() {
for i := range pc {
pc[i] = pc[i/2] + byte(i&1)
}
}
func PopCount(x uint64) int {
ans := 0
for i := 0; i < 8; i++ {
ans += int(pc[byte(x)])
x >>= 8
}
return ans
}
func test_2_3() {
var num uint64
fmt.Printf("please enter a number:")
_, err := fmt.Scan(&num)
if err != nil {
fmt.Println("input error,err:", err)
return
}
start := time.Now()
fmt.Printf("%d has %d set bits\n", num, PopCount(num))
fmt.Printf("%fs has passed\n", time.Since(start).Seconds())
}
2.5 用移位算法重写PopCount函数
// 用移位算法重写PopCount函数
func PopCount(num uint64) int {
ans := 0
for num != 0 {
num = num & (num - 1)
ans++
}
return ans
}
func test_2_5() {
fmt.Printf("Please enter a number:")
var num uint64
_, err := fmt.Scan(&num)
if err != nil {
fmt.Println("input error:", err)
return
}
start := time.Now()
fmt.Printf("%d has %d set bits\n", num, PopCount(num))
fmt.Printf("%d Nanoseconds has passed\n", time.Since(start).Nanoseconds())
}