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).
Related
Is it possible to convert float to double, then back without losing precision? I mean first float should be exaclty bit by bit same like result float.
Yes, and we can test it:
float fl = float.NegativeInfinity;
long cycles = 0;
while (true)
{
double dbl = fl;
float fl2 = (float)dbl;
int flToInt1 = new Ieee754.Int32SingleConverter { Single = fl }.Int32;
int flToInt2 = new Ieee754.Int32SingleConverter { Single = fl2 }.Int32;
if (flToInt1 != flToInt2)
{
Console.WriteLine("\nDifferent: {0} (Int32: {1}, {2})", fl, flToInt1, flToInt2);
}
if (fl == 0)
{
Console.WriteLine("\n0, Sign: {0}", flToInt1 < 0 ? "-" : "+");
}
if (fl == float.PositiveInfinity)
{
fl = float.NaN;
}
else if (float.IsNaN(fl))
{
break;
}
else
{
fl = Ieee754.NextSingle(fl);
}
cycles++;
if (cycles % 100000000 == 0)
{
Console.Write(".");
}
}
Console.WriteLine("\nDone");
Console.ReadKey();
and the utility classes:
public static class Ieee754
{
[StructLayout(LayoutKind.Explicit)]
public struct Int32SingleConverter
{
[FieldOffset(0)]
public int Int32;
[FieldOffset(0)]
public float Single;
}
public static float NextSingle(float value)
{
int bits = new Int32SingleConverter { Single = value }.Int32;
if (bits >= 0)
{
bits++;
}
else if (bits != int.MinValue)
{
bits--;
}
else
{
bits = 0;
}
return new Int32SingleConverter { Int32 = bits }.Single;
}
}
On my computer, in Release Mode, without the debugger (Ctrl+F5 from Visual Studio), it is around 2 minutes.
There are around 4 billion different float values. I cast them around and convert them to int to binary check them. Note that NaN values are "particular". The IEEE754 standard has multiple values for NaN, but .NET "compresses" them to a single NaN value. So you could create a NaN value (manually, through bit manipulation) that wouldn't be converted back and forth correctly. The "standard" NaN values is converted correctly, so are PositiveInfinity and NegativeInfinity, +0 and -0.
Yes, as every float can be exactly represented as a double, the round trip will give you the exact value that you started with.
There is one possible technical exception to your requirement that they are bit-by-bit the same: there are multiple bit patterns that correspond to NaN values (this is often referred to as the "NaN payload"). As far as I know, there is no strict requirement that this be preserved: you will still get a NaN, just maybe a slightly different one.
"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.
I am writing an app that requires the calculation of the Gamma function.
A code (part of a class) snippet is below:
namespace PB.Utilities.Math
{
// class definition
public class SpecialFunctions
{
// Private Fields
// Instance Constructor
public SpecialFunctions() {}
// Public Method for Gamma Function
// x = input value; x MUST BE > 0
// GammaLn = secondary output value equal to natural log of Gamma Function
public double Gamma(double x, out double GammaLn)
{
try
{
if (x <= 0) throw new System.ArgumentException("arg <= 0 in GammaFunction", "x");
}
catch
{
System.Console.WriteLine("argument <= 0 in GammaFunction");
System.Console.ReadKey();
}
double gammaln;
double _gamma = gamma(x, out gammaln);
GammaLn = gammaln;
return _gamma;
}
// private method for Gamma Function
private double gamma(double xx, out double gammaln)
{
// private constants
int j;
double x,tmp,y,ser;
const double k1 = 5.24218750000000000;
const double k2 = 0.999999999999997092;
const double k3 = 2.5066282746310005;
double[] cof = new double[14]
{
57.1562356658629235, -59.5979603554754912, 14.1360979747417471,
-0.491913816097620199, 0.339946499848118887e-4, 0.465236289270485756e-4,
-0.983744753048795646e-4, 0.158088703224912494e-3, -0.210264441724104883e-3,
0.217439618115212643e-3, -0.164318106536763890e-3, 0.844182239838527433e-4,
-0.261908384015814087e-4, 0.368991826595316234e-5
};
y = x = xx;
tmp = x + k1;
tmp = (x + 0.5) * System.Math.Log(tmp) - tmp;
ser = k2;
for (j = 0; j < 14; j++) ser += cof[j]/++y;
gammaln = tmp + System.Math.Log(k3*ser/x);
return System.Math.Exp(gammaln);
}
}
}
public class BSA
{
static void Main()
{
// Create an object of type PB.Utilities.Math.SpecialFunctions
PB.Utilities.Math.SpecialFunctions Function = new PB.Utilities.Math.SpecialFunctions();
// Call the public method GammaFunction.
double GammaLn1;
double GammaLn2;
double GammaLn3;
double g1 = Function.Gamma(3.5, out GammaLn1);
double g2 = Function.Gamma(1.5, out GammaLn2);
double g3 = Function.Gamma(1/7, out GammaLn3);
System.Console.WriteLine("g(7/2) = "+g1);
System.Console.WriteLine("g(3/2) = "+g2);
System.Console.WriteLine("g(1/7) = "+g3);
}
}
The issue is that at compilation, the parameter x in Gamma (even though x is being assigned the value 3.5 in the calling component) is assigned a value of 0 which triggers the exception. Can anyone please suggest how I can get around this? Thank you.
Seems to be 3.5 in my test cases. Are you sure you haven't excluded some information that might be the issue?
using System;
namespace Doubletesting
{
class Program
{
static void Main(string[] args)
{
double d = Doubletesting.TestDouble(3.5);
Console.WriteLine(d.ToString());
Console.ReadKey();
}
public static double TestDouble(double x)
{
double result;
result = x;
return result;
}
}
}
Result
3.5
UPDATED
The Error is caused by your Function.Gamma(1 / 7, out GammaLn3). This is because both 1 and 7 are INT and dividing (int)1 by (int)7 is zero. Try Function.Gamma(1f / 7f, out GammaLn3).
I've made a custom "Coordinate" data structure which defines the position of an object according to a certain system.
A coordinate is defined as follows:
public class Coordinate
{
public int X;
public int Y;
private int face;
public int Face
{
get { return face; }
set
{
if (value >= 6 | value < 0)
throw new Exception("Invalid face number");
else
face = value;
}
}
private int shell;
public int Shell
{
get { return shell; }
set
{
if (value < 0)
throw new Exception("No negative shell value allowed");
else
shell = value;
}
}
public Coordinate(int face, int x, int y, int shell)
{
this.X = x;
this.Y = y;
this.face = face;
this.shell = shell;
}
public static Coordinate operator +(Coordinate a, Coordinate b)
{
return new Coordinate(a.Face + b.Face, a.X + b.X, a.Y + b.Y, a.Shell + b.Shell);
}
public override bool Equals(object obj)
{
Coordinate other = (obj as Coordinate);
if (other == null)
return false;
else
return (Face == other.Face && Shell == other.Shell && X == other.X && Y == other.Y);
}
}
Or, to summarize, it contains an int Face (0 to 5), an int X, int Y, and int Shell. X, Y, and Shell are all bound below at 0 (inclusive).
I have no experience at all in hash codes. I need to compare them to see if they are equal. I tried this:
private const int MULTIPLIER = 89;
[...]
int hashCode = 1;
hashCode = MULTIPLIER * hashCode + obj.X.GetHashCode();
hashCode = MULTIPLIER * hashCode + obj.Y.GetHashCode();
hashCode = MULTIPLIER * hashCode + obj.Face.GetHashCode();
hashCode = MULTIPLIER * hashCode + obj.Shell.GetHashCode();
return hashCode;
Going off something I found while Googling. But when I try to compile the code with this method, I'm pretty sure it runs into collisions, as it never finishes building. Probably getting into all sorts of messy loops thinking a bunch of the coordinates are the same or somesuch.
I'm sorry this question is rather elementary, but for some reason I'm stumped. I'm just looking for advice on how to write this hash code so that it doesn't collide.
If well this is not the best way, it can be a good enough approach:
public override int GetHashCode()
{
return string.Format("{0}-{1}-{2}-{3}", X, Y, Face, Shell).GetHashCode();
}
Update:
Take a look at this article: http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/
Basically, when writing hashcode functions, you need to make sure that:
you don't have stale hashcodes (i.e. the state of the object shouldn't change after a hashcode has been generated, such that the hashcode would change if regenerated)
objects with equal values return the same hashcodes
the same object always returns the same hashcode (if it's not modified) -- deterministic
Also, it's great, but not necessary, if:
your hashcodes are uniformly dispersed over the possible values (source: Wikipedia)
You don't need to ensure that different objects return different hashcodes. It's only frowned upon because it can decrease performance of things like Hashtables (if you have lots of collisions).
However, if you still want your hashcode function to return unique values, then you want to know about perfect hashing.
If you use dotnetcore 2.1+, you can use HashCode struct's Combile method, it's very easily to use and efficiency.
For natural sorting in my application I currently P/Invoke a function called StrCmpLogicalW in shlwapi.dll. I was thinking about trying to run my application under Mono, but then of course I can't have this P/Invoke stuff (as far as I know anyways).
Is it possible to see the implementation of that method somewhere, or is there a good, clean and efficient C# snippet which does the same thing?
My code currently looks like this:
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int StrCmpLogicalW(string psz1, string psz2);
}
public class NaturalStringComparer : IComparer<string>
{
private readonly int modifier = 1;
public NaturalStringComparer() : this(false) {}
public NaturalStringComparer(bool descending)
{
if (descending) modifier = -1;
}
public int Compare(string a, string b)
{
return SafeNativeMethods.StrCmpLogicalW(a ?? "", b ?? "") * modifier;
}
}
So, what I'm looking for is an alternative to the above class which doesn't use an extern function.
I just implemented natural string comparison in C#, perhaps someone might find it useful:
public class NaturalComparer : IComparer<string>
{
public int Compare(string x, string y)
{
if (x == null && y == null) return 0;
if (x == null) return -1;
if (y == null) return 1;
int lx = x.Length, ly = y.Length;
for (int mx = 0, my = 0; mx < lx && my < ly; mx++, my++)
{
if (char.IsDigit(x[mx]) && char.IsDigit(y[my]))
{
long vx = 0, vy = 0;
for (; mx < lx && char.IsDigit(x[mx]); mx++)
vx = vx * 10 + x[mx] - '0';
for (; my < ly && char.IsDigit(y[my]); my++)
vy = vy * 10 + y[my] - '0';
if (vx != vy)
return vx > vy ? 1 : -1;
}
if (mx < lx && my < ly && x[mx] != y[my])
return x[mx] > y[my] ? 1 : -1;
}
return lx - ly;
}
}
http://www.interact-sw.co.uk/iangblog/2007/12/13/natural-sorting seems to be what you're looking for.
(and no, there is no managed equivalent to StrCmpLogicalW built into .NET)
I used regular expression to remove special characters. then casting to int. then i compared integers.
input :
List input = new List{ "6.04","6.01","6.03","6#04" };
Expected Output:
6.01
6.03
6.04
6#04
var output = input.OrderBy(s => s, new NaturalStringComparer());
foreach (var sort in output)
{
Console.WriteLine(sort);
}
public struct NaturalStringComparer : IComparer
{
public int Compare(string x, string y)
{
if (x == null && y == null) return 0;
if (x == null) return -1;
if (y == null) return 1;
int lx = x.Length, ly = y.Length;
int a = int.Parse(System.Text.RegularExpressions.Regex.Replace(x, #"\D+", ""));
int b = int.Parse(System.Text.RegularExpressions.Regex.Replace(y, #"\D+", ""));
return a.CompareTo(b);
}
}
If you're running on Windows XP or newer, you can PInvoke to the shell function StrCmpLogicalW:
public static int StrCmpLogical(String s1, String s2)
{
if (String.IsNullOrEmpty(s1) && !String.IsNullOrEmpty(s2))
return 1; //empty s1 comes after s2
else if (String.IsNullOrEmpty(s2) && !String.IsNullOrEmpty(s1))
return -1; //non-empty string comes before empty
return SafeNativeMethods.StrCmpLogicalW(s1, s2);
}
And then the internal unsafe class:
/// <summary>
/// This class suppresses stack walks for unmanaged code permission.
/// (System.Security.SuppressUnmanagedCodeSecurityAttribute is applied to this class.)
/// This class is for methods that are safe for anyone to call.
/// Callers of these methods are not required to perform a full security review to make sure that the
/// usage is secure because the methods are harmless for any caller.
/// </summary>
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
internal static extern Int32 StrCmpLogicalW(string psz1, string psz2);
}