anton
New Member
Posts: 9
|
Post by anton on Feb 2, 2023 2:04:51 GMT -5
Hi all. I need to find a way to change a signed integer to an unsigned integer. Could anyone help me. There has to be a way. I have found online converters that will do that but I have to be able to do it in my program. Thanks
|
|
|
Post by tsh73 on Feb 2, 2023 2:34:33 GMT -5
some examples would help Obviously if you drop sign you'll get it unsigned? Not that easy? So what and what for you are trying to do?
in LB, integers are virtually unlimited, and signed
You probably need work with some binary form? say 2 bytes signed to 2 bytes unsigned? What should happen with negative values?
|
|
|
Post by Rod on Feb 2, 2023 2:55:09 GMT -5
Signed and unsigned is really just an interpretation. The actual bytes don’t change. Take a very basic example, one byte. It is a number between 0 and 255. Unsigned it produces values between 0 and 255 , easy. A signed interpretation give numbers in the range -127 to 127. The positive set are simply the numbers between 0 and 127 the negative set are interpreted when the number exceeds 128 and the top bit is set. So numbers in the range 128 to 255 represent -1 to -127
But as Anatoly states give us a working example of what you are trying to convert.
|
|
anton
New Member
Posts: 9
|
Post by anton on Feb 2, 2023 16:20:26 GMT -5
I am using Dan Teels LBGfx.dll which creates a graphicbox over top LB's graphicbox. So I have a graphicbox with a range of 100,000 pixels. When I click on the graphicbox at the upper end, MouseX becomes a negative number. Online I found a converter that when you enter the negative number and change it to a unsigned number it provides the correct number. I need to be able to do this in my program. For instance the signed number -34750 becomes 93622 which is the correct number I need.
|
|
|
Post by tsh73 on Feb 2, 2023 16:24:54 GMT -5
Here's a function what does two's complement for a numbers according to wikipedia en.wikipedia.org/wiki/Two%27s_complementbitWidth 8 maxN 256 n 6 6 00000110 minusN 250 6 00000110 reverts back to 6 6 00000110 (n+minusN) is 0 0 00000000 'Two's complement 'https://en.wikipedia.org/wiki/Two%27s_complement
bitWidth = 8 maxN=2^bitWidth
print "bitWidth ";bitWidth print "maxN ";maxN
n = 6 print "n ";n print n, dec2bin$(n, bitWidth)
minusN=twoComplement(n, bitWidth) print "minusN ";minusN print n, dec2bin$(n, bitWidth)
n = twoComplement(minusN, bitWidth) 'reverts back print "reverts back to ";n print n, dec2bin$(n, bitWidth)
'test (n+fixedMinusN) is 0 res = (minusN +n) mod maxN print "(n+minusN) is ";res print res, dec2bin$(res, bitWidth)
function twoComplement(n, bitWidth) maxN=2^bitWidth flip=n xor (maxN-1) twoComplement=(flip+1) mod maxN end function
'------------------------------------------------------ '-- Aux function dec2bin$(n, l) s$="" while n bit = n mod 2 s$=mid$("01", bit+1,1)+s$ n = int(n/2) wend ' dec2bin$ =s$ dec2bin$ =right$( "0000000000000000000000000000000000000000000000000000000000000000"+s$, l) end function
function bin2dec(bin$) res = 0 while bin$<>"" res = res*2 bit$=left$(bin$,1) bin$ = mid$(bin$, 2) if bit$ = "1" then res = res+1 wend bin2dec =res end function
|
|
|
Post by tsh73 on Feb 2, 2023 16:41:11 GMT -5
Numbers -34750 and 93622 doesn't make sense for me it is over 2^15, 2^16 which is natural bounds in such cases So what happened?
found the calculator onlinetoolz.net/unsigned-signed#base=10&value=-34750&bits=17it says 17 bits (and "93622" indeed does not make sense - right one is "96322") 'calculator says 17 bit 'https://onlinetoolz.net/unsigned-signed#base=10&value=-34750&bits=17 '-34750 '10111100001000010 DECIMAL 17-BIT 'unsigned 96322 'signed -34750 print twoComplement(34750, 17)
so twoComplement(abs(-34750), 17) should be it. But still 2^17 feels really really weird. Someone's idea of "will be always enough"?
|
|
|
Post by Walt Decker on Feb 4, 2023 18:09:17 GMT -5
Easy way:
ThisVarb = -31416 ThisVarb = ABS(ThisVarb)
If the variable is not negative its value will not change
|
|
|
Post by Brandon Parker on Feb 5, 2023 8:56:07 GMT -5
Easy way: ThisVarb = -31416 ThisVarb = ABS(ThisVarb) If the variable is not negative its value will not change While that works as shown, it will not provide what the OP is looking for. Using ABS() in LB only negates a negative number. When a number exceeds a signed variable's size, it will wrap around and start at the lowest negative value storable and work up from there. Since there is actually a difference between the binary stores of data types that are the same size but signed vs. unsigned (i.e. one bit is designated for the sign) and the OP appears to be talking about the return value from an API call, the conversion has to be performed if the return data type is correct. For instance: The short data type is a 16-bit signed two's complement integer. It has a minimum value of -32,768 and a maximum value of 32,767 (inclusive) If you try to store 32,769 (two higher than the max allowable limit) in the short, it will work, but the value that the computer will give you back will be -32,767. For twos complement, you can get the expected value like this very easily: 'First, let me say that we should be choosing data types of correct size 'for the things that we intend to store in them. 'That being said, sometimes we run into issues with external libraries 'where we overrun their data types, so we have to just deal with it.
'Let's make a short data type in a Struct since LB will respect it's min/max size 'and we can see how it actually gets stored Struct myStruct, value As short
'Let's store 32769 into the short data type myStruct.value.struct = 32769
'We can see that the value returned is -32767 'This is caused by the binary number having the most significant 'bit reserved for the sign 'When we overrun the max value we wrap back around to the 'negative-most value Print myStruct.value.struct
'Let's return the value that we intended to store Print signedShortToValue(myStruct.value.struct) Wait
Function signedShortToValue(signedShortToValue) If (signedShortToValue >= 0) Then Exit Function minStorableValue = -32768 maxStorableValue = 32767 signedShortToValue = (maxStorableValue + Abs(minStorableValue) + signedShortToValue + 1) End Function {:0) Brandon Parker
|
|
|
Post by tsh73 on Feb 5, 2023 13:14:05 GMT -5
Brandon,
pasting OP "-34750" in your code returns "96322" Obviously both numbers are outside of "signed int16" range. I don't mind that is works but - how it works at all?
probably your code works for special cases 'cause results for 1..32767 looks really off for me(>2^16-1, outside unsigned int range)
a = 0 while a<>1e6 'magic value read a myStruct.value.struct = a Print a, myStruct.value.struct, signedShortToValue(myStruct.value.struct) wend
data 0, 1, -1, 127, -127, 128, -128, data 10000, 20000, 30000 data 32766, -32766, data 32767, -32767, data 32768, -32768, data 32769, -34750, 96322, 1e6
0 0 65536 1 1 65537 -1 -1 65535 127 127 65663 -127 -127 65409 128 128 65664 -128 -128 65408 10000 10000 75536 20000 20000 85536 30000 30000 95536 32766 32766 98302 -32766 -32766 32770 32767 32767 98303 -32767 -32767 32769 32768 -32768 32768 -32768 -32768 32768 32769 -32767 32769 -34750 30786 96322
'and last one 96322 produces Runtime error: anInteger2 must be between -32768 and +32767
|
|
|
Post by danteel on Feb 5, 2023 18:43:40 GMT -5
When windows sends a mouse move/click event to a window, both the x and y are passed in a single DWORD (32 bit) parameter, so each X/Y is only allotted 16 bits, hence the range you're seeing, I'm not sure it will meet the intent of 100,000 considering it should only go up to 65,535 before it overflows if interpreted as an unsigned. My program receives the coordinates in a DWORD (word for each), x and y each gets converted to an int from a WORD, the scrollbar position gets added, and the its converted back to a DWORD (so a word again for each). learn.microsoft.com/en-us/windows/win32/learnwin32/mouse-movement
|
|
|
Post by Brandon Parker on Feb 5, 2023 20:08:59 GMT -5
Anatoly, I would just like to point out that -34750 is outside the valid range for a Short data type which my example was based on. Also, the function should only be called when a negative value is returned by a signed data type when you know for sure a positive value should be returned. I did not go looking to see what type the function in the DLL was using, but that trick can be used with any type; one just has to set up a function correctly. The trick is for converting a value that is returned as a signed data type to the corresponding unsigned data type.
One would have to consider each data type when doing what I was showing above.
{:0)
Brandon Parker
|
|
|
Post by Rod on Feb 6, 2023 8:38:30 GMT -5
So the mouse x y are ushort values wrapped into a word. They are not signed so have the range 0- 65535 So x=100000 is well outside the capabilities of the mouse hardware, so another strategy?
|
|