Checking equality for two byte arrays - c#

I am checking the equality of two byte arrays, and I wanted some help because what I have returns false even though the arrays should be equal.
Within my debug I could see both of a1 and b1 are equal, but it is not going inside the while loop to increment i.
public bool Equality(byte[] a1, byte[] b1)
{
int i;
bool bEqual;
if (a1.Length == b1.Length)
{
i = 0;
while ((i < a1.Length) && (a1[i]==b1[i]))
{
i++;
}
if (i == a1.Length)
{
bEqual = true;
}
}
return bEqual;
}
This always returns false: (a1[i]==b1[i]).

You need to add a return value somewhere. This should work:
public bool Equality(byte[] a1, byte[] b1)
{
int i;
if (a1.Length == b1.Length)
{
i = 0;
while (i < a1.Length && (a1[i]==b1[i])) //Earlier it was a1[i]!=b1[i]
{
i++;
}
if (i == a1.Length)
{
return true;
}
}
return false;
}
But this is much simpler:
return a1.SequenceEqual(b1);
Alternatively, you could use IStructuralEquatable from .NET 4:
return ((IStructuralEquatable)a1).Equals(b1, StructuralComparisons.StructuralEqualityComparer)
If performance is a concern, I'd recommend rewriting your code to use the Binary class, which is specifically optimized for this kind of use case:
public bool Equality(Binary a1, Binary b1)
{
return a1.Equals(b1);
}
A quick benchmark on my machine gives the following stats:
Method Min Max Avg
binary equal: 0.868 3.076 0.933 (best)
for loop: 2.636 10.004 3.065
sequence equal: 8.940 30.124 10.258
structure equal: 155.644 381.052 170.693
Download this LINQPad file to run the benchmark yourself.

To check equality you can just write:
var areEqual = a1.SequenceEqual(b1);

I'd recommend some short-circuiting to make things a bit simpler, and use of object.ReferenceEquals to short-circuit for cases when the arrays are the same reference (a1 = b1):
public bool Equality(byte[] a1, byte[] b1)
{
// If not same length, done
if (a1.Length != b1.Length)
{
return false;
}
// If they are the same object, done
if (object.ReferenceEquals(a1,b1))
{
return true;
}
// Loop all values and compare
for (int i = 0; i < a1.Length; i++)
{
if (a1[i] != b1[i])
{
return false;
}
}
// If we got here, equal
return true;
}

This should work:
public bool Equality(byte[] a1, byte[] b1)
{
if(a1 == null || b1 == null)
return false;
int length = a1.Length;
if(b1.Length != length)
return false;
while(length >0) {
length--;
if(a1[length] != b1[length])
return false;
}
return true;
}

You should add some return statements:
public bool Equality(byte[] a1, byte[] b1)
{
int i = 0;
if (a1.Length == b1.Length)
{
while ((i < a1.Length) && (a1[i]==b1[i]))
{
i++;
}
}
return i == a1.Length;
}
Or, better yet
public bool Equality(byte[] a1, byte[] b1)
{
if(a1.Length != b1.Length)
{
return false;
}
for (int i = 0; i < a1.Length; i++)
{
if (a1[i] != b1[i])
{
return false;
}
}
return true;
}

Related

increase variable value until condition is met C#

Can't figure the good logic here I need to increase the value of my counter until the condition is met. but it says that the program is doing nothing here
int num;
int ctr = 3;
reqID = browser.Div(Find.ByClass("gwt-Label WNII") && Find.ByIndex(ctr)).OuterText;
bool isNumeric = int.TryParse(reqID, out num);
bool isTR = reqID.Contains("T_R_");
do { ctr++; }
while (isTR == true || isNumeric == true);
{
reqID = browser.Div(Find.ByClass("gwt-Label WNII") && Find.ByIndex(ctr)).OuterText;
}
Parsing this pages
https://hpe.wd5.myworkdayjobs.com/en-US/Jobsathpe/job/CBC01---Aruba-Cork-CBC01/Pricing-Specialist_1006905-3
https://hpe.wd5.myworkdayjobs.com/en-US/Jobsathpe/job/RYA01---Riyadh-Al-Faisaliah-Tower-RYA01/Portfolio-Sales-Specialist_1006892-1
See how many iterates of "gwt-Label WNII" class it has
You are not changing any of the variables that are your conditions inside the loop. So, the loop will either never start or never finish
You may want to order it like this:
int num;
int ctr = 3;
bool isTR = false;
bool IsNumeric = false;
do
{
reqID = browser.Div(Find.ByClass("gwt-Label WNII") && Find.ByIndex(ctr)).OuterText;
if(reqID != null)
{
isNumeric = int.TryParse(reqID, out num);
isTR = reqID.Contains("T_R_");
}
ctr++;
}
while (!isTR && !isNumeric);
do reference: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/do
Declare your bool outside of you while context and modify it inside :
int num;
int ctr = 3;
bool isNumeric = true;
bool isTR = true;
do
{
reqID = browser.Div(Find.ByClass("gwt-Label WNII") &&
Find.ByIndex(ctr)).OuterText;
isNumeric = int.TryParse(reqID, out num);
isTR = reqID.Contains("T_R_");
ctr++;
}
while (isTR == true || isNumeric == true);

