constant truncated to integer

1,659 views
Skip to first unread message

Chris Jones

unread,
Jul 2, 2011, 9:10:11 PM7/2/11
to golan...@googlegroups.com
This seems to be an error. If I have this code:

const maxFrameRate = 60
minInterval := int64((1.0 / maxFrameRate) * 1e9)

... then Go reports this error: constant 1.66667e+07 truncated to integer

But this code compiles just fine:

const maxFrameRate = 60
foo := (1.0 / maxFrameRate) * 1e9
minInterval := int64(foo)

I'm not doing something wrong, am I?

Chris

Steven Blenkinsop

unread,
Jul 2, 2011, 9:44:14 PM7/2/11
to Chris Jones, golan...@googlegroups.com
The problem is that (1.0 / maxFrameRate) * 1e9 is a constant expressions that the compiler knows cannot be represented as an int64. So it is stopping you from doing it. foo, on the other hand, is a variable, so the compiler doesn't know it can't be represented as an integer, so there's no error, and the conversion succeeds. Here's the relevant parts of the spec:

This is what allows the second case: 
 When converting a floating-point number to an integer, the fraction is discarded (truncation towards zero). 

And this is what prevents the first case:
The values of typed constants must always be accurately representable as values of the constant type.

int64((1.0 / maxFrameRate) * 1e9) is a typed constant, but the value cannot be represented with the type int64.

This behaviour looks inconsistent and is inconvenient in this case. I believe the rationale is that you're probably making a mistake if you take a known value and try to convert it to a type that can't represent it. I'm not sure how useful this hand holding is in practice. Regardless, it would imply to me that there should be some way to explicitly truncate a constant if you can't do it via a conversion.

peterGo

unread,
Jul 2, 2011, 10:09:01 PM7/2/11
to golang-nuts
Chris,

For an integer result, use integer arithmetic.

const maxFrameRate = 60
minInterval := int64(int64(1e9) / maxFrameRate)

Peter

peterGo

unread,
Jul 2, 2011, 10:12:05 PM7/2/11
to golang-nuts
Chris,

I meant to simplify the answer.

For an integer result, use integer arithmetic.

const maxFrameRate = 60
minInterval := int64(1e9) / maxFrameRate

Peter

Michael Jones

unread,
Jul 3, 2011, 10:07:49 AM7/3/11
to peterGo, golang-nuts
interestingly...

var maxFrameRate int = 60
minInterval := 1e9/maxFrameRate
fmt.Printf("%T, %v\n", minInterval, minInterval)

prints: int, 16666666

while

const maxFrameRate = 60
minInterval := 1e9/maxFrameRate
fmt.Printf("%T, %v\n", minInterval, minInterval)

prints: float64, 1.6666666666666666e+07

P.S. Off topic, but perhaps significant to the application is rounding:

1e9/maxFrameRate // interval sightly smaller than minimum at 60Hz = 16666666
(1e9 + maxFrameRate - 1)/maxFrameRate // similar, but slightly larger = 16666667
--

Michael T. Jones

   Chief Technology Advocate, Google Inc.

   1600 Amphitheatre Parkway, Mountain View, California 94043

   Email: m...@google.com  Mobile: 650-335-5765  Fax: 650-649-1938

   Organizing the world's information to make it universally accessible and useful


Rob 'Commander' Pike

unread,
Jul 3, 2011, 6:24:11 PM7/3/11
to Michael Jones, peterGo, golang-nuts
On 04/07/2011, at 12:07 AM, Michael Jones wrote:

interestingly...

var maxFrameRate int = 60
minInterval := 1e9/maxFrameRate

maxFrameRate is an integer, and since there are no conversions on this line, minInterval is therefore an integer. 1e9 is representable as an integer so it flows neatly.

fmt.Printf("%T, %v\n", minInterval, minInterval)

prints: int, 16666666

while

const maxFrameRate = 60
minInterval := 1e9/maxFrameRate

here maxFrameRate is an ideal constant, so the floating-point syntax of 1e9 determines the type, and minInterval becomes a float64.

-rob

Seer

unread,
Jul 3, 2011, 9:53:47 PM7/3/11
to golang-nuts

He did not really want 1e9, he wanted 10**9. The first conflates
floating point styling and scientific notation with exponentiation. If
we had some syntax for the second it would have worked as expected.

Rob 'Commander' Pike

unread,
Jul 3, 2011, 10:50:33 PM7/3/11
to Seer, golang-nuts

On Jul 4, 2011, at 11:53 AM, Seer wrote:

>
> He did not really want 1e9, he wanted 10**9. The first conflates
> floating point styling and scientific notation with exponentiation. If
> we had some syntax for the second it would have worked as expected.

It worked as I expected and explained. As for the missing syntax: int(1e9).

-rob

Reply all
Reply to author
Forward
0 new messages