Trying to remove ambiguous call in constructor involving int and long - c#

"The call is ambiguous between the following methods or properties: 'fInt.fInt(int, bool)' and 'fInt.fInt(long, bool)'"
Here are my two constructors:
public fInt(int i, bool scale = true)
{
if (scale) value = i * SCALE;
else value = i;
}
public fInt(long i, bool scale = true)
{
if (scale)
{
if(i > long.MaxValue / SCALE || i < long.MinValue / SCALE)
Debug.LogError("fInt Overflow on creation with scaling");
value = i * SCALE;
}
else value = i;
}
Here's how I'm calling one with int using implicit conversion:
fInt i = 8;
I would like to be able to use both int and long so that I may avoid an extra check if it's not needed. Any thoughts on how to fix this? Would I simply have to do this:
fInt i = (int)8;
fInt i2 = (long)9;
I'd rather not have the extra typing if I can avoid it. Here are my implicit conversions:
//implicit int to fInt
public static implicit operator fInt(int i)
{
return new fInt(i);
}
//implicit long to fInt
public static implicit operator fInt(long i)
{
return new fInt(i);
}

It appears to be a bug in the Unity3D editor...as the code runs fine in Visual Studio. It only mixes up the signatures when the second parameter is optional.

Related

Dynamic "Scoping" of C# Checked Expression