Two Arrays have same values but do not returns equal

I want to compare two arrays and if all the values are the same i will do some stuff. I write a function like this to check is there any different value. If so return false.
bool Deneme ()
{
for (int i = 0; i < correctOnes.Length; i++) {
if(correctOnes[i] != cubeRotation[i].rotation.eulerAngles)
{
return false;
}
}
return true;
}
When I call the Deneme function it always return false. However, I check the array values in the console they are all same. Any ideas what is going on ?
Checking the console like that
for (int i = 0; i < correctOnes.Length; i++) {
Debug.Log ("Corrects: " + correctOnes[i]);
Debug.Log ("Cubes: " + cubeRotation[i].rotation.eulerAngles);
}
Console Photo:
The most likely reason for this is that eulerAngles is double, which means that it should not be compared with operator ==. Two numbers may look the same when printed, but they would compare as non-equal.
The trick here is to compare using Math.Abs(a-b) < 1E-8 method:
if(Math.Abs(correctOnes[i]-cubeRotation[i].rotation.eulerAngles) < 1E-8) {
...
}
Above, 1E-8 is a small number that represents the tolerance for comparing doubles for equality.
You can have a try with
bool Deneme ()
{
for (int i = 0; i < correctOnes.Length; i++) {
if (!Mathf.Approximately (correctOnes[i].magnitude, cubeRotation[i].rotation.eulerAngles.magnitude))
{
return false;
}
}
return true;
}
I posted the test scaffolding for completeness, but the linq query at line #35 should get you your pass/fail results.
class Ans34467714
{
List<double> correctOnes = new List<double>() { 22.7, 22.6, 44.5, 44.5, 44.5};
List<rotation> cubeRotation = new List<rotation>() { new rotation() { eulerAngles = 22.3 }, new rotation() { eulerAngles = 22.6 }, new rotation() { eulerAngles = 44.5 }, new rotation() { eulerAngles = 44.5 }, new rotation() { eulerAngles = 44.5 } };
public Ans34467714()
{
}
internal bool Execute(string[] args)
{
bool retValue = false;
if (Deneme())
{
Console.WriteLine("Pass");
}
else
{
Console.WriteLine("Fail");
}
return retValue;
}
internal bool Deneme()
{
return correctOnes.Where((var, index) => cubeRotation[index].eulerAngles == var).Count() == correctOnes.Count;
}
}
class rotation
{
public double eulerAngles {get; set;}
public rotation()
{
}
}

How to group an array of variables based on flags assigned to them with minimal code in C#

