golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.81k stars 17.65k forks source link

proposal: spec: allow untyped float const multiplied by typed integer constants (2.5*time.Hour) #32666

Open cfhay opened 5 years ago

cfhay commented 5 years ago

What version of Go are you using (go version)?

play.golang.org reports 1.12.5

What did you do?

https://play.golang.org/p/klT3SFB7BJE

What did you expect to see?

2h30m0s

What did you see instead?

./prog.go:9:23: constant 2.5 truncated to integer

In the code I'm multiplying a constant with a constant and according to https://blog.golang.org/constants this should just work. But somehow it doesn't.

ericlagergren commented 5 years ago

Per the spec, it’s illegal for a constant expression to truncate a floating point number: https://golang.org/ref/spec#Constant_expressions

The values of typed constants must always be accurately representable by values of the constant type. The following constant expressions are illegal:

[...]
int(3.14)    // 3.14 cannot be represented as an int

What part of the blog post led you to think it would work? That might clear up some confusion.

cfhay commented 5 years ago

Hi Eric,

how are you? Generally speaking "var x int64 = 2.5 2" works (while 2.5 3 does not, which is OK). Why "2.5 * time.Hour" shouldn't? (I think it's fine if something like this would land in Go2)

Sincerely, Zoltán

Eric Lagergren notifications@github.com ezt írta (időpont: 2019. jún. 18., K 15:59):

Per the spec, it’s illegal for a constant expression to truncate a floating point number: https://golang.org/ref/spec#Constant_expressions

What part of the blog post led you to think it would work? That might clear up some confusion.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/golang/go/issues/32666?email_source=notifications&email_token=ACXXRTJ2YNP5KCMVU4VC44DP3DZ5HA5CNFSM4HZAAZR2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODX65EAQ#issuecomment-503173634, or mute the thread https://github.com/notifications/unsubscribe-auth/ACXXRTJVD2WSA6LJMPMPAD3P3DZ5HANCNFSM4HZAAZRQ .

beoran commented 5 years ago

FWIW: It does work if you do it like this:

package main

import (
    "fmt"
    "time"
)

const Duration = int64(float64(time.Hour) * 2.5)

func main() {
    fmt.Printf("%v", Duration)
}

https://play.golang.org/p/E9tMZox7lv0

deanveloper commented 5 years ago

I can get behind this proposal.

time.Second is a typed constant with the (evaluated) value time.Duration(1000000000)

In constant arithmetic, 2.5 * 1000000000 correctly evaluated to 2500000000, an untyped integer that does not need to be truncated.

I believe this proposal is saying that untyped float constants multiplied by typed integer constants should be evaluated as typed integer constants, provided that no truncation occurs (such as the case of 2.5 * time.Second or 2.5 * time.Hour)

EDIT - It looks as if the proposal is stating that the current behavior (not compiling) is a bug. It is definitely not. However it could be useful to add this in as a feature for constants.