Modulus not working for Float & Escaping %

1,359 views
Skip to first unread message

Kishore Kumar Vaishnav

unread,
Sep 29, 2014, 7:27:57 PM9/29/14
to golan...@googlegroups.com
I am still a learner to the Go language and found few things interesting, I would like to understand in detail. I did checked around the web & forumn but looks like none of them reported / discussed, I might miss any.


a) I am not able to do modulus on the float types, it reports the below statement
invalid operation: c % d (operator % not defined on float32)
I feel that modulus should not be restricted on int but should be allowed to be done on float too. Is this a bug to be filed? If not, why?

b) I am trying to use the below line 
fmt.Printf(" a % b : %d", a%b)
instead of printing the desired output
 a % b : 3
it prints the below output
 a  11 : %!d(MISSING)
So I tried to escape with \ but it didn't worked as it generally work for the other characters when we do escaping. But what I found interesting is that it escapes % with % itself. 
fmt.Printf(" a \" % b : %d", a%b)    // a " % b : 3
fmt.Printf(" a %% b : %d", a%b)      // a % b : 3
Is this what expected? Or Go is missing something?

Ian Lance Taylor

unread,
Sep 29, 2014, 7:48:49 PM9/29/14
to Kishore Kumar Vaishnav, golang-nuts
On Mon, Sep 29, 2014 at 4:27 PM, Kishore Kumar Vaishnav
<kishore...@gmail.com> wrote:
>
> a) I am not able to do modulus on the float types, it reports the below
> statement
> invalid operation: c % d (operator % not defined on float32)
> I feel that modulus should not be restricted on int but should be allowed to
> be done on float too. Is this a bug to be filed? If not, why?

I don't know of any sensible definition of the modulos operation on
floating point values. What should it evaluate to.


> b) I am trying to use the below line
> fmt.Printf(" a % b : %d", a%b)
> instead of printing the desired output
> a % b : 3
> it prints the below output
> a 11 : %!d(MISSING)
> So I tried to escape with \ but it didn't worked as it generally work for
> the other characters when we do escaping. But what I found interesting is
> that it escapes % with % itself.
> fmt.Printf(" a \" % b : %d", a%b) // a " % b : 3
> fmt.Printf(" a %% b : %d", a%b) // a % b : 3
> Is this what expected? Or Go is missing something?

This is working as intended. When using fmt.Printf you introduce
formatting directives with %. The %% formatting directive prints as
"%". There is no need to also support backslash escaping, which is a
good thing because backslashes are evaluated when parsing string
literals.

C's printf function behaves the same way.

Ian

Kishore Kumar Vaishnav

unread,
Sep 29, 2014, 9:41:56 PM9/29/14
to golan...@googlegroups.com, kishore...@gmail.com
Hi Ian,

Thanks for your reply. Please see my inline comments


On Monday, September 29, 2014 4:48:49 PM UTC-7, Ian Lance Taylor wrote:
On Mon, Sep 29, 2014 at 4:27 PM, Kishore Kumar Vaishnav
<kishore...@gmail.com> wrote:
>
> a) I am not able to do modulus on the float types, it reports the below
> statement
> invalid operation: c % d (operator % not defined on float32)
> I feel that modulus should not be restricted on int but should be allowed to
> be done on float too. Is this a bug to be filed? If not, why?

I don't know of any sensible definition of the modulos operation on
floating point values.  What should it evaluate to.
Based on your answer to b) I referred the C language and found that % doesn't works for float operation. And later I found that math package contains, fmod to do the modulus on float types. And I referred back with Go, it contained Mod present in the math package and worked. Both works with float64 and not float32. Then out of curiosity, I tried to with Ruby it works with both int & float and returns the type based on the type it is been passed.

But do I assume that Go's functionality will be similar to C.


> b) I am trying to use the below line
> fmt.Printf(" a % b : %d", a%b)
> instead of printing the desired output
>  a % b : 3
> it prints the below output
>  a  11 : %!d(MISSING)
> So I tried to escape with \ but it didn't worked as it generally work for
> the other characters when we do escaping. But what I found interesting is
> that it escapes % with % itself.
> fmt.Printf(" a \" % b : %d", a%b)    // a " % b : 3
> fmt.Printf(" a %% b : %d", a%b)      // a % b : 3
> Is this what expected? Or Go is missing something?

This is working as intended.  When using fmt.Printf you introduce
formatting directives with %.  The %% formatting directive prints as
"%".  There is no need to also support backslash escaping, which is a
good thing because backslashes are evaluated when parsing string
literals.

C's printf function behaves the same way.
Regarding this, yes, C's printf function works the same way. But isn't that confusing as we escape everything with \ but only % is the exceptional case. Why doesn't % is not considered as string literals when it is followed by \.

One thing I am not clear is that are we mimic'ing C apart from the concurrency (which is a major drawback in C) & other features. Sorry if my questions are vague as I am trying to understand Go language more in depth.

Ian

andrewc...@gmail.com

unread,
Sep 29, 2014, 9:42:20 PM9/29/14
to golan...@googlegroups.com
Being really nitpicky, but I believe its called modulo. Modulus is the magnitude of a vector.