I have an array that has four elements
example :
int[] a = new int[5];
the value would be like : a[0] = 10,a[1]=5,a[2]=15,a[3]=10,a[4]=0;
I have flag ,
public bool[] flag = new bool[4]{false,false,false,false};
based on which I need to assign this above values to another variable named b[5].
If the flag is false,it will add to the existing values of b ,
else it will reset the values of a to b.
I have tried the following code which seems to be too lengthy
count[0]=20,count[1]=20;count[2]=20;count[3]=20;
flag[0]=true,flag[1]=true,flag[2]=true,flag[3]=false;
void display(int[] count,int[]flag)
{
if (flag[0] == true)
{
resetcount[0] = count[0];
}
if(flag[1]==true)
{
resetcount[1] = count[1];
}
if (flag[2] == true)
{
resetcount[2] = count[2];
}
if(flag[3]==true)
{
resetcount[3] = count[3];
}
if (flag[0] == false)
{
resetcount[0] += count[0];
}
if (flag[1] == false)
{
resetcount[1] += count[1];
}
if (flag[2] == false)
{
resetcount[2] += count[2];
}
if (flag[3] == false)
{
resetcount[3] += count[3];
}
}
here resetcount[0]=10,resetcount[1]=10,resetcount[2]=10,resetcount[3]=10;
if all flag is false the count value will be added and if it is true the count value will be set to reset count
so as above it will be 0,1,2
count[0]=20,count[1]=20;count[2]=20;count[3]=20;
flag[0]=true,flag[1]=true,flag[2]=true,flag[3]=false;
resetcount[0]=10,resetcount[1]=10,resetcount[2]=10,resetcount[3]=10;
so now resetcount would be :
resetcount[0]=20,resetcount[1]=20,resetcount[2]=20,resetcount[3]=30;
Like a loop?
count[0]=20,count[1]=20;count[2]=20;count[3]=20;
flag[0]=true,flag[1]=true,flag[2]=true,flag[3]=false;
void display(int[] count,int[]flag)
{
for (int i = 0 ; i<=3 ; i++)
{
if (flag[i])
{
resetcount[i] = count[i];
}
else
{
resetcount[i] += count[i];
}
}
public void Display(int[] resetCount, int[] count, bool[] flags)
{
for (int i = 0; i < resetCount.Count(); i++)
{
resetCount[i] = this.Calculate(resetCount[i], count[i], flags[i]);
}
}
public int Calculate(int resetCount, int count, bool flag)
{
if (flag)
{
resetCount = count;
}
else
{
resetCount += count;
}
return resetCount;
}

Condition if for Nunit assert

I need to compare two Lists by NUnit's Assert.AreEqual. If this statement is false (lists not the same) - then I need find elements in lists which not the same.
How I can use If statement for know- Assert return true or false?
It seems that nunit CollectionAssert.AreEquivalent is exactly what you were looking for.
This method compare between the collections.
If a mismatch was found then the method will throw exception with the difference.
Here's a possible solution.
[Test]
public void TestMethod1()
{
List<int> a = new List<int>();
List<int> b = new List<int>();
//Fake data
a.Add(1);
b.Add(2);
b.Add(2);
Assert.IsTrue(AreEquals(a,b), GetDifferentElements(a,b));
}
private string GetDifferentElements(List<int> a, List<int> b)
{
if (AreEquals(a, b))
{
return string.Empty;
}
if (a.Count != b.Count)
{
return "The two lists have a different length";
}
StringBuilder s = new StringBuilder();
for (int i = 0; i < a.Count; i++)
{
if (a[i] != b[i])
{
s.Append(i.ToString() + " ");
}
}
return string.Format("Elements at indexes {0} are different", s.ToString());
}
private bool AreEquals(List<int> a, List<int> b)
{
if (a.Count != b.Count)
{
return false;
}
for (int i = 0; i < a.Count; i++)
{
if (a[i] != b[i])
{
return false;
}
}
return true;
}
UPDATE
Of course I was unaware of the CollectionAssert.AreEquivalent method provided in the accepted answer. That's a better solution of course!

Mixed managed C++ method does not always return the same result to the calling C# code

A C++ method returns the correct value when I use a conditional breakpoint, but an incorrect value without a breakpoint.
C# method which calls C++:
bool SetProperty(Element element, Node referencePoint, List<Materializer> materializers, List<ulong> properties)
{
// Loop over STLs
for (int i = 0; i < materializers.Count; i++)
{
Materializer materializer = materializers[i];
if (materializer.IsPointInside(referencePoint.X, referencePoint.Y, referencePoint.Z, pentalTreeDatasets[i].top))
{
element.PropertyId = properties[i];
return true;
};
}
return false;
}
C++ methods in the header file:
int CountIntersects(double x, double y, double z, PentalTreeNode ^root)
{
Math3d::M3d rayPoints[2], intersectionPoint;
rayPoints[0].set(x,y,z);
rayPoints[1].set(x,y,1.0e6);
if(!root)
return 0;
else
{
int special = CountIntersects(x,y,z,root->special);
if (x <= root->xMax && x >= root->xMin && y <= root->yMax && y >= root->yMin)
{
if( _stlMesh->IsRayIntersectsPoly(root->index, rayPoints, intersectionPoint))
{
return (1 + special);
}
else
return special;
}
else
{
if (y>root->yMax)
{
return (CountIntersects(x,y,z,root->top)+special);
}
else if(y<root->yMin)
{
return (CountIntersects(x,y,z,root->bottom)+special);
}
else if(x<root->xMin)
{
return (CountIntersects(x,y,z,root->left)+special);
}
else if(x>root->xMax)
{
return (CountIntersects(x,y,z,root->right)+special);
}
else
return special;
}
}
}
bool IsPointInside(double x, double y, double z, PentalTreeNode ^root)
{
int intersectionCount = 0;
Math3d::M3d rayPoints[2], intersectionPoint;
rayPoints[0].set(x,y,z);
rayPoints[1].set(x,y,1.0e6);
if(_box->IsContainingPoint(x,y,z))
{
intersectionCount=CountIntersects(x,y,z,root);
return (intersectionCount%2!=0);
}
}
C++ methods in other header files:
bool IsRayIntersectsPoly(int nPolygonIndex, Math3d::M3d RayPoints[2], CVector3D& IntersectionPoint)
{
CMeshPolygonBase& Poly = m_PolygonArray[nPolygonIndex];
CArrayResultI Result;
int* pPolygonPoints = GetPolygonPoints(Poly, Result);
Math3d::MPlane TrianglePlane;
double Atmp[3], A;
CVector3D* pPoints[3];
pPoints[0] = &m_PointArray[*pPolygonPoints].m_Position;
for(int i = 1; i < Result.GetSize() - 1; i++)
{
pPoints[1] = &m_PointArray[*(pPolygonPoints+i)].m_Position;
pPoints[2] = &m_PointArray[*(pPolygonPoints+i+1)].m_Position;
TrianglePlane.Init(*pPoints[0], *pPoints[1], *pPoints[2]);
TrianglePlane.IntersectLine(RayPoints[0], RayPoints[1], IntersectionPoint);
A = GetTriangleArea(*pPoints[0], *pPoints[1], *pPoints[2]);
for(int j = 0; j < 3; j++)
{
Atmp[j] = GetTriangleArea(*pPoints[j], *pPoints[(j+1)%3], IntersectionPoint);
}
if( fabs(A - Atmp[0] - Atmp[1] - Atmp[2]) < 1.0e-5 ) return true;
}
return false;
};
double GetTriangleArea(CVector3D& T1, CVector3D& T2, CVector3D& T3)
{
double a, b, c, s;
a = (T1 - T2).length();
b = (T2 - T3).length();
c = (T3 - T1).length();
s = 0.5 * (a + b + c);
return( sqrt(s * (s - a)* (s - b)* (s - c)) );
}
When I start the program which calls SetProperty() within the for-loop, the results for some iterator values are wrong. When I set conditional breakpoints for critical iterator values in the for-loop and step over it, then the result is OK for that item. What may be the problem?
This is method in which I post breakpoint. For example, for critical element.Id==2393.
private void StartButton_Click(object sender, EventArgs e)
{
DateTime startTime = DateTime.Now;
List<Materializer> materializers = new List<Materializer>();
List<ulong> properties = new List<ulong>();
// Load STLs
for (int i = 0; (int)i < (this.dataGridView.RowCount - 1); i++)
{
if (dataGridView.Rows[i].Cells[1].Value != null && (string)dataGridView.Rows[i].Cells[1].Value != "")
{
Materializer materializer = new Materializer();
materializer.LoadSTLMesh(dataGridView.Rows[i].Cells[0].Value.ToString());
materializers.Add(materializer);
properties.Add((ulong)dataGridView.Rows[i].Cells[1].Tag);
}
}
CreatePentalTrees(materializers);
int processedElementCount = 0;
int changedElementCount = 0;
// Loop over elements
foreach (Element element in model.ElementsList.Values)
if ((element.Topology == 7 || element.Topology == 8) && !lockedProperties.ContainsKey(element.PropertyId)) // 3D elements only
{
Node center = this.CenterPoint(element, model.NodesList);
if (element.Id == 2393)
{
//if breakpoints thats ok, else not ok
Console.WriteLine(element.Id);
Console.WriteLine(element.PropertyId);
}
if (SetProperty(element, center, materializers, properties)) // Check for center point
{
//changedElements.Add(element.Id, true);
changedElementCount++;
}
else
{
// Check for all nodes if center point does not belong to any STL
int[] nodeOrder;
switch (element.Topology)
{
case 7:
nodeOrder = wedgeNodeOrder;
break;
case 8:
nodeOrder = brickNodeOrder;
break;
default:
throw new Exception("Unknown topology " + element.Topology.ToString());
}
for (int i = 0; i < nodeOrder.Length; i++)
{
Node node = model.NodesList[element.NodeIds[nodeOrder[i]]];
if (SetProperty(element, node, materializers, properties))
{
//changedElements.Add(element.Id, true);
changedElementCount++;
break;
}
}
}
if (++processedElementCount % 100 == 0)
{
labelTime.Text = "Changed/processed elements: " + changedElementCount.ToString() + "/" + processedElementCount.ToString();
labelTime.Refresh();
Application.DoEvents();
}
}
DateTime endTime = DateTime.Now;
labelTime.Text = "Total time: " + (endTime - startTime).TotalSeconds.ToString() + " s";
MessageBox.Show("Completed.");
SaveFileDialog saveFileDlg = new SaveFileDialog();
saveFileDlg.Title = "Save FEMAP neutral file";
saveFileDlg.Filter = "(*.neu)|*.neu";
if (saveFileDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
FemapNeutral.ExportNeu(saveFileDlg.FileName, model);
}
}
You seem to be calling a lot of methods you haven't listed, and/or the wall of code made me get lost. Adding that code won't help: reducing your problem to a simpler one that demonstrates the problem might.
However, the most likely cause of your problem, if you have unmanaged code reading managed data, is that you failed to marshal or pin the data prior to using the managed code.
Unpinned data can be moved around by the garbage collector in unexpected ways.

Categories

Resources