I am trying to write some operation overloading and assertion routine.
I have a struct named Degree, and following is my code;
public struct Degree
{
public float InnerValue;
public Degree(float value)
{
InnerValue = value;
}
public static Degree operator +(Degree a, Degree b)
{
return new Degree(a.InnerValue + b.InnerValue);
}
public static void UnitTest()
{
Random rd = new Random();
Degree lhs = rd.NextDegree(-(Degree)360, (Degree)360);
Degree rhs = rd.NextDegree(-(Degree)360, (Degree)360);
float f = rd.NextFloat(-100, 100);
float temp = lhs.InnerValue + rhs.InnerValue;
Debug.Assert((lhs + rhs).InnerValue == temp);
Debug.Assert((lhs + rhs).InnerValue == lhs.InnerValue + rhs.InnerValue);
}
}
my code seems looks very well for operator overloading, but assertion fails.
The problem is only second Assert fails.
I am unable to understand the reason for the same. Any help would be appreciated.
Related
This is an extension of this question: Is it possible to dynamically compile and execute C# code fragments?
But is it possible to reference fields, properties and methods of a certain object? For example:
public class SomeClass
{
public int a, b;
public int SomeMethod(int a, int b, int c)
{
return a + b + c;
}
public void Execute()
{
int c = 3;
string code = "a = b = 2; int result = SomeMethod(a, b, c);";
// Compile and execute code here
}
}
The code obviously makes no sense in terms of functionality, but it's just an example.
I wouldn't know a way, but you can call string tmp = Path.GetTempFile() to create a temp file and do a code = "void Main(string[] args){int a = b = 2; int result = SomeMethod(a, b, c); File.WriteAllBytes(\"" + tmp + "\", BitConverter.GetBytes(result));" to save the result. Then you can load it with BitConverter.ToInt32(File.ReadAllBytes(tmp)).
I think you're looking for something like Lambda Expression Serializers
DynamicExpresso
I'm working on an assignment for school that consists of both a Program.cs file and a separate class called Car. I have written all code for the Car class and pasted already provided code into the program.cs file. The resulting output is
2010 Ford Focus is going 20 MPH.
2018 Chevy Cruze is going 0 MPH.
The assignment calls for an expected output of
2010 Ford Focus is going 28 MPH.
2018 Chevy Cruze is going 18 MPH.
I need to know how to get the window to output the expected speed of 28 for Car 1 and 18 for car 2. I'm assuming that I'm not supposed to alter the code that was provided for program.cs to accomplish the right output for the application/assignment.
public class Car
{
private int Speed;
private string Make;
private string Model;
private int Year;
public Car (string make, string model, int year, int speed)
{
this.Make = make;
this.Model = model;
this.Year = year;
this.Speed = speed;
}
public Car(string make, string model, int year)
{
this.Make = make;
this.Model = model;
this.Year = year;
this.Speed = 0;
}
public int SpeedUp()
{
this.Speed = Speed++;
return (Speed);
}
public int SlowDown()
{
if (Speed > 0)
{
this.Speed = Speed--;
}
return (Speed);
}
public void Display()
{
Console.WriteLine(Year + " " + Make + " " + Model + " is going " + Speed + " MPH.");
Convert.ToString(Console.ReadLine());
}
}
and here is the given code that goes in program.cs
class Program
{
static void Main(string[] args)
{
int car1Speed = 20;
int car2Speed = 0;
Car car1 = new Car("Ford", "Focus", 2010, car1Speed);
Car car2 = new Car("Chevy", "Cruze", 2018, car2Speed);
for (int i = 0; i < 60; i++)
{
if (i % 2 == 0)
{
car2Speed = car2.SpeedUp();
}
if (i % 3 == 0)
{
car1Speed = car1.SpeedUp();
}
if (i % 5 == 0)
{
car1Speed = car1.SlowDown();
car2Speed = car2.SlowDown();
}
}
car1.Display();
car2.Display();
}
}
The line of code
this.Speed = Speed++;
Has no effect on the value of this.Speed.
The line of code is roughly equivalent to
int temp = this.Speed; // We store the original value of Speed.
this.Speed = Speed + 1; // We add one to Speed and assign it back to Speed.
this.Speed = temp; // We immediately replace Speed with the original value of Speed.
This is the due to the behavior of the '++' operator which, when appended to the end of a variable will add 1 to its current value and then assigns the result back to the variable. This operator however temporarily stores the original value and uses that as the result of the expression. This temporary result of the ++ operator is ultimately what you are assigning to this.Speed due to the '=' operator you're using in the same expression, this in turn is what is causing the variable to not actually be modified.
The correct usage would be to simply call
Speed++;
This will perform the addition of 1 and assignment back to Speed, and also discard the temporary variable, as it is not being assigned anywhere.
This issue also exists in your SpeedDown method with the '--' operator.
In your Car.cs class, here is a better way to increment the speed without modifying the Program.cs file:
public int SpeedUp()
{
this.Speed += 1;
return (Speed);
}
public int SlowDown()
{
if (Speed > 0)
{
this.Speed -= 1;
}
return (Speed);
}
That produces the output that you're after.
Writing the code for the mathematical operations between my custom classes of vectors and matrices I have faced a strange (at least for me) problem.
The overloaded operators between types give different results in different places. I have dug out that the result of the operation is sensitive on how the new instance is created inside the "operator +(...)".
I have created the simple code showing the difference (see below).
Two classes are making the same thing and the same result is expected, but in reality not the same.
The overloaded operator of Type2 and the function "test" modify the variable.
I have not found any warning about this in MSDN. This behavior is not marked directly by syntax (f.e. by the "ref" keyword).
Can anyone recommend a link about this problem?
Is it predicted behavior or a mistake in the C# syntax?
using System;
namespace test_operator_overload
{
class Program
{
static void Main()
{
Type1 A1 = new Type1(1);
Console.WriteLine(A1); // 1 - OK
Console.WriteLine(A1 + A1); // 2 - OK
Console.WriteLine(A1); // 1 - OK
Console.WriteLine();
Type2 B1 = new Type2(1);
Console.WriteLine(B1); // 1 - OK
Console.WriteLine(B1 + B1); // 2 - OK
Console.WriteLine(B1); // 2 - Not OK
Console.WriteLine();
Type2 C1 = new Type2(1);
Console.WriteLine(C1); // 1 - OK
Console.WriteLine(test(C1)); // 2 - OK
Console.WriteLine(C1); // 2 - Not OK
}
static Type2 test(Type2 a)
{
a.x += 1;
return a;
}
}
class Type1
{
public double x;
public Type1(double x)
{
this.x = x;
}
public static Type1 operator +(Type1 a, Type1 b)
{
return new Type1(a.x + b.x);
}
public override string ToString() { return GetType().Name + " (" + x + ")"; }
}
class Type2
{
public double x;
public Type2(double x)
{
this.x = x;
}
public static Type2 operator +(Type2 a, Type2 b)
{
a.x += b.x;
return a;
}
public override string ToString() { return GetType().Name + " (" + x + ")"; }
}
}
Your + operator for Type2 is borked, you should not modify the inputs in the operators.
Operators operate on the input by combining the inputs and returning the new results.
I have this in my main:
static void Main(string[] args)
{
Money m1 = new Money(2315.99);
Money m2 = new Money(4000, 25);
Console.WriteLine(m1);
Console.WriteLine(m2);
Console.WriteLine(m1.IncrementMoney(m2));
}
public void IncrementMoney(Money x)
{
//what do I put in here?
}
So
Money m1 = new Money(2315.99); is supposed to turn 2315.99 into "$2315.99"
and
Money m2 = new Money(4000, 25); forms "$4000.25"
I have all that done in Money class and it works fine.
Now what I'm supposed to do is add those two together using
m1.IncrementMoney(m2);
This is my "Money" class
class Money
{
//instance variables
private int dollars;
private int cents;
double amount;
public int Dollars
{
get { return dollars; }
set
{
if (value > 0)
dollars = value;
}
}
public int Cents
{
get { return cents; }
set
{
if (value > 0)
cents = value;
}
}
public Money(int Dol, int Cen)
{
Dollars = Dol;
Cents = Cen;
double Dollar = Convert.ToDouble(Dollars);
double Cent = Convert.ToDouble(Cents);
amount = Dollar + (Cent / 100);
}
public Money(double am)
{
int dol = Convert.ToInt32(am);
if (dol > am)
Dollars = dol - 1;
else if (dol < am)
Dollars = dol;
//Dollars
double cen = am % 1;
cen = cen * 100;
Cents = Convert.ToInt32(cen);
//Cents
double Dollar = Convert.ToDouble(Dollars);
double Cent = Convert.ToDouble(Cents);
amount = Dollar + (Cent / 100);
}
//override ToString()
public override string ToString()
{
return string.Format("{0:c}", amount);
}
}//end class Money
But I have no idea what to put into the IncrementMoney method. Please help?
and if not too much trouble, maybe a little insight to how it works? I'd really like to know.
Sorry if I didn't give enough info,
If anything else is required please let me know.
and thanks!
Since IncrementMoney is supposed to add the two money values together, your usage looks like it should instead be an extension method of the Money type. Which is fine, because extension methods are pretty awesome. A common joke on this site is that they're the solution to everything.
Your code should look similar to:
public static Money IncrementMoney(this Money x, Money y)
{
var totalCents = x.Cents + y.Cents;
var retCents = totalCents / 100;
var retDollars = x.Dollars + y.Dollars + (totalCents % 100)
return new Money(retDollars, retCents);
}
As for a quick explanation...
By adding this to the first argument, we are telling C# that we want to write an extension method. This will mean that this method we're writing will hang off the type of the this argument (in this case, Money) and allow us to use it exactly like it was always in the .NET framework. Extension methods have to be static, so you can't not use that modifier. Beyond that, you just write a method to do whatever you have in mind, exactly like you normally would!
I would suggest you name it something other than IncrementMoney, though. That's not very descriptive. AddMoney would be better.
You may also look into operator overloading, by the way. You could adapt what I just wrote to simply use the + operator to do exactly the same thing, like so:
public static Money operator +(Money x, Money y)
{
var totalCents = x.Cents + y.Cents;
var retCents = totalCents / 100;
var retDollars = x.Dollars + y.Dollars + (totalCents % 100)
return new Money(retDollars, retCents);
}
With this defined, you can simply go m1 + m2 and add them together.
public void IncrementMoney(Money x)
{
this.Dollars += x.Dollars;
var newCents = this.Cents + x.Cents;
this.Cents = newCents % 100;
this.Dollars += newCents / 100;
}
And I would actually name the function Add since you are taking the current value and adding the provided value, and no need for the Money modifier as it should be on the Money class and takes a Money object
Well first of all this line:
Console.WriteLine(m1.IncrementMoney(m2));
indicates that IncrementMoney should return something, but right now it returns void.
So it looks like it should be something like:
public void IncrementMoney(ClassA x)
{
this.Value += x.Value;
}
And then display it with:
ClassA m1 = new ClassA(2315.99);
ClassA m2 = new ClassA(4000, 25);
Console.WriteLine(m1);
Console.WriteLine(m2);
m1.IncrementMoney(m2);
Console.WriteLine(m1);
I took upon myself to present my team with a situation where a bug would be introduced by the rearrangement of instructions, however my understanding of CPUs, CLR, and JIT is quite amateurish and I did not manage to pull off a good example.
Below I show what is the best I came up with, so please look at the code snippet to understand what I am talking about from here on.
The main point is in thread2's if statement, if it ever happens - it means that the instructions were rearranged. if i manually rearrange the instructions in thread 1 or in thread 2 -> the printing will happened(even if you you swap c.x and c.y reads in thread 2, it will print due to a race condition).
My idea was to force a rearrangement of writes of x and z by making the variables which are placed farther apart integers thinking it could write them both withing one cpu cycle due to the 8 byte word size, instead of it being 3 cycles of writing 4 -> 8 -> 4 bytes. (I know it is not actually 3 cpu cycles, unfortunately, I don't know anything about assembly.) I even tried as a last resort to put it in a struct, thinking that would force some kind of an optimization from JIT.
Any help would be appreciated, because I am very eager to make it work. (I have also tried to follow the examples shown in the ebook by Joseph Albahari, but those did not work, this is why i tried to make a more sophisticated example.) I also did not forget compiling in Release for x64 instruction set.
Code:
public class Program
{
public static void Main()
{
var stopWatch = new Stopwatch();
for (var i = 0; i < 100000000; i++)
{
var delegates = new MultiTreadingDelegates(i);
Task.Run(delegates.Thread1);
Task.Run(delegates.Thread2);
}
Console.WriteLine("finished");
Console.ReadKey();
}
}
public class MultiTreadingDelegates
{
private int i = 0;
private Container container = new Container();
public MultiTreadingDelegates(int i)
{
this.i = i;
}
public void Thread1()
{
container.X = 10000000;
container.Z = 6000000000;
container.Y = 20000000;
}
public void Thread2()
{
int y = container.Y;
long z = container.Z;
int x = container.X;
if (x != 0 && z == 0 && y != 0)
{
System.Console.WriteLine($"i = {i}{Environment.NewLine}"
+ $"x = {x}{Environment.NewLine}"
+ $"z = {z}{Environment.NewLine}"
+ $"y = {y}{Environment.NewLine}"
);
}
}
}
public struct Container
{
public int X;
public long Z;
public int Y;
}
Inspired by the lecture of Sasha Goldshtein - a video i was given as a comment to my question - I have managed to pull off and example of reordering on an Intel machine(code below)! I thank everyone once again for their help.
class Program
{
static void Main(string[] args)
{
Task.Run(DelegatesUsingPetersons.Thread1);
Task.Run(DelegatesUsingPetersons.Thread2).GetAwaiter().GetResult();
}
}
static class DelegatesUsingPetersons
{
private static long x = 0;
private static long y = 0;
private static bool flag1 = false;
private static bool flag2 = false;
public static void Thread1()
{
while (true)
{
flag1 = true;
/*Thread.MemoryBarrier();*/ //Uncomment to fix locking mechanism
if (flag2 == false)
{
x++;
y++;
}
flag1 = false;
}
}
public static void Thread2()
{
long lx = 0;
long ly = 0;
while (true)
{
flag2 = true;
/*Thread.MemoryBarrier();*/ //Uncomment to fix locking mechanism
if (flag1 == false)
{
lx = x;
ly = y;
}
flag2 = false;
if (lx != ly)
{
Console.WriteLine($"lx={lx}, ly={ly} - OMG this cannot happen!");
}
}
}
}
If you want to juxtapose it with a working "more traditional" code, here is the same kind of code just without Mr.Peterson doing all the fancy algorithmic witchcraft
static class DelegatesUsingLock
{
private static long x = 0;
private static long y = 0;
private static object loq = new object();
public static void Thread1()
{
while (true)
{
if (Monitor.TryEnter(loq))
{
x++;
y++;
Monitor.Exit(loq);
}
}
}
public static void Thread2()
{
long lx = 0;
long ly = 0;
while (true)
{
if (Monitor.TryEnter(loq))
{
lx = x;
ly = y;
Monitor.Exit(loq);
}
if (lx != ly)
{
Console.WriteLine($"lx={lx}, ly={ly} - This Never Happens");
}
}
}
}