10 write power as constants compact

I am reading the recently released Go Go programming language , and it has been a joy so far (when Brian Kernighan was one of the authors, I would not expect anything but perfection in any case).

In chapter 3, I found the following exercise:

Exercise 3.13 Write const declarations for KB, MB, up to YB as compact as possible.

( NOTE : in this context, KB, MB, etc. denote authority 1000)

This is preceded by a section in which iota is introduced as a mechanism for generating useful constants; in particular, the previous paragraph shows a good and compact way to define powers of 1024 as constants:

 const ( _ = 1 << (10 * iota) KiB MiB GiB TiB PiB EiB ZiB YiB ) 

The authors further mention this with respect to degrees 10:

The iota mechanism has its limits. For example, it is not possible to create more familiar 1000 credentials (KB, MB, etc.), since there is no exponential operator.

I am struggling with this exercise because it looks like the expected solution is something more complicated than just manually writing 1000 permissions (especially after iota ). I feel there is some kind of smart way to do this that uses iota subtle way combined with something else.

I thought about systematically subtracting the "excess" amount from each of the capacities of 1024 in order to get 1000 powers, but this led me nowhere. Then I looked at the binary representations to try to make a generic template where iota might be useful, but again, I got nothing.

I really don’t see how it would be possible to generate 1000 powers from one increasing value ( iota ) without an exponential operator.

Any ideas?

+5
source share
2 answers

I would say that this is impossible because you want to represent the function 10^(3i) , where i is a positive integer as some function f(i) , where f is the composition function of your elementary functions go (+, -, / , *).

This is possible for 2^(10i) only because go introduced another elementary raising to the power of an elementary function. Therefore, if 1 << y allows y to be a float, you can change your code to use 1 << (log2(10) * 3 * i) . This would work because it is equivalent to the solution 10^(3i) = 2^y . Taking log2 on both sides y = log2(10) * 3 * i .

But, unfortunately, the bitwise shift is the whole operator.

+3
source

You yourself quoted:

The iota mechanism has its limits. For example, it is not possible to create more familiar 1000 credentials (KB, MB, etc.), since there is no exponential operator.

The authors do not want you to still find a way, even though they did not know anything. The authors want you to create permanent ads for KB, MB, etc. As compact as possible.

With floating point literals

Here's a compact way. It uses exponential floating point literals . Think about it: the 1e3 record 1e3 even shorter than the 1000 record (not to mention the rest ...).

It also compresses all identifiers into one constant specification, so we reduce the signs = to 1.

Here it is just one line ( 67 characters without spaces):

 const ( KB, MB, GB, TB, PB, EB, ZB, YB = 1e3, 1e6, 1e9, 1e12, 1e15, 1e18, 1e21, 1e24 ) 

Note that since we used floating point literals, constant identifiers ( KB , MB ...) denote floating point constants, even if the fractional parts of the literals are zero.

With a whole literal, using KB as a factor

If we need untyped integer constants, we must write 1000 for KB . And to get the next one, we will automatically move on to multiplying the previous identifier by 1000 . But note that we can also multiply the next by KB , because it's exactly 1000 - but shorter by two characters :).

So here are the declarations of untyped integer constants ( 77 characters without spaces):

 const (KB,MB,GB,TB,PB,EB,ZB,YB = 1000,KB*KB,MB*KB,GB*KB,TB*GB,PB*KB,EB*KB,ZB*KB) 

(Sorry to remove the spaces, but wanted it to fit on one line.)

With an integer literal, using the extra x const as a factor

You can even get 3 characters from the last solution if you also enter a const x length of 1 char, which you use several times to do the multiplication instead of *KB :

With optional x const ( 74 characters without spaces):

 const (x,KB,MB,GB,TB,PB,EB,ZB,YB = 1000,x,x*x,MB*x,GB*x,TB*GB,PB*x,EB*x,ZB*x) 

With rune literal

We can even shorten it another character if we specify the constant 1000 as a rune constant, with a rune whose code point 1000 , which is 'Ϩ' is 1 character less :)

With rune literal 'Ϩ' const ( 73 characters without spaces):

 const (x,KB,MB,GB,TB,PB,EB,ZB,YB = 'Ϩ',x,x*x,MB*x,GB*x,TB*GB,PB*x,EB*x,ZB*x) 

Note that these will be rune constants, but like all other numerical constants, they represent arbitrary precision values ​​and do not overflow.

+6
source

Source: https://habr.com/ru/post/1237532/


All Articles