[RESOLVED] Unsigned to signed conversion problem
Hi, It seems silly with these posts count to ask such thing, I'm feeling a bit nervous and ashamed but let me ask it anyway:
Consider two unsigned bytes and the goal is to make them a signed short (or any other signed large capable number I found short type suitable for this purpose)
In another meaning a 0 to 65535 turn into -32768 to +32767. I just want to shift the whole range into signed limits. Positives stay the same but for more than half represents negative values. Sort of "Word" data type behavior on Windows built in calculator.
When I do this
Code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text = CShort(CByte(NumericUpDown1.Value) * 256 + CByte(NumericUpDown2.Value))
End Sub
It works for half of the range (&H7FFF or +32767) but from &H8000 to &HFFFF it fails and unhandled exception says that: System.OverflowException: 'Arithmetic operation resulted in an overflow.'
CInt, CLng and others were also tested, same results.
Re: Unsigned to signed conversion problem
You should look at the BitConverter class. I would imagine that the ToInt16 method is what you want. Keep in mind that signed data types store the sign in one bit, so one of your Bytes will include that bit. You should use the Bitconverter class to convert various values to Bytes and see the result, then work out what exactly you need to do to go the other way.
Re: Unsigned to signed conversion problem
No idea about dot NET, but i would look for something called "Union Structures" like in C or Pascal
Something like here: https://stackoverflow.com/questions/...rflowexception
Re: Unsigned to signed conversion problem
Quote:
Originally Posted by
jmcilhinney
You should use the Bitconverter class to convert various values to Bytes and see the result, then work out what exactly you need to do to go the other way.
The dictation format (By MS) is like
Code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text = BitConverter.ToString(BitConverter.GetBytes(CByte(NumericUpDown1.Value) * 256 + CByte(NumericUpDown2.Value)))
End Sub
You mean this way? Which in my case it returns 4 discrete bytes (by dashes), to be honest I panic at first sight...
Quote:
Originally Posted by
Zvoni
"Union Structures" like in C or Pascal Something like here:[/url]
Thanks for the link. In C we were used to do just (signed int)((HighByte * 256) + LowByte) . Ranges shrink or expand as you command. I thought it was as easy as C.
Re: Unsigned to signed conversion problem
Quote:
Originally Posted by
pourkascheff
The dictation format (By MS) is like
Code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text = BitConverter.ToString(BitConverter.GetBytes(CByte(NumericUpDown1.Value) * 256 + CByte(NumericUpDown2.Value)))
End Sub
You mean this way? Which in my case it returns 4 discrete bytes (by dashes), to be honest I panic at first sight...
Thanks for the link. In C we were used to do just
(signed int)((HighByte * 256) + LowByte) . Ranges shrink or expand as you command. I thought it was as easy as C.
would something like
Code:
Sub Main(args As String())
Dim bytes(1) As Byte
b1 = 100
b2 = 200
Dim res = b1 * 256 + b2
End Sub
not be suitable? Seemed to work for me, I wonder if your error was down to the precedence of casting by doing it in one single line....
Re: Unsigned to signed conversion problem
Quote:
Originally Posted by
PlausiblyDamp
Seemed to work for me
In your example combination of b1 (100) and b2 (200) will never reach short's half (25800 not even close to 32767).
Try 255 and 255 and instead of 65535 we expect that achieve -1. (Or try other negative values based on your calculator)
I wasn't following the "write them down on separate lines" paragraph.
If you mean
Code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim HIGHBYTE As Byte = 255
Dim LOWBYTE As Byte = 255
TextBox1.Text = CShort((HIGHBYTE * 256) + LOWBYTE)
End Sub
I've tried it. Same exception occurs.
Re: Unsigned to signed conversion problem
It is an emergency case (We didn't considered negative values for a simple measuring device) and now we want to have/support it as an update and thought it is not a big deal (Maybe a data or type conversion or two with built-in easy access functions) but now I am facing a give up scenario.
Re: Unsigned to signed conversion problem
Quote:
Originally Posted by
pourkascheff
It is an emergency case (We didn't considered negative values for a simple measuring device) and now we want to have/support it as an update and thought it is not a big deal (Maybe a data or type conversion or two with built-in easy access functions) but now I am facing a give up scenario.
VB does have an option in the project properties "Remove Integer Overflow Checks" that would solve this, although as it is a project wide setting it could introduce bugs in other areas of your app. Shame VB doesn't have C# "unchecked" and "checked" keywords to give finer control over these things.
Re: Unsigned to signed conversion problem
Well, you could always go the "old-school" way (as it was in VB6), and CopyMemory it over:
Create a Structure for your bytes:
e.g.
Code:
Private Type UDTMyBytes
LowByte As Byte
HiByte As Byte
End Type
dim by As UDTMyBytes
Dim res As Integer '2-Bytes signed integer
.
.
by.LowByte = 255
by.HiByte = 255
CopyMemory res, by, 2 'Declaration of CopyMemory is ByRef. If ByVal use VarPtr
I don't remember the order of the Bytes. Might be the other way round
But as always with CopyMemory: All gloves are off
Re: Unsigned to signed conversion problem
Quote:
Originally Posted by
PlausiblyDamp
"Remove Integer Overflow Checks"
Mate! It worked...:ehh: However it may cause me severe heart attacks in the future since it affects all arithmetics/conversions in project but, Now it returns correct negative values as expected. Thank you so much, didn't know there is a option for that (Still don't know how overflow is related to not IEEE 754 (float) but 4 bytes negative numbering standard).
One last question: I'm using VS2019Ent. but on projects workstation (isn't available for now) it runs VS2012. Does this specific version cover the "Remove Integer Overflow Checks" in same location (Advanced compile options)? This is not the first time I've being lost in VS setting not because of displacement but in excluding and not supporting a feature anymore.
Thanks all again for contribution because of making me hopeful <3
Re: Unsigned to signed conversion problem
Quote:
Originally Posted by
Zvoni
you could always go the "old-school" way
I'm a 90's guy, I'm familiar to oldschool things but I guess I stick to that way.
Do you think this thread is useful and related to my subject? Since it is not marked as resolved, I didn't spend enough time on it. It would be justified manner to restrict this tricky overflow bypass thing on specific part or small partial code.
Update: I guess I figured why it is called overflow. Consider VS as a human being. Less than -32,768 for instance -40,000 is lesser (still overflow) than boundaries therefore it throws an exception, meaning that "I didn't understand what are you talking about. It makes no sense to me". But when we toggle its condition, we want to use the identical shadow of this number from the other side (+25,536 for invalid -40,000 (Both represented as &H63C0)) Does my sophistries and fallacies right so far?
Re: Unsigned to signed conversion problem
Quote:
Originally Posted by
pourkascheff
I'm a 90's guy, I'm familiar to oldschool things but I guess I stick to that way.
Do you think
this thread is useful and related to my subject? Since it is not marked as resolved, I didn't spend enough time on it. It would be justified manner to restrict this tricky overflow bypass thing on specific part or small partial code.
Update: I guess I figured why it is called overflow. Consider VS as a human being. Less than -32,768 for instance -40,000 is lesser (still overflow) than boundaries therefore it throws an exception, meaning that "I didn't understand what are you talking about. It makes no sense to me". But when we toggle its condition, we want to use the identical shadow of this number from the other side (+25,536 for invalid -40,000 (Both represented as &H63C0)) Does my sophistries and fallacies right so far?
Where's the "-40000" coming from?
Your initial inquiry was converting unsigned bytes to signed Short/2-Byte Integer.
"-40000" as is will never fit into a 2-Byte signed integer
Re: Unsigned to signed conversion problem
Quote:
Originally Posted by
Zvoni
Where's the "-40000" coming from?
I said as an invalid or overflew (from other direction) or even a non-possible number. Relax... It still may return a valid converted value (from other side) if remove overflow option is checked, aye?
Re: Unsigned to signed conversion problem
Quote:
Originally Posted by
pourkascheff
I'm a 90's guy, I'm familiar to oldschool things but I guess I stick to that way.
Do you think
this thread is useful and related to my subject? Since it is not marked as resolved, I didn't spend enough time on it. It would be justified manner to restrict this tricky overflow bypass thing on specific part or small partial code.
Update: I guess I figured why it is called overflow. Consider VS as a human being. Less than -32,768 for instance -40,000 is lesser (still overflow) than boundaries therefore it throws an exception, meaning that "I didn't understand what are you talking about. It makes no sense to me". But when we toggle its condition, we want to use the identical shadow of this number from the other side (+25,536 for invalid -40,000 (Both represented as &H63C0)) Does my sophistries and fallacies right so far?
An OverflowException is thrown whenever you try to assign a value that is outside of the acceptable range of values that a variable type can contain. That means going greater then the Maximum value, or less than the minimum value.
The thread you linked to is for VB6, so although the underlying problem is the same, I don't think the solution would be relevant for VB.Net. The annoying thing is that C# addresses this issue directly in the language itself instead of only at the project compilation level.
Re: Unsigned to signed conversion problem
Quote:
Originally Posted by
PlausiblyDamp
An OverflowException is thrown whenever you try to assign a value that is outside of the acceptable range of values that a variable type can contain. That means going greater then the Maximum value, or less than the minimum value.
The thread you linked to is for VB6, so although the underlying problem is the same, I don't think the solution would be relevant for VB.Net. The annoying thing is that C# addresses this issue directly in the language itself instead of only at the project compilation level.
That pretty much leaves my two approaches above:
1) the analogy of a union struct (from C)
2) CopyMemory-Hack
Re: Unsigned to signed conversion problem
Quote:
Originally Posted by
Zvoni
That pretty much leaves my two approaches above:
1) the analogy of a union struct (from C)
2) CopyMemory-Hack
In which case
Code:
Imports System.Runtime.InteropServices
Module Program
Sub Main(args As String())
Dim b1 As Byte = 255
Dim b2 As Byte = 255
Dim b As DemoConvert
b.UShortVal = (b1 * 256) + b2
Dim res = b.ShortVal
End Sub
<StructLayout(LayoutKind.Explicit)>
Structure DemoConvert
<FieldOffset(0)> Public ShortVal As Short
<FieldOffset(0)> Public UShortVal As UShort
End Structure
End Module
would be the equivalent of the union struct, I would definitely prefer it to CopyMemory if I was using .Net, not sure how I feel about it compared to disabling overflow checks as I don't really like either and just wish VB had C#'s flexibility on this one.
Re: Unsigned to signed conversion problem
Quote:
Originally Posted by
pourkascheff
Hi, It seems silly with these posts count to ask such thing, I'm feeling a bit nervous and ashamed but let me ask it anyway:
Consider two unsigned bytes and the goal is to make them a signed short (or any other signed large capable number I found short type suitable for this purpose)
In another meaning a 0 to 65535 turn into -32768 to +32767. I just want to shift the whole range into signed limits. Positives stay the same but for more than half represents negative values. Sort of "Word" data type behavior on Windows built in calculator.
When I do this
Code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text = CShort(CByte(NumericUpDown1.Value) * 256 + CByte(NumericUpDown2.Value))
End Sub
It works for half of the range (&H7FFF or +32767) but from &H8000 to &HFFFF it fails and unhandled exception says that: System.OverflowException: 'Arithmetic operation resulted in an overflow.'
CInt, CLng and others were also tested, same results.
Quote:
Originally Posted by
jmcilhinney
You should look at the BitConverter class. I would imagine that the ToInt16 method is what you want. Keep in mind that signed data types store the sign in one bit, so one of your Bytes will include that bit. You should use the Bitconverter class to convert various values to Bytes and see the result, then work out what exactly you need to do to go the other way.
What John said...
Code:
Dim byts() As Byte = {1, 0} 'note that byts(0) is least significant
Dim foo As Short
For x As Integer = 1 To 255
foo = BitConverter.ToInt16(byts, 0)
Debug.WriteLine(foo.ToString("N0"))
byts(1) = CByte(x)
Next