andrewc...@gmail.com

unread,
Sep 29, 2014, 9:44:44 PM9/29/14
to golan...@googlegroups.com
*Absolute value of a number. Now I'm getting things mixed up.


On Tuesday, September 30, 2014 12:27:57 PM UTC+13, Kishore Kumar Vaishnav wrote:

Ian Lance Taylor

unread,
Sep 29, 2014, 11:00:41 PM9/29/14
to Kishore Kumar Vaishnav, golang-nuts
There are two different levels of quoting involved here. A backslash
quotes characters in a string literal. The string literal is passed
to fmt.Printf. At that point the backslash quoting is gone. So if we
used backslash quoting for % in fmt.Printf, we would have to write
either fmt.Printf("\\%") or fmt.Printf(`\%`). Easier to write
fmt.Printf("%%"), especially since that is what people already
familiar with printf will write.

Ian

kis...@railsfactory.org

unread,
Sep 30, 2014, 1:29:55 PM9/30/14
to golan...@googlegroups.com, kishore...@gmail.com
Hi Ian,

Thanks for you explanation. I am still not convinced about this, as lot of questions raises for me.. is Go nothing but C + performance + etc., ? If yes, why? Anyway I might be acting pedantic, ignore it. Thanks. 

chris dollin

unread,
Oct 1, 2014, 9:00:12 AM10/1/14
to kis...@railsfactory.org, golang-nuts, kishore...@gmail.com
On 30 September 2014 18:29, <kis...@railsfactory.org> wrote:
> Hi Ian,
>
> Thanks for you explanation. I am still not convinced about this, as lot of
> questions raises for me.. is Go nothing but C + performance + etc.,

No. It is its own language, noting that it -- like many other languages --
has been influenced in its design by C (which was in turn derived
from B, which was influenced / inspired-by by BCPL, which itself
was a cut-down CPL, and ...

The thing about \-escapes and % is because \-escapes apply at
/compile time/ when "string" and 'char' literals are being constructed,
while the interpretation of %notpercent and %% is done at /run-time/
by the code in the fmt functions. There's no particular in-advance
reason why some programs interpretation of strings be the same as
that of the language it's implemented in -- so arguments like
familiarity to the target audience or general convenience of expression
apply.

Chris

--
Chris "allusive" Dollin

Kishore Kumar Vaishnav

unread,
Oct 1, 2014, 1:52:48 PM10/1/14
to golan...@googlegroups.com, kis...@railsfactory.org, kishore...@gmail.com
Thanks, this explains better to me. I am glad to understand why %% was special.

xea...@gmail.com

unread,
Oct 1, 2014, 2:17:01 PM10/1/14
to golan...@googlegroups.com, kishore...@gmail.com


On Tuesday, 30 September 2014 00:48:49 UTC+1, Ian Lance Taylor wrote:
On Mon, Sep 29, 2014 at 4:27 PM, Kishore Kumar Vaishnav
<kishore...@gmail.com> wrote:
>
> a) I am not able to do modulus on the float types, it reports the below
> statement
> invalid operation: c % d (operator % not defined on float32)
> I feel that modulus should not be restricted on int but should be allowed to
> be done on float too. Is this a bug to be filed? If not, why?

I don't know of any sensible definition of the modulos operation on
floating point values.  What should it evaluate to.



In response to both of you

math.Floor(c/d) is the 'obvious' float equivalent of integer divide,

Thus use c-d*math.Floor(c/d) to give a float equivalent of modulus - it should give the same behaviour when c and d at integer values..  and should give what the original poster asked for.

Disclaimer - double check the behaviour of both functions when values are negative to make sure they are equivalent - I haven't

Matt Harden

unread,
Oct 1, 2014, 7:45:28 PM10/1/14
to xea...@gmail.com, golang-nuts, kishore...@gmail.com
The OP found math.Mod, which is the float64 modulus operation. Case closed IMO.

--
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.
For more options, visit https://groups.google.com/d/optout.

Kishore Kumar Vaishnav

unread,
Oct 1, 2014, 8:49:48 PM10/1/14
to golan...@googlegroups.com, xea...@gmail.com, kishore...@gmail.com
Thanks I found this earlier too, do you remember any float32 modulus function. Looks like its not present, is it something which is intentionally not done for some reason?

Matt Harden

unread,
Oct 1, 2014, 10:32:39 PM10/1/14
to Kishore Kumar Vaishnav, golang-nuts, xea...@gmail.com
On Wed, Oct 1, 2014 at 7:49 PM, Kishore Kumar Vaishnav <kishore...@gmail.com> wrote:
Thanks I found this earlier too

Yes - you're the OP - it stands for "original poster".
 
, do you remember any float32 modulus function. Looks like its not present, is it something which is intentionally not done for some reason?

None (well, very few) of the functions in the math package use float32. My understanding is that this is because on modern processors float32 operations don't tend to be any faster than float64 operations. Maybe I just assumed that. Anyway just use float64 for math and convert to/from float32 when storage space is an issue.
Reply all
Reply to author
Forward
0 new messages