Using plus equals operator with bytes - kotlin

The code below gives me the following error.
Error: Type mismatch: inferred type is kotlin.Int but kotlin.Byte was expected
var temp: Byte = 0
var temp2: Byte = 1
temp += temp2
Is there any way around this in kotlin or am I not allowed to use the += or -= operators with Byte? Is plus equals overloaded for Long and Int but not Byte and Short?

According to kotlin docs Byte's plus/minus operations with other Byte will result in an Int. So while you think it is weird try to add Byte with value of 255 to other Byte with calue of 255 ;)
I think they made it on purpose. If you are certain that your result is still within Byte bounds then just use Int.toByte() and the end of the calculations.

Related

How to read 8-byte integers in GMS 2.x?

I need to read 8-byte integers from a stream. I could not find any documentation how to read 8-byte integers in DM. It would be something similar to a long long integer.
Is there a trick how to stream 8-byte integers from file in GMS 2.x ?
We can use the "Stream" object to read/import data of various kinds. Please refer to the DM Help > Scripting > File Input and Output:
Other examples can also be found at DM-Script-Database :
Read-Ser (http://donation.tugraz.at/dm/source_codes/127)
JEMS_.ems file reader (http://donation.tugraz.at/dm/source_codes/108)
Hope this helps.
I used the following (stupid) method to do so:
number readint32(object s){
number stream_byte_order=2
number result=0
TagGroup tg = NewTagGroup();
tg.TagGroupSetTagAsLong( "SInt32_0", 0 )
TagGroupReadTagDataFromStream( tg, "SInt32_0", s, stream_byte_order );
tg.TagGroupGetTagAsLong( "SInt32_0", result)
return result
}
number readint64(object s){
//new for reading 8-byte integer in TIA ver >3.7
//DM automatic convert result to float when the second 4-byte >1
number result = readint32(s)+ (readint32(s)*4294967296)
// 4294967296 equals to 0xFFFFFFFF in hex form
return result
}
It works with reading ser <2GB, but does not for larger file. I still did not figure it out...
#09-04-2016
Now i got a solution to the data offset problem in ser:
Here is the solution:
Void b_readint64(object s, number &lo, number &hi){
//new for reading 8-byte (64bit) integer in TIA ver >3.7
//read the low and high section individually and later work
//together with StreamSetPos32singed, StreamSetPos64 funcsions
lo = b_readint32(s)
hi = b_readint32(s)
}
Void StreamSetPos32Signed(object s, number base, number lo){
if (lo>0) StreamSetPos(s, base, lo)
else StreamSetPos(s, base, 4294967296+lo)
}
Void StreamSetPos64(object s, number base, number lo, number hi){
if (hi!=0){
StreamSetPos(s, base, 0)
for (number i=0; i<hi; i++) StreamSetPos(s, 1, 4294967296)
StreamSetPos32Signed(s, 1, lo)
} else StreamSetPos32signed(s, base, lo)
}
BTW, I just uploaded this upgraded script to
http://portal.tugraz.at/portal/page/portal/felmi/DM-Script/DM-Script-Database
There is nothing like an 8-byte integer in DigitalMicrograph. You can use the streaming to read in two successive 4-byte sections as integers (See answer above) and then display them as binary using binary() or hexadecimal using hex(), but you will have to do the maths yourself for the "meaning" of the 8-byte integer (storing it as real-number). You can use the binary operators & | ^ for bitwise numeric, when needed.

Delphi Double to Objective C double

I am looking a few hours for some solution of this problem, but I don't get how it works. I have a hex string from delphi double value : 0X3FF0000000000000. That value should be 1.0. It is 8 byte long, first bit is sign, next 11 are exponent and the rest is mantissa. So for me is this hex value equals 0 x 10^(1023). Maybe I am wrong somewhere, but it doesn't matter. The point is, I need this hex value to convert into objective c double value. If I do: (double)strtoll(hexString.UTF8String, NULL,16); I get: 4.607...x 10 ^18. What am I doing wrong?
It seems that trying to cast in this way ends up with a call to an implicit type conversion (calls _ultod3 or _ltod3) that alters the underlying data. In fact, even trying to do this seems to do the same thing :
UINT64 temp1 = strtoull(hexString, NULL, 16);
double val = *&temp1;
But if you cast the uint pointer to a double* it semes to suppress the compiler's desire to try to perform a conversion. Something like this should work :
UINT64 temp1 = strtoull(hexString, NULL, 16);
double val = *(double*)&temp1;
At least this works with the MS C++ compiler... I imagine the objective C compiler would cooperate as well.

vb xor checksum

This question may already have been asked but nothing on SO actually gave me the answer I need.
I am trying to reverse engineer someone else's vb.NET code and I am stuck with what a Xor is doing here. Here is 1 line of the body of a soap request that gets parsed (some values have been obscured so the checksum may not work in this case):
<HD>CHANGEDTHIS01,W-A,0,7753.2018E,1122.6674N, 0.00,1,CID_V_01*3B</HD>
and this is the snippet of vb code that checks it
LastStar = strValues(CheckLoop).IndexOf("*")
StrLen = strValues(CheckLoop).Length
TransCheckSum = Val("&h" + strValues(CheckLoop).Substring(LastStar + 1, (StrLen - (LastStar + 1))))
CheckSum = 0
For CheckString = 0 To LastStar - 1
CheckSum = CheckSum Xor Asc(strValues(CheckLoop)(CheckString))
Next '
If CheckSum <> TransCheckSum Then
'error with the checksum
...
OK, I get it up to the For loop. I just need an explanation of what the Xor is doing and how that is used for the checksum.
Thanks.
PS: As a bonus, if anyone can provide a c# translation I would be most grateful.
Using Xor is a simple algorithm to calculate a checksum. The idea is the same as when calculating a parity bit, but there is eight bits calculated across the bytes. More advanced algorithms like CRC and MD5 are often used to calculate checksums for more demanding applications.
The C# code would look like this:
string value = strValues[checkLoop];
int lastStar = value.IndexOf("*");
int transCheckSum = Convert.ToByte(value.Substring(lastStar + 1, 2), 16);
int checkSum = 0;
for (int checkString = 4; checkString < lastStar; checkString++) {
checkSum ^= (int)value[checkString];
}
if (checkSum != transCheckSum) {
// error with the checksum
}
I made some adjustments to the code to accomodate the transformation to C#, and some things that makes sense. I declared the variables used, and used camel case rather than Pascal case for local variables. I use a local variable for the string, instead of getting it from the collection each time.
The VB Val method stops parsing when it finds a character that it doesn't recognise, so to use the framework methods I assumed that the length of the checksum is two characters, so that it can parse the string "3B" rather than "3B</HD>".
The loop starts at the fourth character, to skip the first "<HD>", which should logically not be part of the data that the checksum should be calculated for.
In C# you don't need the Asc function to get the character code, you can just cast the char to an int.
The code is basically getting the character values and doing a Xor in order to check the integrity, you have a very nice explanation of the operation in this page, in the Parity Check section : http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/xor.html

Converting a number larger than 255 into a byte variable

I understand the concept of bytes and declaring variables to save on processing space. I understand that the max value that can be stored in a byte is 255.
I cannot seem to wrap my head around my current issue and was hoping that someone would be able to educate me and help me solve this problem. I don't have much experience working with byte manipulation.
I was given a project to update and was told that the service that is passing data to my project would start using 2bytes to transfer the ID rather than the 1 byte previously as their parameters have grown.
The current declaration for the variable is:
Dim bytvariable As Byte = 0
What is the new declaration to accept a 2 byte value?
Secondly, how would I be able to convert that 2 byte value into an integer number?
Example, they are passing me this value: 0x138 and it is supposed to come out as 312.
Thank you in advance.
Here's a summary of the "primitive" datatypes in .NET, and their sizes.
Yes, an Int16 is probably what you want.
Often you'd be reading the binary data from a stream, or getting it from an array of bytes.
To convert from those sources into an Int16, you can do this:
in C#:
byte[] block = new byte[128];
mystream.Read(block, 0, block.Length);
int i = 0;
Int16 value = (Int16)(block[i++] + block[i++] * 256);
In VB.NET, it would be:
Dim block as New Byte(128)
stream.Read(block, 0, block.Length)
Dim i as Int16 = 0
Dim value As Short = CShort((block(i) + (buffer(i+1) * &H100)))
i = i + 2
(I think)
from the top of my head I'd suggest if you insist on doing it that way (instead of just passing an integer), you could use an array of byte, first index holding the first number and the second index the second ex. byte[0] = 123, byte[1] = 255;
then combine them into a string ex. string concatenatedNumber = byte[0].ToString() + byte[1].ToString(); then parse it ex. int ID = Int32.Parse(concatenatedNumber);
Examples are in C#, but I think you should get the idea. I would definitely rather just pass it as an integer though.
You could try this:
Dim bytvariable As Byte(0 To 1)
bytvariable(0) = ' Get the first byte however they are sending it
bytvariable(1) = ' Get the second byte however they are sending it
Dim value As Int16 = BitConverter.ToInt16(buffer, 0);

How can I do a bitwise-AND operation in VB.NET?

I want to perform a bitwise-AND operation in VB.NET, taking a Short (16-bit) variable and ANDing it with '0000000011111111' (thereby retaining only the least-significant byte / 8 least-significant bits).
How can I do it?
0000000011111111 represented as a VB hex literal is &HFF (or &H00FF if you want to be explicit), and the ordinary AND operator is actually a bitwise operator. So to mask off the top byte of a Short you'd write:
shortVal = shortVal AND &HFF
For more creative ways of getting a binary constant into VB, see: VB.NET Assigning a binary constant
Use the And operator, and write the literal in hexadecimal (easy conversion from binary):
theShort = theShort And &h00ff
If what you are actually trying to do is to divide the short into bytes, there is a built in method for that:
Dim bytes As Byte() = BitConverter.GetBytes(theShort)
Now you have an array with two bytes.
result = YourVar AND cshort('0000000011111111')