1

I have a string which I'm converting to BigInteger by parsing then shifting it by 3 bits to the left and convert to a string again. The problem is that it always output extra bits before the actual value. For example:

Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
        Dim positiveString As String = "C0020ACB1086886D8C2E4D2DEDC726A6"
        Dim posBigInt As BigInteger = 0
        posBigInt = BigInteger.Parse(positiveString, System.Globalization.NumberStyles.AllowHexSpecifier)
        posBigInt = posBigInt << Hex(3)
        RichTextBox1.Text = posBigInt.ToString("X")
    End Sub
  • Gives me: E001056588434436C6172696F6E393530 - Which is incorrect
  • First 4 bytes Should be: 00105658 (I can't check the whole array because i don't know another way to do it other then BigInteger, checked with UInt64)

The "E" before the value is what I can't explain. I tried different hex strings but it always produces those extra bits. What am I doing wrong?

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
James_BK
  • 21
  • 1
  • 7
  • FWIW your hex number times 8 (left shifted by 3) should be hex "6001056588434436c6172696f6e393530", i.e. it should start with "600105658...". After all, "C" is 12. Times 8, that is 96, or hex 60. – Rudy Velthuis Jul 04 '18 at 22:19
  • @RudyVelthuis yes, it gives 6001056588434436C6172696F6E393530 but if im test shifting with uint32, it gives me 001056.. – James_BK Jul 05 '18 at 02:41
  • Why would you test shifting with a uint32? Anyway, I guess that in your test the 6 overflows the size of the uint32, so you only see the low 32 bits. – Rudy Velthuis Jul 05 '18 at 11:06

1 Answers1

5
 Dim positiveString As String = "C0020ACB1086886D8C2E4D2DEDC726A6"

It is not actually positive, easy to see with the debugger. Presumably you saw that. That hex literal has the sign bit turned on, C = 1100 in binary. The sign bit is the most significant bit in the value, the first 1 in 1100. That bit does not otherwise participate in the value, it only indicates the sign.

Making it positive, i.e. turning off the sign bit, is easy to do. Fix:

 Dim positiveString As String = "0C0020ACB1086886D8C2E4D2DEDC726A6"

More about two's complement encoding, the standard way that processors encode negative numbers today, is available here.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 0C gives me 6001056588434436C6172696F6E393530, i guess its impossible to make it clear 001056 without extra bits, so i think it should to be like this – James_BK Jul 05 '18 at 02:28
  • It should be `60010...`, not `0010...`. So it is *not impossible* to get `0010...`(just *and* with an appropriate mask and you get that), but it is *wrong*. – Rudy Velthuis Jul 05 '18 at 11:09