Adding delegate in C# [duplicate] - c#

This question already has answers here:
Events and Delegates in F#
(3 answers)
Closed 9 years ago.
How does one add a new function to a delegate without using the += notation ?
I wonder how to do his from another CLR langage, namely F#. (I know there are much nicer way to deal with events in F#, but I am being curious..)
static int Square (int x) { return x * x; }
static int Cube(int x) { return x * x * x; }
delegate int Transformer (int x);
Transformer d = Square ;
d += Cube;
Edit
As pointed out by Daniel in the comments, the fact that one has no direct way of doing this probably is a design decision by dotnet team to not mutate the queue too much.

Here is one way to do it in F#. You need downcasting due to the use of Delegate.Combine:
let square x = x * x
let cube x = x * x * x
type Transformer = delegate of int -> int
let inline (++) (a: 'T) (b: 'T) =
System.Delegate.Combine(a, b) :?> 'T
let d = Transformer(square)
let e = d ++ Transformer(cube)

Delegate.Combine?
d = (Transformer) Delegate.Combine(d, new Transformer(Cube));

Related

Precomputation of constants (Is there a performance difference?) [duplicate]

This question already has answers here:
Does C# Compiler calculate math on constants?
(2 answers)
Closed 1 year ago.
Is the compiler 'smart enough' to precompute this, or will it have a performance impact?
const float num = 0.8660254f; // Sqrt(3) / 2
while(true)
{
float h = num * GetSomeNumber();
}
vs
while(true)
{
float h = (Sqrt(3) / 2 ) * GetSomeNumber();
}
vs
const float num = 1.7320508f; // Sqrt(3)
while(true)
{
float h = (num / 2) * GetSomeNumber();
}
And is there any reason to (not) precompute?
First, the compiler does not do any computation. Computation or execution of the code is a runtime thing. The compiler is smart enough to do multiple adjustments to the code for performance, but it does not have any idea about what method you are calling at runtime. So it won't know how your method Sqrt behaves at runtime. And hence, it will not be able to perform calculations beforehand during compilation.

Noob explanation of ++x [duplicate]

This question already has answers here:
How do the post increment (i++) and pre increment (++i) operators work in Java?
(14 answers)
Closed 4 years ago.
Please explain ++x in layman's terms
I tried searching for this here, youtube, Google, Chegg, and a programming community on discord. I'm pretty desperate now because I I still don't understand this. haha
I know that it's a prefix which means that it increments the value then does the expression, but I don't exactly understand what that means.
I also know what y -= 3 means which is y-3.
int x = 8;
int y = ++x;
if (x > 5)
y -= 3;
else
y = 9;
Console.WriteLine(y);
I don't know what the answer is.
int x = 10;
int y = ++x;
now y == 11 and x == 11
int x = 10;
int y = x++;
now y==10 and x == 11
In both cases x is increased by 1. The difference is that when you use ++x it returns the value after increment (increment first and assign second) while x++ returns the value before increment (assign first and increment second).

BesselK Function in C#