Is it possible (in C#) to cause a checked(...) expression to have dynamic "scope" for the overflow checking? In other words, in the following example:
int add(int a, int b)
{
return a + b;
}
void test()
{
int max = int.MaxValue;
int with_call = checked(add(max, 1)); // does NOT cause OverflowException
int without_call = checked(max + 1); // DOES cause OverflowException
}
because in the expression checked(add(max, 1)), a function call causes the overflow, no OverflowException is thrown, even though there is an overflow during the dynamic extent of the checked(...) expression.
Is there any way to cause both ways to evaluate int.MaxValue + 1 to throw an OverflowException?
EDIT: Well, either tell me if there is a way, or give me a better way to do this (please).
The reason I think I need this is because I have code like:
void do_op(int a, int b, Action<int, int> forSmallInts, Action<long, long> forBigInts)
{
try
{
checked(forSmallInts(a, b));
}
catch (OverflowException)
{
forBigInts((long)a, (long)b);
}
}
...
do_op(n1, n2,
(int a, int b) => Console.WriteLine("int: " + (a + b)),
(long a, long b) => Console.WriteLine("long: " + (a + b)));
I want this to print int: ... if a + b is in the int range, and long: ... if the small-integer addition overflows. Is there a way to do this that is better than simply changing every single Action (of which I have many)?
To be short, no it is not possible for checked blocks or expressions to have dynamic scope.
If you want to apply this in the entirety of your code base you should look to adding it to your compiler options.
Checked expressions or checked blocks should be used where the operation is actually happening.
int add(int a, int b)
{
int returnValue = 0;
try
{
returnValue = checked(a + b);
}
catch(System.OverflowException ex)
{
//TODO: Do something with exception or rethrow
}
return returnValue;
}
void test()
{
int max = int.MaxValue;
int with_call = add(max, 1);
}
You shouldn't catch exceptions as part of the natural flow of your program. Instead, you should anticipate the problem. There are quite a few ways you can do this, but assuming you just care about int and long and when the addition overflows:
EDIT: Using the types you mention below in your comment instead of int and long:
void Add(RFSmallInt a, RFSmallInt b)
{
RFBigInt result = new RFBigInt(a) + new RFBigInt(b);
Console.WriteLine(
(result > RFSmallInt.MaxValue ? "RFBigInt: " : "RFSmallInt: ") + result);
}
This makes an assumption that you have a constructor for RFBigInt that promotes a RFSmallInt. This should be trivial as BigInteger has that same for long. There is also an explicit cast from BigInteger to long that you can use to "demote" the value if it is does not overflow.
An exception should be an exception, not the usual program flow. But lets not care about that for now :)
The direct answer to you question I believe is no, but you can always work yourself around the problem. I'm posting a small part of some of the ninja stuff I made when implementing unbounded integers (in effect a linked list of integers) which could help you.
This is a very simplistic approach for doing checked addition manually if performance is not an issue. Is quite nice if you can overload the operators of the types, ie you control the types.
public static int SafeAdd(int left, int right)
{
if (left == 0 || right == 0 || left < 0 && right > 0 || right < 0 && left > 0)
// One is 0 or they are both on different sides of 0
return left + right;
else if (right > 0 && left > 0 && int.MaxValue - right > left)
// More than 0 and ok
return left + right;
else if (right < 0 && left < 0 && int.MinValue - right < left)
// Less than 0 and ok
return left + right;
else
throw new OverflowException();
}
Example with your own types:
public struct MyNumber
{
public MyNumber(int value) { n = value; }
public int n; // the value
public static MyNumber operator +(MyNumber left, MyNumber right)
{
if (left == 0 || right == 0 || left < 0 && right > 0 || right < 0 && left > 0)
// One is 0 or they are both on different sides of 0
return new MyNumber(left.n + right.n); // int addition
else if (right > 0 && left > 0 && int.MaxValue - right > left)
// More than 0 and ok
return new MyNumber(left.n + right.n); // int addition
else if (right < 0 && left < 0 && int.MinValue - right < left)
// Less than 0 and ok
return new MyNumber(left.n + right.n); // int addition
else
throw new OverflowException();
}
// I'm lazy, you should define your own comparisons really
public static implicit operator int(MyNumber number) { return number.n; }
}
As I stated earlier, you will lose performance, but gain the exceptions.
You could use Expression Tree & modify it to introduce Checked for math operator & execute it. This sample is not compiled and tested, you will have to tweak it little more.
void CheckedOp (int a, int b, Expression <Action <int, int>> small, Action <int, int> big){
var smallFunc = InjectChecked (small);
try{
smallFunc(a, b);
}catch (OverflowException oe){
big(a,b);
}
}
Action<int, int> InjectChecked( Expression<Action<int, int>> exp )
{
var v = new CheckedNodeVisitor() ;
var r = v.Visit ( exp.Body);
return ((Expression<Action<int, int>> exp) Expression.Lambda (r, r. Parameters) ). Compile() ;
}
class CheckedNodeVisitor : ExpressionVisitor {
public CheckedNodeVisitor() {
}
protected override Expression VisitBinary( BinaryExpression be ) {
switch(be.NodeType){
case ExpressionType.Add:
return Expression.AddChecked( be.Left, be.Right);
}
return be;
}
}

Is there a direct way to multiply a Size or Point by a number?

