My program currently loads a csv file and converts each line to different strings and int values. The problem is, while I can easily convert a simple number, it needs to be able to convert an equation with variables.
My current code for this is -
string[] values = line.Split(new string[] { "," }, StringSplitOptions.None)
.Select(p => p.Trim()).ToArray();
if (values.Length != 8) continue;
var species = new SpeciesClasses()
{
Species = values[0],
Description= values[1],
Strength = int.Parse(values[2]),
Intelligence = int.Parse(values[3]),
Dexerity = int.Parse(values[4]),
Charisma = int.Parse(values[5]),
Endurance = int.Parse(values[6]),
Initiative = int.Parse(values[7]),
};
And my csv file is
Pilot, Trained to handle all vehicle types., 0, 6, 0, 0, 0, 0
Medic, Trained to cure and heal others., 0, 0, 5, 0, 0, 0
Which works fine, now the tricky part is a line like this -
Berzerker, The closer to death this crew gets - the stronger they hit., (15-HP)/4, 0, 0, 0, 0, 0
Focused, Using their mass intellect - this crew can aim more accurately., 0, 0, INTEL, 0, 0, 0
So I not only need to convert the string to an int equation with different variables - in this case an HP and INTEL int.
If int.Parse() fails (btw try int.TryParse(...)) fallback to a more specialized tool:
More info here:
Equation (expression) parser with precedence?
Related
I am trying to convert an array of int values (each value representing a bit) to its representation as an Int32 object.
I have the following code:
//0000_0000_0000_0000_0000_0000_0000_1111 = 15
int[] numberData = new int[]
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 1
};
//We convert our int[] to a bool[]
bool[] numberBits = numberData.Select(s => { return s == 0 ? false : true; }).ToArray();
//We generate a bit array from our bool[]
BitArray bits = new BitArray(numberBits);
//We copy all our bits to a byte[]
byte[] numberBytes = new byte[sizeof(int)];
bits.CopyTo(numberBytes, 0);
//We convert our byte[] to an int
int number = BitConverter.ToInt32(numberBytes, 0);
However, after executing this code, the value of number is -268435456.
Why does this happen?
The bit order is incorrect. -268435456 as a 32-bit integer is 11110000 00000000 00000000 00000000, which, as you can see, is exactly opposite what you wanted.
Just reverse your numberBits array before converting it to an Int32.
Alternatively, you could make numberData have the correct order and then never do any reversing.
Your code is working exactly how you wrote it. In numberData[0] is 0, numberData[1] is 0, ..., and numberData[31] is 1. This will cause bit 0 of your result to be 0, bit 1 to be 0, ..., and bit 31 to be 1.
EDIT:
After fixing the syntax error and working with this algorithm I found the MKL provider is not the matrix multiplication needed. This algorithm simply multiplies element by element and does not compute the dot(row_n,column_n) as I had originally thought.
other source
End Edit
I can't get this passed the compiler. I have looked all over for a good example but have come up short. The documentation I'm referencing is MklLinearAlgebraProvider
MathNet.Numerics.Algorithms.LinearAlgebra.Mkl.MklLinearAlgebraProvider
I'm trying to write a simple method to compute the rotation matrix R = rz*ry*rx from Euler angles. The problem is the compiler won't take ryXrx or resultMat arrays I'm trying to pass it. I've tried out keyword as well.
inputMat is a 1-D array of the form {x,y,z,rx,ry,rz} where x,y and z are translations and rx,ry and rz are rotation angles in degrees.
private float[,] EulerToHMat(float[] inputMat)
{
var linalg = new MathNet.Numerics.Algorithms.LinearAlgebra.Mkl.MklLinearAlgebraProvider();
double rzRad = ((double)inputMat[5])*Math.PI/180;
double cosZ = Math.Cos(rzRad);
double sinZ = Math.Sin(rzRad);
double ryRad = ((double)inputMat[4])*Math.PI/180;
double cosY= Math.Cos(ryRad);
double sinY = Math.Sin(ryRad);
double rxRad = ((double)inputMat[3])*Math.PI/180;
double cosX= Math.Cos(rxRad);
double sinX = Math.Sin(rxRad);
var rz = new float[,] { { (float)cosZ, -(float)sinZ, 0 }, { (float)sinZ, (float)cosZ , 0 }, {0,0,1 } };
var ry = new float[,] { { (float)cosY , 0 , (float)sinY }, { 0, 1 , 0 }, { -(float)sinY, 0, (float)cosY } };
var rx = new float[,] { {1,0,0 }, {0,(float)cosX,-(float)sinX }, {0,(float)sinX,(float)cosX } };
var ryXrx = new float[3,3];
var resultMat = new float[3, 3];
// won't take the matrix --ryXrx-- here
linalg.MatrixMultiply(ry, 3, 3, rx, 3, 3,ryXrx);
// won't take the matrix --resultMat-- here
linalg.MatrixMultiply(rz, 3, 3, ryXrx, 3, 3,resultMat);
return resultMat;
}
This seems like it should be simple.... Please ignore the casting mess.
According to the reference you linked, the method works on matrices that are stored in a SINGLE-dimensional array, you are trying to pass two-dimensionals.
Try this:
var rz = new float[] { (float)cosZ, -(float)sinZ, 0, (float)sinZ, (float)cosZ, 0, 0, 0, 1 };
var ry = new float[] { (float)cosY, 0, (float)sinY, 0, 1, 0, -(float)sinY, 0, (float)cosY };
var rx = new float[] { 1, 0, 0, 0, (float)cosX, -(float)sinX, 0, (float)sinX, (float)cosX };
int size = 3;
var ryXrx = new float[size * size];
var resultMat = new float[size * size];
// won't take the matrix --ryXrx-- here
linalg.MatrixMultiply(ry, size, size, rx, size, size,ryXrx);
This question is somewhat extension of a question asked previously c# using marshalling for packet parsing by me.
I have to parse a variable size packet although header size is fixed but data packets inside it can be of different size and may be of more than 1 type are present in same packet.
For example the packet has following fields in its header :
1) username(12 bytes)
2 password(12 bytes)
3) id_number(4 bytes)
4) may be 1 or combination of other data packets of variable size(size can be 12, 16 or 512 bytes)
5) crc(2 bytes)
Now data packets can be following
a) data packet type 1
1) size(2 bytes)
2) name(12 bytes)
3) id_number(2 bytes)
b) data packet type 2
1) size(2 bytes)
2) data(24 bytes)
3) id_number(1 byte).
So there can be either type1 or type2. It is also possible for both type to be present. My question is how can I use marshalling to parse these packets or anyone can suggest some other way.
One more thing I want to add is that 1st and 3rd field of data packets will always be the data packet size(2 bytes) and data packet id number(1 byte) respectively. The 2nd field of data packets can be anything and of variable size(2, 3, 13, 18, 515).
As an alternative, you may use LINQ (assuming that ASCII encoding is being used):
var packet = new byte[]{
97, 108, 101, 120, 0, 0, 0, 0, 0, 0, 0, 0, // username
112, 97, 115, 115, 119, 111, 114, 100, 0, 0, 0, 0, //password
49, 50, 51, 0, // id_number
0, 53, 0, 0, 1, // 1st data packet
0, 54, 1, 2, 5, 2, // 2nd data packet
49, 0 // crc
};
var username = Encoding.ASCII.GetString(packet.Take(12).ToArray());
var password = Encoding.ASCII.GetString(packet.Skip(12).Take(12).ToArray());
var idNumber = Encoding.ASCII.GetString(packet.Skip(24).Take(4).ToArray());
var data = packet.Skip(28).Take(packet.Length - 30).ToArray();
var crc = Encoding.ASCII.GetString(packet.Skip(packet.Length - 2).ToArray());
var nextDataPackedPos = 0;
var nextDataPackedPos = 0;
var dataPackets = data
.TakeWhile(b => nextDataPackedPos < data.Length)
.Zip(data.Skip(nextDataPackedPos), (a, b) =>
{
var size = Int32.Parse(
Encoding.ASCII
.GetString(data.Skip(nextDataPackedPos).Take(2).ToArray())
.Trim('\0')
);
var result = data.Skip(nextDataPackedPos).Take(size).ToArray();
nextDataPackedPos += size;
return result;
}).ToList();
The code first separates the data section from the packet bytes. Then it reads the size of each packet and based on it, it creates an equaly sized array containing the bytes of the data packet. It hen advances to the beginning of the next packet until the end of the array is reached.
Is there a way to show the representation of an int in bits in c#?
i.e.
1 = 00001
20 = 10100
etc.
I have tried using BitConverter with no luck. This should be simple, but I can't find a solution!
Convert.ToString(value, base)
Converts the value of a 32-bit signed integer to its equivalent string representation in a specified base. Specify 2 for the base.
Here's a one-liner using linq:
var myint = 20;
var bytes = Enumerable.Range(0, 32).Select(b => (myint >> b) & 1);
// { 0, 0, 1, 0, 1, 0 ... }
Of course this is in reverse order, to swap it around just use:
var myint = 20;
var bytes = Enumerable.Range(0, 32).Select(b => (myint >> (31 - b)) & 1);
// { ..., 0, 1, 0, 1, 0, 0 }
You could also look at using a BitArray.
var array = new BitArray(BitConverter.GetBytes(1));
Is there a good way to map vectors? Here's an example of what I mean:
vec0 = [0,0,0,0,0,0,0,0,0,0,0]
vec1 = [1,4,2,7,3,2]
vec2 = [0,0,0,0,0,0,0,0,0]
vec2 = [7,2,7,9,9,6,1,0,4]
vec4 = [0,0,0,0,0,0]
mainvec =
[0,0,0,0,0,0,0,0,0,0,0,1,4,2,7,3,2,0,0,0,0,0,0,0,0,0,7,2,7,9,9,6,1,0,4,0,0,0,0,0,0]
Lets say mainvec doesn't exist (I'm just showing it to you so you can see the general data structure in mind.
Now say I want mainvec(12) which would be 4. Is there a good way to map the call of these vectors without just stitching them together into a mainvec? I realize I could make a bunch of if statements that test the index of mainvec and I can then offset each call depending on where the call is within one of the vectors, so for instance:
mainvec(12) = vec1(1)
which I could do by:
mainvec(index)
if (index >=13)
vect1(index-11);
I wonder if there's a concise way of doing this without if statements. Any Ideas?
Are you looking for something like this?
using System.Collections.Generic;
namespace Test
{
class Program
{
static void Main(string[] args)
{
int[] vec0 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] vec1 = { 1, 4, 2, 7, 3, 2 };
int[] vec2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] vec3 = { 7, 2, 7, 9, 9, 6, 1, 0, 4 };
int[] vec4 = { 0, 0, 0, 0, 0, 0 };
List<int> temp = new List<int>();
temp.AddRange(vec0);
temp.AddRange(vec1);
temp.AddRange(vec2);
temp.AddRange(vec3);
temp.AddRange(vec4);
int[] mainvec = temp.ToArray();
}
}
}
I would create a class that would receive array of lengths, and have a method to give you Array number and Index inside the array for a given index in the combined list.
It would be wrapped by a class that will get references to the actual arrays and an indexer to bring you to the right element.
It looks like your doing basic list concatenation, in which case the Concat function would seem to be the most straight forward way of doing things. In real-live code terms, somethng like:
var vec0 = new[] {0,0,0,0,0,0,0,0,0,0,0};
var vec1 = new[] {1,4,2,7,3,2};
var vec2 = new[] {0,0,0,0,0,0,0,0,0};
var vec3 = new[] {7,2,7,9,9,6,1,0,4};
var vec4 = new[] { 0, 0, 0, 0, 0, 0 };
var mainvec = vec0.Concat(vec1).Concat(vec2).Concat(vec3).Concat(vec4).ToList();
mainvec[12] == 1;
I'm not really sure of the context behind what you are wanting to do, so there may be a more direct way of doing things, but based on what you've got, this seems the simplest to me.
I would use a jagged array.
You still have to have a loop, but you can keep the separate vectors without redundancy:
var mainvec = new int[][]{vec0, vec1, vec2, vec3, vec4};
int desiredInd = 12, totalInd = 0, rowInd = 0, result;
while(rowInd < mainvec.Length && (totalInd + mainvec[rowInd].Length) <= desiredInd)
{
totalInd += mainvec[rowInd++].Length;
}
if(rowInd < mainvec.Length && (desiredInd - totalInd) < mainvec[rowInd].Length)
{
result = mainvec[rowInd][desiredInd - totalInd];
}