I am attempting to implement the BesselK method from Boost (a C++ library).
The Boost method accepts two doubles and returns a double. (I have it implemented below as cyl_bessel_k .)
The equation I modeled this off of comes from Boosts documention:
http://www.boost.org/doc/libs/1_45_0/libs/math/doc/sf_and_dist/html/math_toolkit/special/bessel/mbessel.html
I have also been checking values against Wolfram:
http://www.wolframalpha.com/input/?i=BesselK%283%2C1%29
I am able to match output from the Boost method when passing a positive non-integer value for "v". However, when an integer is passed, my output is severely off. So,there is an obvious discontinuity issue. From reading up on this, it seems that this issue arises from passing a negative integer to the gamma function. Somehow reflection comes into play here with the Bessel_I method, but I'm nearing the end of my math skillset.
1.) What needs to happen to the bessel_i method with reflection to make this work?
2.) I'm currently doing a partial sum approach. Boost uses a continuous fraction approach. How can I modify this to account for convergence?
Any input is appreciated! Thank you!
static double cyl_bessel_k(double v, double x)
{
if (v > 0)
{
double iNegativeV = cyl_bessel_i(-v, x);
double iPositiveV = cyl_bessel_i(v, x);
double besselSecondKind = (Math.PI / 2) * ((iNegativeV - iPositiveV ) / (Math.Sin(Math.PI * v)));
return besselSecondKind;
}
else
{
//error handling
}
}
static double cyl_bessel_i(double v, double x)
{
if (x == 0)
{
return 0;
}
double summed = 0;
double a = Math.Pow((0.5d * x), v);
for (double k = 0; k < 10; k++) //how to account for convergence? 10 is arbitrary
{
double b = Math.Pow(0.25d * Math.Pow(x, 2), k);
double kFactorial = SpecialFunctions.Factorial((int)k); //comes from MathNet.Numerics (Nuget)
double gamma = SpecialFunctions.Gamma(v + k + 1); //comes from MathNet.Numerics
summed += b / (kFactorial * gamma);
}
return a * summed;
}
After lots of refactoring and trying things that didn't work, this is what I came up with. It's mostly Boost logic that has been adapted and translated into C#.
It's not perfect though (likely due to rounding, precision,etc). Any improvements are welcome! Max error is 0.0000001926% between true Bessel_K value from Wolfram and my adapted method. This is occurs when parameter 'v' is an integer. For my purposes, this was close enough.
Link to fiddle:
https://dotnetfiddle.net/QIYzK6
Hopefully it saves someone some headache.

Multiple Assignment syntax in C#

Ive seen the following syntax in a couple of code samples, it looks pretty obvious, but not in the context that i saw it in,
so can someone confirm
var x = 1
var y = 2
var z = 3
x = y = z
so in essence does this mean that
x and y both equal z?
tried to google this, and couldn't find the syntax, also looked in murach .net books with no luck
The assignment operator returns the value being assigned as it's result
The assignment operator (=) stores the value of its right-hand operand in the storage location, property, or indexer denoted by its left-hand operand and returns the value as its result.
So
x = y = z;
Is parsed as
x = (y = z);
And this is equivalent to
y = z;
x = y;
In the end, x, and y are assigned the same value as z (in this case, 3).
This will indeed set x and y to the value of z, however to see why you can parenthesize the expression:
x = (y = z);
In this case the y = z expression will return the new value for y (in this case 3), and set x to that value.
This works for very long expressions too:
x = y = z = a = b
x = (y = (z = (a = b)))
Where x, y, z and a will be set to the value of b.
EDIT:
Also remember the order of precedence of operators when using this method of reading into a long expression, while its not a good practice to create huge chained statements you do sometimes see it in code online, another (and better) way you can use to read confusing statements like this is to think of the syntax tree that is generated.
Ehm, yes that is correct :).
x, y and x will all be 3 as you can assign values like that.
you can make the chain as long as you like too.
a = b = c = d;
all preceding values would be the value of d

Precedence of cast in c# [duplicate]

This question already has answers here:
Cast operation precedence in C#
(3 answers)
Closed 8 years ago.
What is the precedence of a cast in c#? For example in the following code, will z be less than or equal to two?
double x = 4.5;
double y = 2.1;
double z = (int) x / y;
The cast beats all binary operators for binding. Hence (int)x / y means ((int)x)/y.
On the other hand, you should always prefer readable code to clever code, so since you don't know you should write the following instead:
((int)x) / y
Note that brackets are free, and make your code more readable.
Less than:
using System;
public class Test
{
public static void Main()
{
double x = 4.5;
double y = 2.1;
double z = (int) x / y;
Console.WriteLine(z);
}
}
See here: http://ideone.com/fhg5ai
z will be less than two:
double x = 4.5;
double y = 2.1;
double z = (int) x / y;
Console.WriteLine(z); //1.9047619047619
Your code is really doing this: ((int)x) / y, which may or may not be your expected output.

Categories