C# Convert Hex string to byte - c#

Little bit stuck on this, I have a var called PORTBhex holding a value in the range 0x00 to 0x3F which is written to an external device via USB. The problem I am having is getting the value into this bit of code:
public bool PORTBwrite()
{
Byte[] outputBuffer = new Byte[65];
outputBuffer[0] = 0;
outputBuffer[1] = 0x00; //Command tells PIC18F4550 we want to write a byte
outputBuffer[0] = 0;
//Must be set to 0
outputBuffer[2] = IO.PORTBhex;
//Hex value 0x00 - 0x3F to write to PORTB
//above line gives the error cannot implicity convert string - byte
//IO.PORTBhex is returned from the code in second snippet
if (writeRawReportToDevice(outputBuffer))
{
return true; //command completed OK
}else{
return false; //command failed .... error stuff goes here
}
}
Now the problem is the value i have is an integer that is converted to hex using:
public static string ToHex(this int value)
{
return string.Format("0x{0:X}", value);
}
The value starts off as an integer and is converted to hex however I cannot use the converted value as its of the wrong type I am getting Cannot implicitly convert type 'string' to 'byte'.
Any idea what I can do to get around this please?
Thanks
EDIT:
I think I might have poorly described what I'm trying to achieve, I have an int variable holding a value in the range 0-255 which I have to convert to Hex which must be formatted to be in the range 0x00 to 0xFF and then set outputBuffer[2] to that value to send to the microcontroller.
The integer var has some maths performed on it before it needs to be converted so i cannot solely use byte vars and has to be converted to a hex byte afterwards.
Thanks

To solution is to change PORTBhex to be of type byte and don't use that ToHex method at all:
Instead of IO.PORTBhex = ToHex(yourIntValue) use this:
IO.PORTBhex = checked((byte)yourIntValue);
It would be even better if you could make yourIntValue to be of type byte, too.

outputBuffer[2] = Convert.ToByte(IO.PORTBhex, 16);
Although personally I'd probably try to avoid strings here in the first place, and just store the byte

Related

How to Convert from byte? to byte[]?

I am trying to convert a byte received from a database query.
EF Core returns nullable tinyint as byte? and I need to convert it to decimal.
Is there any way to convert it OnModelCreating with model builder in the DbContext?
I am not very familiar with EF Core. So far I only managed to do this - after I already got my object in handler:
decimal? newDecimal = Convert.ToDecimal(BitConverter.ToDouble(AddByteToArray(priceByte), 0)));
private static byte[] AddByteToArray(byte? newByte)
{
if (newByte != null)
{
if(newByte == 0)
{
return Enumerable.Repeat((byte)0x0, 8).ToArray();
}
byte[] bArray = new byte[1];
// Not sure how to convert a non null and byte > 0 to byte[]?? As double requires byte[] while the tinyint return byte from the database
return bArray;
}
return null;
}
I think you are getting a little confused by the types here. The DB returns a byte? for a tinyint because a tinyint has only 8 bits of data. But otherwise it is an integer. If you want to convert it to a decimal, you would use the same mechanism as you would to convert an int or a long to a decimal: cast it. You do not want to convert a byte array to a decimal as that will try to interpret the data in the array as a binary representation of a decimal (see my last paragraph). So this code should suffice to do the conversion.
decimal? d = newByte == null ? null : (decimal)newByte;
See that such a conversion is possible here: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions
Note the remarks section here that indicates we are dealing with a binary representation of the number, where care must be taken in dealing with endianness, etc.
https://learn.microsoft.com/en-us/dotnet/api/system.bitconverter?view=net-6.0#remarks
Basically, numbers larger than a byte are technically stored as an array of bytes (since all memory is byte addressable in x86) but the interpration of those bytes into a number depends on the type of the number. For floating point numbers especially the structure of data inside the byte array is complex, broken into fields that represent the base, exponent and sign. And those are not always interpreted in a straightforward way. If you just give a byte array with 27 as the first byte, you don't know where that ends up in the several fields that make up the binary representation of a double. It may well work, but probably not.
Instead of
byte[] bArray = new byte[1];
You can use
byte[] bArray = {(byte)newByte};

A letter in a byte? C#

I have an imported C++ method that receives a byte parameter, but according to the documentation, I can send a letter to that parameter, this is the C++ and C# method:
int WINAPI Sys_InitType(HID_DEVICE device, BYTE type)
public static extern int Sys_InitType(IntPtr device, byte type);
This causes me a syntax error in C#, how do I send a letter in that parameter?
My code (A bit random):
//CRASHES
byte random = Convert.ToByte("A");
_ = RFIDReader.Sys_SetAntenna(g_hDevice, 0);
int lol = RFIDReader.Sys_InitType(g_hDevice, random);
_ = RFIDReader.Sys_SetAntenna(g_hDevice, 1);
CError.Text = lol.ToString();
Convert.ToByte(string); doesn't do what you think it does, according to the documentation
Converts the specified string representation of a number to an equivalent 8-bit unsigned integer.
This would work byte random = Conver.ToByte("52"); which will return the byte 52.
See here:
https://learn.microsoft.com/en-us/dotnet/api/system.convert.tobyte?view=net-6.0#system-convert-tobyte(system-string)
As was pointed out in the comment already, you will have to use character instead of string, so either this
byte random = Convert.ToByte('A');
or a simple cast to byte
byte random = (byte)'A'
In case it is unknown to you, which I didn't assume, a byte can only contain values of the range 0 - 255, while a character can contain everything within the specs of UTF-16.
So this will not work
byte random = Convert.ToByte('\u4542');
And result in the error:
Value was either too large or too small for an unsigned byte.
https://dotnetfiddle.net/anjxt5

