constatnt conversion question

118 views
Skip to first unread message

dja...@gmail.com

unread,
May 20, 2019, 5:34:03 AM5/20/19
to golang-nuts
Hi,
does this should work ?

package main

import (
   
"fmt"
)

func main
() {
   
const (
        c
= 2
        z
= 3.3
        y
= c * z
        x
= int(y) // or x int = y
   
)

    fmt
.Println(x)
}


it does not compile with error:
constant 6.6 truncated to integer


Jan Mercl

unread,
May 20, 2019, 5:43:42 AM5/20/19
to dja...@gmail.com, golang-nuts
On Mon, May 20, 2019 at 11:33 AM <dja...@gmail.com> wrote:
>
> Hi,
> does this should work ?

The error is correct. See https://golang.org/ref/spec#Conversions

""""
A constant value x can be converted to type T if x is representable by
a value of T.
""""

An integer cannot represent the value 6.6 hence the failure.

fge...@gmail.com

unread,
May 20, 2019, 5:45:42 AM5/20/19
to dja...@gmail.com, golang-nuts
https://golang.org/ref/spec#Constants

"A constant may be given a type explicitly by a constant declaration
or conversion, or implicitly when used in a variable declaration or an
assignment or as an operand in an expression. It is an error if the
constant value cannot be represented as a value of the respective
type."
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/736e8b03-d38f-4ec4-adc8-fcb77e0cda7b%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

Michael Jones

unread,
May 20, 2019, 3:01:21 PM5/20/19
to fge...@gmail.com, dja...@gmail.com, golang-nuts

fge...@gmail.com

unread,
May 21, 2019, 2:50:44 AM5/21/19
to Michael Jones, dja...@gmail.com, golang-nuts
Could you please clarify which statement your example is meant to
confirm or refute?
> *Michael T. Jonesmich...@gmail.com <michae...@gmail.com>*
>

Michael Jones

unread,
May 21, 2019, 6:06:44 AM5/21/19
to fge...@gmail.com, dja...@gmail.com, golang-nuts
Oh, Sorry. Have been away from email today. (Focused 100% in VS-code on a cool feature for Go)

My statement was meant to convey an insight into a subtle aspect of Go's constants and high-precision expression evaluation--that the "type" of untyped constants/values, in the conversion rules sense, is derived in the instant of the conversion and is not an inherent trait of the value as is quite generally the case in other languages and situations. Also I think, the spec document is a little deceptive here, or at least, it needs to be read creatively to understand what all the possibilities are.

In this case, the original question by Djadala was about a const "6.6" not being able to be coerced to integer form in either of two ways of trying ("x = int(y)" and "x int = y"). Both you and Jan explained why this is so and where/how it is defined in the specification. That was authoritative.

However, the original question was worded in such a way that I could not discern if he was asking "please share the official reason why this seems impossible" or if instead he/she meant, "can I do this? I've tried two ways, and it seems impossible." I'm very supportive of the "how can I make it work?" sentiment and I doubted that the OP would figure it out since the two responses seemed so absolute, so I weighed in.

Here's the subtle point. That 6.6 constant "y" is NOT a floating-point value.  it's value just happens to "be as if floating" at the moment. However, "y*10" evaluates to 66, and that is a "just plain 66" not "10 times the floating point 6.6, therefore an inherent floating point value of 66.0" The upshot is that Djadala cannot get "y" into an int, but can easily get "10*y" into one, and having done so, can make that integer 66 into the integer 6 via truncating integer division as I showed in the linked Go Playground example: https://play.golang.org/p/7gcb9Yv7c9e

Since the "6.6" has one decimal place making y be as if floating point, multiplication by an integer multiple of 10 is enough to clear the decimals and let it be as if integer in arbitrary expressions. If it was "6.67" (2 places) or "6.678" (three places), then the least power of ten to clear the "as if floating" problem Djadala faced would be "10**k, k >= number of decimals" as was indicated in my comment in the linked Playground example.

Sadly, this is not a general-purpose, remedy because the magic expression evaluation logic insists that values fit into the target size; were it not this way, we might imagine multiplying by 10**k, k>=19, capturing the integerness of the expression in that instant, and then dividing by the same factor. Alas, we'll be stopped right there because the expression, while as if an integer, is simultaneously, as if too big to fit into one. Since 64-bit ints are big and the OP was wrestling with only one decimal place in a small sized number, it worked with fifteen or more digits of precision to spare. However, if "y" were (1e16 + 0.6) then there would not be much wiggle room to clear the decimals this way.

