go语言 算术运算时的类型转换问题,希望高手指点下

wwwmmm 发布于 2013/01/15 11:20
阅读 2K+
收藏 1
Go
package main

import (
	"fmt"
)

func main() {

	var hs int

	for hs = 0; hs <= 300; hs = hs + 20 {
		fmt.Printf("%v.....%5.2f\n", hs, (hs-32)*5.0/9.0)
	}
}

运行结果:

0.....%!f(int=  -17)
20.....%!f(int=  -06)
40.....%!f(int=   04)
60.....%!f(int=   15)
80.....%!f(int=   26)
100.....%!f(int=   37)
120.....%!f(int=   48)
140.....%!f(int=   60)
160.....%!f(int=   71)
180.....%!f(int=   82)
200.....%!f(int=   93)
220.....%!f(int=  104)
240.....%!f(int=  115)
260.....%!f(int=  126)
280.....%!f(int=  137)
300.....%!f(int=  148)
 这个是 打印 华氏温度 摄氏温度的转换 

如果要打印 摄氏温度 float类型的话 这样打印不出来, 

如果要打印必须要强制转换下,但是 c语言中 却不需要强制 转换 ,

希望高手 指点下 算术运算时的 类型转换问题,谢谢

加载中
1
chai2010
chai2010

引用来自“wwwmmm”的答案

引用来自“chai2010”的答案

浮点数字面值常量属于untyped类型.
如果 浮点数字面值常量 能被精确的表示为int, 那么可以当作数字类型使用(untyped).
如果 浮点数字面值常量 不能精确转换为 int , 应该会有编译错误.

表达式 (hs-32)*5.0/9.0, 因为 hs 是 int 类型, 且作为 untyped的 5.0/9.0 都可以精确转换为 int.
所以表达式还是有效的, 但是表达式的类型根据hs的类型推导为 int.

关于表达式的类型可以使用reflect包查看:
package main

import (
	"fmt"
	"reflect"
)

func main() {
	var x int

	t0 := reflect.ValueOf(0)
	t1 := reflect.ValueOf(0.0)
	t2 := reflect.ValueOf(0+0.0)
	t3 := reflect.ValueOf(x+0.0)

	fmt.Printf("t0 type: %v\n", t0.Type())
	fmt.Printf("t1 type: %v\n", t1.Type())
	fmt.Printf("t2 type: %v\n", t2.Type())
	fmt.Printf("t3 type: %v\n", t3.Type())
	// t0 type: int
	// t1 type: float64
	// t2 type: float64
	// t3 type: int
}

表达式的类型根据hs的类型推导为 int  具体表达式的类型是怎么来推导的呢

Go语言是强类型(不会像C与语言那样做类型的隐式转换), 因此会要求表达式中所以的成员类型是一致的.

如果不同的类型是不能在一个表达式运算的, 需要手工做强制类型转换.

但是, 因为数字面值常量比较特殊一点, 比如 100, 可以参与int/float32/float64等多种数值型运算.

这个100就是untyped类型.

对于表达式 (hs-32)*5.0/9.0, 后面都是untyped, 所以类型只能是根据hs确定, 就是int.

wwwmmm
wwwmmm
thx 了解了
1
chai2010
chai2010
浮点数字面值常量属于untyped类型.
如果 浮点数字面值常量 能被精确的表示为int, 那么可以当作数字类型使用(untyped).
如果 浮点数字面值常量 不能精确转换为 int , 应该会有编译错误.

表达式 (hs-32)*5.0/9.0, 因为 hs 是 int 类型, 且作为 untyped的 5.0/9.0 都可以精确转换为 int.
所以表达式还是有效的, 但是表达式的类型根据hs的类型推导为 int.

关于表达式的类型可以使用reflect包查看:
package main

import (
	"fmt"
	"reflect"
)

func main() {
	var x int

	t0 := reflect.ValueOf(0)
	t1 := reflect.ValueOf(0.0)
	t2 := reflect.ValueOf(0+0.0)
	t3 := reflect.ValueOf(x+0.0)

	fmt.Printf("t0 type: %v\n", t0.Type())
	fmt.Printf("t1 type: %v\n", t1.Type())
	fmt.Printf("t2 type: %v\n", t2.Type())
	fmt.Printf("t3 type: %v\n", t3.Type())
	// t0 type: int
	// t1 type: float64
	// t2 type: float64
	// t3 type: int
}

0
戴威
戴威
你把(hs-32)*5.0/9.0改成(hs-32)*5.0/8.9试试
0
wwwmmm
wwwmmm

引用来自“喵了个咪”的答案

你把(hs-32)*5.0/9.0改成(hs-32)*5.0/8.9试试
9.0 正常编译  8.9的话 会报如下
./main.go:12: constant 8.9 truncated to integer
0
戴威
戴威

引用来自“wwwmmm”的答案

引用来自“喵了个咪”的答案

你把(hs-32)*5.0/9.0改成(hs-32)*5.0/8.9试试
9.0 正常编译  8.9的话 会报如下
./main.go:12: constant 8.9 truncated to integer
所以你应该差不多明白golang的逻辑了吧
0
wwwmmm
wwwmmm

引用来自“喵了个咪”的答案

引用来自“wwwmmm”的答案

引用来自“喵了个咪”的答案

你把(hs-32)*5.0/9.0改成(hs-32)*5.0/8.9试试
9.0 正常编译  8.9的话 会报如下
./main.go:12: constant 8.9 truncated to integer
所以你应该差不多明白golang的逻辑了吧
会先转换成 整形再运算  ?
0
SunRunAway
SunRunAway

go语言不会自动转换,必须显示类型转换。

所以(hs-32)*5.0/9.0 编译器把它认为成int了

0
Liuxd
Liuxd
float64((hs-32)*5.0/9.0))
0
wwwmmm
wwwmmm

引用来自“Archer OO”的答案

go语言不会自动转换,必须显示类型转换。

所以(hs-32)*5.0/9.0 编译器把它认为成int了

那为什么把9.0换成8.9的话 编译过不去呢
SunRunAway
SunRunAway
首先编译器把它认为成int 而go语言常量会转换 所以9.0会变成9 但8.9变不了int所以就报错啦
0
wwwmmm
wwwmmm

引用来自“Liuxd”的答案

float64((hs-32)*5.0/9.0))
这个 知道  我想知道 运算时  是怎么变换的
返回顶部
顶部