converting byte to string and back again

I have a Byte from my database, stored as 0-254
i can convert it from a Byte to string using
byteVal.ToString() //0 return 0 20 returns 20
but to then return it back to a Byte I cannot figure out.
Similar to other number-types you need the appropriate Parse-method, in this case Byte.Parse:
Byte b = Byte.Parse("20");
If you don't know if the format is valid you can use Byte.TryParse:
Byte b;
if(!Byte.TryParse("256", out b))
Console.WriteLine("Not a valid byte");
You can use the Convert.ToByte overload which converts string to a byte

Byte to integer in C#

I am reading a row from a SQL Server table. One of the columns is of type tinyint.
I want to get the value into an int or int32 variable.
rdr.GetByte(j)
(byte) rdr.GetValue(j)
...seems to be the only way to retrieve the value. But how do I get the result into an int variable?
int value = rdr.GetByte(j);
An explicit cast is not required, because a byte to int is a widening conversion (no possibility of data loss).
See the documentation for BitConverter.ToInt32 (contains more examples):
byte[] bytes = { 0, 0, 0, 25 };
// If the system architecture is little-endian (that is, little end first),
// reverse the byte array.
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
int i = BitConverter.ToInt32(bytes, 0);
Console.WriteLine("int: {0}", i);
// Output: int: 25
Assigning a byte to an int works:
int myInt = myByte;
But maybe you're getting an exception inside IDataRecord.GetByte, in which case you should check that the index you're using to access the data record really points to a tinyint column. You can check the type returned from GetValue. It should be a byte for a tinyint column.
Trace.Assert(rdr.GetValue(j).GetType() == typeof(byte));
Another option is to forego the fragile numeric index altogether:
int myInt = rdr.GetByte(rdr.GetOrdinal(TheNameOfTheTinyintColumn))
(int)rdr.GetByte(j)
Casting the byte to int should work just fine:
int myInt = (int) rdr.GetByte(j);
Since C# supports implicit conversions from byte to int, you can alternatively just do this:
int myInt = rdr.GetByte(j);
Which one you choose is a matter of preference (whether you want to document the fact that a cast is taking place or not). Note that you will need the explicit cast if you want to use type inference, or otherwise myInt will have the wrong type:
var myInt = (int) rdr.GetByte(j);
Quick tidbit I ran into as a kind of corner case. If you have an object type that is of type System.Byte, you can not directly cast to int. You must first cast to a byte, then cast to an int.
public int Method(object myByte)
{
// will throw a cast exception
// var val = (int)myInt;
// will not throw a cast exception
var val = (int)((byte)myInt)
return val;
}
Method((byte)1);
This is similar to Stephen Cleary's comment on the accepted answer, however I am required to specify the size of the int. This worked for me:
int value = Convert.ToInt32(rdr.GetValue(j));
(And it also provided backward compatibility with a database column using an int.)

C#: Convert a UInt16 in string format into an integer(decimal)

Here's the problem.
I ,for example,have a string "2500".Its converted from byte array into string.I have to convert it to decimal(int).
This is what I should get:
string : "2500"
byte[] : {0x25, 0x00}
UInt16 : 0x0025 //note its reversed
int : 43 //decimal of 0x0025
How do I do that?
Converting from hex string to UInt16 is UInt16.Parse(s, NumberStyles.AllowHexSpecifier).
You'll need to write some code to do the "reversal in two-digit blocks" though. If you have control over the code that generates the string from the byte array, a convenient way to do this would be to build the string in reverse, e.g. by traversing the array from length - 1 down to 0 instead of in the normal upward direction. Alternatively, assuming that you know it's exactly a 4 character string, s = s.Substring(2, 2) + s.Substring(0, 2) would do the trick.
It might be better to explicitly specify what base you want with Convert.ToUInt16.
Then, you can flip it around with IPAddress.HostToNetworkOrder (though you'll have to cast it to an int16, then cast the result back to a uint16.
there is a special class for conversion : Convert
to convert from string to uint16 use the following method: Convert.ToUInt16
for difference on int.parse and Convert.ToInt32 is explained in this page
and the msdn site for Convert.ToUInt16 here
Assuming your string is always 4 digits long.
You can get away with one string variable but I'm using multiple ones for readability.
string originalValue = "2500";
string reverseValue = originalValue.Substring(2, 2) + originalValue.Substring(0, 2);
string hexValue = Convert.ToUInt16(reverseValue, 16).ToString();
int result = Convert.ToInt32(hexValue, 10);

Categories

Resources