If these kinds of topics are interesting to you, there are discussions about related matters and possible changes for Go 2 in various proposal threads.

fge...@gmail.com

unread,
May 21, 2019, 6:46:44 AM5/21/19
to Michael Jones, dja...@gmail.com, golang-nuts
naah, thanks, that's ok.
As soon as I can acquire my own turing machine, I'll insist on 1 number type.
Until then I can live with different number types and some rules for
my finite machines.


On 5/21/19, Michael Jones <michae...@gmail.com> wrote:
> Oh, Sorry. Have been away from email today. (Focused 100% in VS-code on a
> cool feature for Go)
>
> My statement was meant to convey an insight into a subtle aspect of Go's
> constants and high-precision expression evaluation--that the "type" of
> untyped constants/values, in the conversion rules sense, is derived in the
> instant of the conversion and is not an inherent trait of the value as is
> quite generally the case in other languages and situations. Also I think,
> the spec document is a little deceptive here, or at least, it needs to be
> read creatively to understand what all the possibilities are.
>
> In this case, the original question by Djadala was about a const "6.6" not
> being able to be coerced to integer form in either of two ways of
> trying ("x = int(y)" and "x int = y"). Both you and Jan explained why this
> is so and where/how it is defined in the specification. That was
> authoritative.
>
> However, the original question was worded in such a way that I could not
> discern if he was asking "please share the official reason why this seems
> impossible" or if instead he/she meant, "can I do this? I've tried two
> ways, and it seems impossible." I'm very supportive of the "how can I make
> it work?" sentiment and I doubted that the OP would figure it out since the
> two responses seemed so absolute, so I weighed in.
>
> Here's the subtle point. *That 6.6 constant "y" is NOT a floating-point
> value.* it's value just happens to "be as if floating" at the moment.
> However, "y*10" evaluates to 66, and that is a "just plain 66" not "10
> times the floating point 6.6, therefore an inherent floating point value of
> 66.0" The upshot is that Djadala cannot get "y" into an int, but can easily
> get "10*y" into one, and having done so, can make that integer 66 into the
> integer 6 via truncating integer division as I showed in the linked Go
> Playground example: https://play.golang.org/p/7gcb9Yv7c9e
>
> Since the "6.6" has one decimal place making y *be as if floating point,*
> multiplication by an integer multiple of 10 is enough to clear the decimals
> and let it *be as if integer* in arbitrary expressions. If it was "6.67" (2
> places) or "6.678" (three places), then the least power of ten to clear the
> "as if floating" problem Djadala faced would be "10**k, k >= number of
> decimals" as was indicated in my comment in the linked Playground example.
>
> Sadly, this is not a general-purpose, remedy because the magic expression
> evaluation logic insists that values fit into the target size; were it not
> this way, we might imagine multiplying by 10**k, k>=19, capturing the
> integerness of the expression in that instant, and then dividing by the
> same factor. Alas, we'll be stopped right there because the expression,
> while *as if an integer,* is simultaneously, *as if too big to fit into
> one. *Since 64-bit ints are big and the OP was wrestling with only one

dja...@gmail.com

unread,
May 21, 2019, 7:12:38 AM5/21/19
to golang-nuts

Thanks all for comments,
 
for me confusion is that
int( some_float_var)

works, and surprisingly
int( some_float_constant)

does not. 
 

fge...@gmail.com

unread,
May 22, 2019, 1:39:34 AM5/22/19
to dja...@gmail.com, golang-nuts
I'm not sure if you are still interested in details or not.

Assuming you ask the question "why" it works differently, one of the
short answers, assuming some basic background knowledge on your part
about compilers and programming language implementation details:
similar, but different concepts->different restrictions->different
rules->different implementations.
You might want to take a look at the different precision requirements
in the spec for both constants and variables.
You maybe also want to think about the costs and benefits to having
the compiler and the compiled code work this way or if you are really
curious, think about how the same rules with the same semantics could
be implemented for both constants and variables,
I'm not sure, but iirc there was some discussion pre 1.0 about some of
the aspects of constants, you might want to take a look at the mailing
list archives.

Another short answer: the expressions just look similar, these aren't the same.

(+1: if you quote code, please use links to the playground or
alternatively just no html in emails.)
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/50e711ce-6e11-43d7-8e7f-46275e141bdb%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages