title: Go hashtable: casting without conversion?
body: <p>I am implementing a specialized hashtable. I'm trying store a lot of data in a single 64-bit int key, for space usage and performance reasons.</p>
  
  <p>Each key should have this structure:</p>
  
  <pre><code>// Key structure, from LSB
  // eval result (16 bits)
  // move (16 bits)
  // age (16 bits): the move of the game on which this position would have occurred
  // depth (8 bits)
  // node type (8 bits): from the three constants above
  </code></pre>
  
  <p>Here is a simple implementation:</p>
  
  <pre><code>var keys [1000]uint64
  var values [1000]uint64
  
  func Put(b *dragontoothmg.Board, m dragontoothmg.Move, eval int16, depth uint8, ntype uint8) {
      var value uint64 = uint64(eval) | (uint64(m) &lt;&lt; 16) | (uint64(b.Fullmoveno) &lt;&lt; 32) |
          (uint64(depth) &lt;&lt; 48) | (uint64(ntype) &lt;&lt; 56)
      hash := b.Hash()
      key := hash ^ value
      index := hash % uint64(len(keys))
      keys[index] = key
      values[index] = value
  }
  
  func Get(b *dragontoothmg.Board) (found bool, move dragontoothmg.Move,
      eval int16, depth uint8, ntype uint8) {
      hash := b.Hash()
      index := hash % uint64(len(keys))
      key := keys[index]
      value := values[index]
      found = (hash == (key ^ value))
      if !found {
          return false, 0, 0, 0, 0
      }
      eval = int16(value &amp; 0xFFFF)
      move = dragontoothmg.Move((value &gt;&gt; 16) &amp; 0xFFFF)
      depth = uint8((value &gt;&gt; 48) &amp; 0xFF)
      ntype = uint8((value &gt;&gt; 56) &amp; 0xFF)
      return
  }
  </code></pre>
  
  <p>However, when I try to <code>Get()</code> the data, it comes back corrupted. I suspect this might be related to the fact that <code>eval</code> is a signed int, and the cast converts it to a signed uint64. What have I done wrong, and how can I fix it?</p>
  
  <p>This is failing test result:</p>
  
  <pre><code>--- FAIL: TestSimpleTt (0.10s)
      transtable_test.go:37: Simple ttable test failed. 
          Put data: (board: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 0) e2e4 -30 6 2 
           Fetched data: true h8h8 -30 255 255
  FAIL
  </code></pre>
  
  <p><code>h8h8</code> is the maximum value of the field, for what it's worth.</p>