By "direct" I mean something like Size*2 (which doesn't work) as opposed to:
size1 = new Size(size1.Width * 2, size1.Height * 2);
You can technically write an extension method:
public static class Extensions {
public static Size Multiply(this Size size, double factor) {
return new Size((int)(size.Width * factor), (int)(size.Height * factor));
}
}
But just about nobody is going to use it correctly. They'll write
this.Size.Multiply(1.2);
instead of the required
this.Size = this.Size.Multiply(1.2);
An almost inevitable mistake because it looks like an instance method. So don't do it, just write a static helper method.
You can overload the * operator:
class Size
{
public int Width { get; set; }
public int Height { get; set; }
public Size(int w, int h)
{
this.Width = w;
this.Height = h;
}
public static Size operator *(Size s, int n)
{
return new Size(s.Width * n, s.Height * n);
}
}
Now you can do:
Size s1 = new Size(1, 2);
Size s = s1 * 2; // s.Height = 2, s.Width = 4
Since there is no * operator implemented for the Size struct you would have to create one. But with extension methods it is not possible to create new operators. Instead you could create an extension method called multiply for instance.
Not without work but it is quite easy to overload operators
see demo of operator overloading on codeproject
see right at the bottom:
public static MySize operator +(MySize mySize, Int32 value)
{
return new MySize(
mySize.m_Width + value,
mySize.m_Height + value);
}
It shouldn't take you long to work out the * operator overload

C# Compiler "Optimize code" : disable on a code fragment only

I have a C# code which is working good when the "optimize code" option is off, but fails otherwise. Is there any function or class attribute which can prevent the optimisation of a function or class, but let the compiler optimize the others ?
(I tried unsafe or MethodImpl, but without success)
Thanks
Edit :
I have done some more test...
The code is like this :
double arg = (Math.PI / 2d - Math.Atan2(a, d));
With a = 1 and d = 0, arg should be 0.
Thid code is a function which is called by Excel via ExcelDNA.
Calling an identical code from an optimized console app : OK
Calling this code from Excel without optimization : OK
Calling this code from Excel with optimization : Not OK, arg == 0 is false (instead arg is a very small value near 0, but not 0)
Same result with [MethodImpl(MethodImplOptions.NoOptimization)] before the called function.
This is very likely to do with the floating point mode which Excel likely has set - meaning that your program is calculating floating points slightly different because of the program (Excel) hosting your assembly (DLL). This might impact how your results are calculated, or how/what values are automatically coerced to zero.
To be absolutely sure you are not going to run into issues with different floating point modes and/or errors you should check for equality rather by checking if the values are very close together. This is not really a hack.
public class AlmostDoubleComparer : IComparer<double>
{
public static readonly AlmostDoubleComparer Default = new AlmostDoubleComparer();
public const double Epsilon = double.Epsilon * 64d; // 0.{322 zeroes}316
public static bool IsZero(double x)
{
return Compare(x, 0) == 0;
}
public static int Compare(double x, double y)
{
// Very important that cmp(x, y) == cmp(y, x)
if (Double.IsNaN(x) || Double.IsNaN(y))
return 1;
if (Double.IsInfinity(x) || Double.IsInfinity(y))
return 1;
var absX = Math.Abs(x);
var absY = Math.Abs(y);
var diff = absX > absY ? absX - absY : absY - absX;
if (diff < Epsilon)
return 0;
if (x < y)
return -1;
else
return 1;
}
int IComparer<double>.Compare(double x, double y)
{
return Compare(x, y);
}
}
// E.g.
double arg = (Math.PI / 2d - Math.Atan2(a, d));
if (AlmostDoubleComparer.IsZero(arg))
// Regard it as zero.
I also ported the re-interpret integer comparison, in case you find that more suitable (it deals with larger values more consistently).
public class AlmostDoubleComparer : IComparer<double>
{
public static readonly AlmostDoubleComparer Default = new AlmostDoubleComparer();
public const double MaxUnitsInTheLastPlace = 3;
public static bool IsZero(double x)
{
return Compare(x, 0) == 0;
}
public static int Compare(double x, double y)
{
// Very important that cmp(x, y) == cmp(y, x)
if (Double.IsNaN(x) || Double.IsNaN(y))
return 1;
if (Double.IsInfinity(x) || Double.IsInfinity(y))
return 1;
var ix = DoubleInt64.Reinterpret(x);
var iy = DoubleInt64.Reinterpret(y);
var diff = Math.Abs(ix - iy);
if (diff < MaxUnitsInTheLastPlace)
return 0;
if (ix < iy)
return -1;
else
return 1;
}
int IComparer<double>.Compare(double x, double y)
{
return Compare(x, y);
}
}
[StructLayout(LayoutKind.Explicit)]
public struct DoubleInt64
{
[FieldOffset(0)]
private double _double;
[FieldOffset(0)]
private long _int64;
private DoubleInt64(long value)
{
_double = 0d;
_int64 = value;
}
private DoubleInt64(double value)
{
_int64 = 0;
_double = value;
}
public static double Reinterpret(long value)
{
return new DoubleInt64(value)._double;
}
public static long Reinterpret(double value)
{
return new DoubleInt64(value)._int64;
}
}
Alternatively you could try and NGen the assembly and see if you can work around the either the mode Excel has, or how it is hosting the CLR.
That is what you get when working with floating point datatypes. You don't get exactly 0, but a very close value, since a double has limited precision and not every value can be represented and sometimes those tiny precision errors add up. You either need to expect that (check that the value is close enough to 0).

Sorting Complex Numbers

I have a struct called "Complex" in my project (I build it with using C#) and as the name of the struct implies, it's a struct for complex numbers. That struct has a built-in method called "Modulus" so that I can calculate the modulus of a complex number. The things are quite easy up to now.
The thing is, I create an array out of this struct and I want to sort the array according to the modulus of the complex numbers contained.(greater to smaller). Is there a way for that?? (Any algorithm suggestions will be welcomed.)
Thank you!!
Complex[] complexArray = ...
Complex[] sortedArray = complexArray.OrderByDescending(c => c.Modulus()).ToArray();
First of all, you can increase performances comparing squared modulus instead of modulus.
You don't need the squared root: "sqrt( a * a + b * b ) >= sqrt( c * c + d * d )" is equivalent to "a * a + b + b >= c * c + d * d".
Then, you can write a comparer to sort complex numbers.
public class ComplexModulusComparer :
IComparer<Complex>,
IComparer
{
public static readonly ComplexModulusComparer Default = new ComplexModulusComparer();
public int Compare(Complex a, Complex b)
{
return a.ModulusSquared().CompareTo(b.ModulusSquared());
}
int IComparer.Compare(object a, object b)
{
return ((Complex)a).ModulusSquared().CompareTo(((Complex)b).ModulusSquared());
}
}
You can write also the reverse comparer, since you want from greater to smaller.
public class ComplexModulusReverseComparer :
IComparer<Complex>,
IComparer
{
public static readonly ComplexModulusReverseComparer Default = new ComplexModulusReverseComparer();
public int Compare(Complex a, Complex b)
{
return - a.ModulusSquared().CompareTo(b.ModulusSquared());
}
int IComparer.Compare(object a, object b)
{
return - ((Complex)a).ModulusSquared().CompareTo(((Complex)b).ModulusSquared());
}
}
To sort an array you can then write two nice extension method ...
public static void SortByModulus(this Complex[] array)
{
Array.Sort(array, ComplexModulusComparer.Default);
}
public static void SortReverseByModulus(this Complex[] array)
{
Array.Sort(array, ComplexModulusReverseComparer.Default);
}
Then in your code...
Complex[] myArray ...;
myArray.SortReverseByModulus();
You can also implement the IComparable, if you wish, but a more correct and formal approach is to use the IComparer from my point of view.
public struct Complex :
IComparable<Complex>
{
public double R;
public double I;
public double Modulus() { return Math.Sqrt(R * R + I * I); }
public double ModulusSquared() { return R * R + I * I; }
public int CompareTo(Complex other)
{
return this.ModulusSquared().CompareTo(other.ModulusSquared());
}
}
And then you can write the ReverseComparer that can apply to every kind of comparer
public class ReverseComparer<T> :
IComparer<T>
{
private IComparer<T> comparer;
public static readonly ReverseComparer<T> Default = new ReverseComparer<T>();
public ReverseComparer<T>() :
this(Comparer<T>.Default)
{
}
public ReverseComparer<T>(IComparer<T> comparer)
{
this.comparer = comparer;
}
public int Compare(T a, T b)
{
return - this.comparer.Compare(a, b);
}
}
Then when you need to sort....
Complex[] array ...;
Array.Sort(array, ReverseComparer<Complex>.Default);
or in case you have another IComparer...
Complex[] array ...;
Array.Sort(array, new ReverseComparer<Complex>(myothercomparer));
RE-EDIT-
Ok i performed some speed test calculation.
Compiled with C# 4.0, in release mode, launched with all instances of visual studio closed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace TestComplex
{
class Program
{
public struct Complex
{
public double R;
public double I;
public double ModulusSquared()
{
return this.R * this.R + this.I * this.I;
}
}
public class ComplexComparer :
IComparer<Complex>
{
public static readonly ComplexComparer Default = new ComplexComparer();
public int Compare(Complex x, Complex y)
{
return x.ModulusSquared().CompareTo(y.ModulusSquared());
}
}
private static void RandomComplexArray(Complex[] myArray)
{
// We use always the same seed to avoid differences in quicksort.
Random r = new Random(2323);
for (int i = 0; i < myArray.Length; ++i)
{
myArray[i].R = r.NextDouble() * 10;
myArray[i].I = r.NextDouble() * 10;
}
}
static void Main(string[] args)
{
// We perform some first operation to ensure JIT compiled and optimized everything before running the real test.
Stopwatch sw = new Stopwatch();
Complex[] tmp = new Complex[2];
for (int repeat = 0; repeat < 10; ++repeat)
{
sw.Start();
tmp[0] = new Complex() { R = 10, I = 20 };
tmp[1] = new Complex() { R = 30, I = 50 };
ComplexComparer.Default.Compare(tmp[0], tmp[1]);
tmp.OrderByDescending(c => c.ModulusSquared()).ToArray();
sw.Stop();
}
int[] testSizes = new int[] { 5, 100, 1000, 100000, 250000, 1000000 };
for (int testSizeIdx = 0; testSizeIdx < testSizes.Length; ++testSizeIdx)
{
Console.WriteLine("For " + testSizes[testSizeIdx].ToString() + " input ...");
// We create our big array
Complex[] myArray = new Complex[testSizes[testSizeIdx]];
double bestTime = double.MaxValue;
// Now we execute repeatCount times our test.
const int repeatCount = 15;
for (int repeat = 0; repeat < repeatCount; ++repeat)
{
// We fill our array with random data
RandomComplexArray(myArray);
// Now we perform our sorting.
sw.Reset();
sw.Start();
Array.Sort(myArray, ComplexComparer.Default);
sw.Stop();
double elapsed = sw.Elapsed.TotalMilliseconds;
if (elapsed < bestTime)
bestTime = elapsed;
}
Console.WriteLine("Array.Sort best time is " + bestTime.ToString());
// Now we perform our test using linq
bestTime = double.MaxValue; // i forgot this before
for (int repeat = 0; repeat < repeatCount; ++repeat)
{
// We fill our array with random data
RandomComplexArray(myArray);
// Now we perform our sorting.
sw.Reset();
sw.Start();
myArray = myArray.OrderByDescending(c => c.ModulusSquared()).ToArray();
sw.Stop();
double elapsed = sw.Elapsed.TotalMilliseconds;
if (elapsed < bestTime)
bestTime = elapsed;
}
Console.WriteLine("linq best time is " + bestTime.ToString());
Console.WriteLine();
}
Console.WriteLine("Press enter to quit.");
Console.ReadLine();
}
}
}
And here the results:
For 5 input ...
Array.Sort best time is 0,0004
linq best time is 0,0018
For 100 input ...
Array.Sort best time is 0,0267
linq best time is 0,0298
For 1000 input ...
Array.Sort best time is 0,3568
linq best time is 0,4107
For 100000 input ...
Array.Sort best time is 57,3536
linq best time is 64,0196
For 250000 input ...
Array.Sort best time is 157,8832
linq best time is 194,3723
For 1000000 input ...
Array.Sort best time is 692,8211
linq best time is 1058,3259
Press enter to quit.
My machine is an Intel I5, 64 bit windows seven.
Sorry! I did a small stupid bug in the previous edit!
ARRAY.SORT OUTPEFORMS LINQ, yes by a very small amount, but as suspected, this amount grows with n, seems in a not-so-linear way. It seems to me both code overhead and a memory problem (cache miss, object allocation, GC ... don't know).
You can always use SortedList :) Assuming modulus is int:
var complexNumbers = new SortedList<int, Complex>();
complexNumbers.Add(number.Modulus(), number);
public struct Complex: IComparable<Complex>
{
//complex rectangular number: a + bi
public decimal A
public decimal B
//synonymous with absolute value, or in geometric terms, distance
public decimal Modulus() { ... }
//CompareTo() is the default comparison used by most built-in sorts;
//all we have to do here is pass through to Decimal's IComparable implementation
//via the results of the Modulus() methods
public int CompareTo(Complex other){ return this.Modulus().CompareTo(other.Modulus()); }
}
You can now use any sorting method you choose on any collection of Complex instances; Array.Sort(), List.Sort(), Enumerable.OrderBy() (it doesn't use your IComparable, but if Complex were a member of a containing class you could sort the containing class by the Complex members without having to go the extra level down to comparing moduli), etc etc.
You stated you wanted to sort in descending order; you may consider multiplying the results of the Modulus() comparison by -1 before returning it. However, I would caution against this as it may be confusing; you would have to use a method that normally gives you descending order to get the list in ascending order. Instead, most sorting methods allow you to specify either a sorting direction, or a custom comparison which can still make use of the IComparable implementation:
//This will use your Comparison, but reverse the sort order based on its result
myEnumerableOfComplex.OrderByDescending(c=>c);
//This explicitly negates your comparison; you can also use b.CompareTo(a)
//which is equivalent
myListOfComplex.Sort((a,b) => return a.CompareTo(b) * -1);
//DataGridView objects use a SortDirection enumeration to control and report
//sort order
myGridViewOfComplex.Sort(myGridViewOfComplex.Columns["ComplexColumn"], ListSortDirection.Descending);

C# Structs: Unassigned local variable?

From the documentation:
Unlike classes, structs can be instantiated without using a new operator.
So why am I getting this error:
Use of unassigned local variable 'x'
When I try to do this?
Vec2 x;
x.X = det * (a22 * b.X - a12 * b.Y);
x.Y = det * (a11 * b.Y - a21 * b.X);
Where Vec2 x is a struct?
Well, are X and Y properties (rather than fields)? If so, that's the problem. Until all the fields within x are definitely assigned, you can't call any methods or properties.
For instance:
public struct Foo
{
public int x;
public int X { get { return x; } set { x = value; } }
}
class Program
{
static void Main(string[] args)
{
Foo a;
a.x = 10; // Valid
Foo b;
b.X = 10; // Invalid
}
}
Is Vec2 your own type? Do you have access to the fields involved, or only the properties?
If it's your own type, I would strongly urge you to try to stick to immutable structs. I know managed DirectX has some mutable structs for getting as close to optimal performance as possible, but that's at the cost of strange situations like this - and much worse, to be honest.
I would personally give the struct a constructor taking X and Y:
Vec2 x = new Vec2(det * (a22 * b.X - a12 * b.Y),
det * (a11 * b.Y - a21 * b.X));
It is still uninitialized. You need to initialize it before using it. You can use default operator for that if you don't want to create a static Vec.Empty value and happy with the defaults for the structs members:
Vec2 x = default(Vec2);
Mitch Wheat:
This, however doesn't:
public struct Vec2
{
int x;
int y;
public float X { get { return x; } set { x = value; } }
public float Y { get { return y; } set { y = value; } }
}
static void Main(string[] args)
{
Vec2 x;
x.X = 1;
x.Y = 2;
}
The compiler prevents you from calling propertis on types before all of it's members have been initialized, even though a property might just set one of the values. The solution, as Jon Skeet proposed, is to have an initializing constructor and preferably no setters.

Categories

Resources