第一题
题意:向tempconv包添加类型、常量和函数用来处理Kelvin绝对温度的转换,Kelvin 绝对零度是−273.15°C,Kelvin绝对温度1K和摄氏度1°C的单位间隔是一样的。
package main
import (
"fmt"
"gopl/real_paragraph2/packageAndFile/tempconv"
)
func main() {
var k tempconv.Kelvin = 1
c := tempconv.KToC(k)
fmt.Println(c)
var c0 tempconv.Celsius = 0
k0 := tempconv.CToK(c0)
fmt.Println(k0)
}
运行结果:
第二题
题意: 写一个通用的单位转换程序,用类似cf程序的方式从命令行读取参数,如果缺省的话则是从标准输入读取参数,然后做类似Celsius和Fahrenheit的单位转换,长度单位可以对应英尺和米,重量单位可以对应磅和公斤等。
package main
import (
"fmt"
"os"
"strconv"
)
//1英尺(ft)=0.3048米(m)
type Inch float64
type Meter float64
const tr float64 = 0.3048
func IToM (i Inch) Meter {
return Meter(i * Inch(tr))
}
func MToI (m Meter) Inch {
return Inch(m / Meter(tr))
}
func (i Inch) String() string {
return fmt.Sprintf("%g inch",i)//注意转换格式需要是float类型的格式,这里用%g,不要用%v
}
func (m Meter) String() string {
return fmt.Sprintf("%g meters",m)
}
func main() {
for _,arg := range os.Args[1:]{
t,err := strconv.ParseFloat(arg,64)
if err != nil {
fmt.Fprintf(os.Stderr,"transfer:%v\n",err)
os.Exit(1)
}
i := Inch(t)
m := Meter(t)
fmt.Printf("%s = %s,%s = %s\n",i,IToM(i),m,MToI(m))
}
}
运行结果示例:
第三题
题意:重写PopCount函数,用一个循环代替单一的表达式。
package popCount2_3
var pc [256]byte//byte只占一个字节
//pc被初始化为0-255无符号整数每一个数字所拥有的二进制1个数
func init() {
for i := range pc {//只用了pc的索引值
pc[i] = pc[i/2] + byte(i&1)
}
}
//byte(x>>(n*8))截取低8位
func PopCount(x uint64) int {
var temp int = 0
for i := 0;i < 8;i++ {
temp += int(pc[byte(x >> (i*8))])
}
return temp
}
第四题
题意:用移位算法重写PopCount函数,每次测试最右边的1bit,然后统计总数。
package popCount2_4
func PopCount(x uint64) int {
var cnt int = 0
for i := 0;i<64;i++ {
cnt += ((x >> i) & 1)
}
return cnt
}
第五题
题意:表达式x&(x-1)用于将x的最低的一个非零的bit位清零。使用这个算法重写PopCount函数
package popCount2_5
func PopCount(x uint64) int {
var cnt int = 0
for x != 0 {
x = x & (x - 1)
cnt++
}
return cnt
}