Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does 1 << 64 - 1 work?

Tags:

At http://tour.golang.org/#14 they show an example where the number 1 is shifted by 64 bits. This of course would result in an overflow, but then it is subtracted by 1 and all is well. How does half of the expression result in a failure while the entire expression as whole work just fine?

Thoughts:
I would assume that the setting of the unsigned to a number larger than what it allows is what causes the explosion. It would seem that memory is allocated more loosely on the right hand side of the expression than on the left? Is this true?

like image 677
Parris Avatar asked Nov 09 '14 21:11

Parris


People also ask

What does << mean in C?

The << operator shifts the left-hand value left by the (right-hand value) bits. Your example does nothing! 1 shifted 0 bits to the left is still 1. However, 1 << 1 is 2, 1 << 2 is 4, etc.

How do you know if two bits are set?

Check if a number has two adjacent set bits in C++ Suppose the number 12 has two consecutive 1s (12 = 1100). To check this type of number, the idea is very simple. We will shift the number 1 bit, then do bitwise AND. If the bitwise AND result is non-zero, then there must be some consecutive 1s.


2 Answers

The result of your expression is a (compile time) constant and the expression is therefore evaluated during compilation. The language specification mandates that

Constant expressions are always evaluated exactly; intermediate values and the constants themselves may require precision significantly larger than supported by any predeclared type in the language. The following are legal declarations:

const Huge = 1 << 100         // Huge == 1267650600228229401496703205376  (untyped integer constant) const Four int8 = Huge >> 98  // Four == 4                                (type int8) 

https://golang.org/ref/spec#Constant_expressions

like image 162
user7610 Avatar answered Sep 18 '22 13:09

user7610


That is because the Go compiler handles constant expressions as numeric constants. Contrary to the data-types that have to obey the law of range, storage bits and side-effects like overflow, numeric constants never lose precision.

Numeric constants only get deduced down to a data-type with limited precision and range at the moment when you assign them to a variable (which has a known type and thus a numeric range and a defined way to store the number into bits). You can also force them to get deduced to a ordinary data-type by using them as part of a equation that contains non Numeric constant types.

Confused? So was I..

Here is a longer write-up on the data-types and how constants are handled: http://www.goinggo.net/2014/04/introduction-to-numeric-constants-in-go.html?m=1

like image 42
Nils Pipenbrinck Avatar answered Sep 16 '22 13:09

Nils Pipenbrinck