I try to help these kids, I really do.



  • We've got some co-op students here. They're like interns, but they get paid.

    I found this bit-bashing code and tried to tell him that it wouldn't work:

    Public Sub New(ByVal Something As Byte()) 
      ...
      Me.Value= ((Incoming(1) << 16) Or (Incoming(2) << 8) Or Incoming(3)) And &HFFFFFF
      ...

    End Sub

    His response was, "No, it's working. We can see the right values." He didn't understand that "Incoming" is only 8 bits long and thus can't bit-shift by more than 8 bits.

    Poor kid.



  • Isn't that implementation specific how many bytes a var uses? In C it is. Well, as it seems that's VB, and that is f***** up anway.

    Oh,btw: WTF is this code supposed to do? 



  • Most languages would promote byte to int (possibly through a cast), so the shift by 16 would be allowed on a 32-bit platform.  Does VB not do that?



  • @arty said:

    Most languages would promote byte to int (possibly through a cast), so the shift by 16 would be allowed on a 32-bit platform.  Does VB not do that?

    You put that in a way more technical language than me (and btw: yes, I know what a bitshift is).

    I just tried... mk? There is always somebody worse than me ! 

    Is there a byte in C that isn't always converted to an int? 



  • @arty said:

    Most languages would promote byte to int (possibly through a cast), so the shift by 16 would be allowed on a 32-bit platform.  Does VB not do that?

    In this case, it don't think it matters.  Looking at the docs, VB applies a mask to the second operand to ensure that the result is not larger than the first operand.  So a short shifted 16 places still results in a short, at least that's how I read the docs and it been too long since I did bit ops to think about it.  I looked it up cause I vaguely remember compiler errors about "the size is not large enough to hold the shifted value" or some other whining message, but that was probably C#.

     (ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_vbalr/html/fdb93d25-81ba-417f-b808-41207bfb8440.htm)

    Example:

    Dim A as Short = 255

    Dim B as Short = (A << 16)

    Per the chart, A is shifted 0 bits (16 AND 15 = 0) resulting in B = 255.  I personally disagree with this behavior, B should be 0.  IMO, it is acting like some kind of mutant left shift/rotate.  I'm guessing this is what is causing the stated "It's working, I see the values." comment.

     

    In fact I just tried this in C# and got a compile error about cannot convert int to short.   Damn VB and it's helper monkeys.

    short a = 255;

    short b = (a << 16);  // compile error here


     



  • @lpope187 said:

    @arty said:

    Most languages would promote byte to int (possibly through a cast), so the shift by 16 would be allowed on a 32-bit platform.  Does VB not do that?

    In this case, it don't think it matters.  Looking at the docs, VB applies a mask to the second operand to ensure that the result is not larger than the first operand.  So a short shifted 16 places still results in a short, at least that's how I read the docs and it been too long since I did bit ops to think about it.  I looked it up cause I vaguely remember compiler errors about "the size is not large enough to hold the shifted value" or some other whining message, but that was probably C#.

     (ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_vbalr/html/fdb93d25-81ba-417f-b808-41207bfb8440.htm)

    Example:

    Dim A as Short = 255

    Dim B as Short = (A << 16)

    Per the chart, A is shifted 0 bits (16 AND 15 = 0) resulting in B = 255.  I personally disagree with this behavior, B should be 0.  IMO, it is acting like some kind of mutant left shift/rotate.  I'm guessing this is what is causing the stated "It's working, I see the values." comment.

     

    In fact I just tried this in C# and got a compile error about cannot convert int to short.   Damn VB and it's helper monkeys.

    short a = 255;

    short b = (a << 16);  // compile error here


     

    Firstly, realize how useless an ms-help url is to those without MSDN (like me, on linux). Try this.

    Secondly, you are basically correct: VB masks the shift amount (the documentation obfuscates it with masking and such, easier to think of it this way: it just does a modulus of the amount by the size (in bits) of the left side (so-called pattern). IE: Byte is 8 bits thus the shift amount is modulus 8 (or AND 7). This is probably why it 'worked' even though it is incorrect (and no, the Byte is not promoted in this case, in fact, IIRC VB doesn't promote unless necessary).

    Of course, VB goes all fancy and calls it an "arithmetic shift" - as if there were any other kind of left shift. Though, technically a true arithmetic left shift would exactly emulate a * 2 ^ x. Which would mean x > SizeOf(pattern)*8 leaves the result 0. So this isn't really an arithmetic shift even though the docs say so.



  • @aquanight said:
    Of course, VB goes all fancy and calls it an "arithmetic shift" - as if there were any other kind of left shift. Though, technically a true arithmetic left shift would exactly emulate a * 2 ^ x. Which would mean x > SizeOf(pattern)*8 leaves the result 0. So this isn't really an arithmetic shift even though the docs say so.
    Wait, are you saying that instead of letting variables overflow, VB just sets the value to 0?

  • Considered Harmful

    @Faxmachinen said:

    @aquanight said:
    Of course, VB goes all fancy and calls it an "arithmetic shift" - as if there were any other kind of left shift. Though, technically a true arithmetic left shift would exactly emulate a * 2 ^ x. Which would mean x > SizeOf(pattern)*8 leaves the result 0. So this isn't really an arithmetic shift even though the docs say so.
    Wait, are you saying that instead of letting variables overflow, VB just sets the value to 0?

    Well I wrote a long, detailed, and illustrated explanation of what was happening, and then the forum software stripped away all my formatting; so I said, "fuck it."



  • I also constructed a long, witty, informative post on this very subject but lost it when my computer magically rebooted 



  • I have a truly marvellous proof of this proposition, which this WTF is unfortunately too narrow to contain.




  • @Faxmachinen said:

    @aquanight said:
    Of course, VB goes all fancy and calls it an "arithmetic shift" - as if there were any other kind of left shift. Though, technically a true arithmetic left shift would exactly emulate a * 2 ^ x. Which would mean x > SizeOf(pattern)*8 leaves the result 0. So this isn't really an arithmetic shift even though the docs say so.
    Wait, are you saying that instead of letting variables overflow, VB just sets the value to 0?

    Er, yeah, my bad: I must have somehow mixed VB in with the rest of the languages that treat overflow as a wrap-around. Although it still only makes sense to either leave it 0 or throw an exception, rather than modulus by the number of bits (leave it coder's responsibility to do Mod 8/16/32/64 on the shiftcount operand).



  • @DaveK said:

    I have a truly marvellous proof of this proposition, which this WTF is unfortunately too narrow to contain.

    Now THAT was funny! 


Log in to reply