Golang的类型系统行为 – 将int除以隐式浮点数。

huangapple go评论83阅读模式
英文:

Golang's type system behaviour - dividing an int by an implicit float

问题

最近我在尝试使用Go语言的类型系统时遇到了一个有趣(或者不是很有趣)的与浮点数相关的行为:

package main

import (
	"fmt"
)

func main() {
	doesntWork()
	works()
}

func doesntWork() {
	x := 1234
	y := x / 100000.0
	s := fmt.Sprintf("%.8f", y)
	fmt.Printf("%s\n", s)
}

func works() {
	x := 1234
	y := float64(x) / 100000.0
	s := fmt.Sprintf("%.8f", y)
	fmt.Printf("%s\n", s)
}

Go Playground

我认为在上面的示例中,在doesntWork()函数中,当将int除以隐式的float时,Go语言不会自动假设为float32/64。这样理解正确吗?有人可以指导我查阅一些文档或规范,以了解Go语言在类似上述情况下的行为吗?

英文:

I was experimenting lately with golang's type system and encountered an interesting (or not) behaviour related to floats:

package main

import (
	"fmt"
)

func main() {
	doesntWork()
	works()
}

func doesntWork() {
	x := 1234
	y := x / 100000.0
	s := fmt.Sprintf("%.8f", y)
	fmt.Printf("%s\n", s)
}

func works() {
	x := 1234
	y := float64(x) / 100000.0
	s := fmt.Sprintf("%.8f", y)
	fmt.Printf("%s\n", s)
}

Go Playground

I think that in the case presented in the example above, in procedure doesntWork(), golang does not automatically "assume" float32/64 when dividing an int by an implicit float? Is that correct? Could anyone point me towards some docs or specs where I could learn more about how golang behaves in situations like the one above?

答案1

得分: 6

这里的10000.0不是float64/32类型,而是一个数值常量。在这种情况下,Go语言会根据表达式中的x的类型来推断,并将常量100000.0截断为整数。

如果你将代码更新为:

func doesntWork() {
    x := 1234
    y := x / float64(100000.0)
    s := fmt.Sprintf("%.8f", y)
    fmt.Printf("%s\n", s)
}

它会报错,提示:

invalid operation: x / float64(100000) (mismatched types int and float64)

同样地,如果你将常量改为100000.111,其中truncate到整数将不再给出相同的值,它也会报错:

func doesntWork() {
    x := 1234
    y := x / 100000.1
    s := fmt.Sprintf("%.8f", y)
    fmt.Printf("%s\n", s)
}

它会报错,提示:

constant 100000 truncated to integer
英文:

Here 10000.0 is not float64/32 it is a numeric constant. Go will assume the type of x in this case for the expression and truncate the constant 100000.0 to integer

func doesntWork() {
	x := 1234
	y := x / 100000.0
	s := fmt.Sprintf("%.8f", y)
	fmt.Printf("%s\n", s)
}

If you update it to

func doesntWork() {
	x := 1234
	y := x / float64(100000.0)
	s := fmt.Sprintf("%.8f", y)
	fmt.Printf("%s\n", s)
}

it will error out saying

 invalid operation: x / float64(100000) (mismatched types int and float64)

Similarly if you change the constant to 100000.111 where truncating to integer will no longer give the same value it will error out

func doesntWork() {
	x := 1234
	y := x / 100000.1
	s := fmt.Sprintf("%.8f", y)
	fmt.Printf("%s\n", s)
}

It will error out saying

constant 100000 truncated to integer

huangapple
  • 本文由 发表于 2017年1月2日 15:19:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/41422777.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定