這很可能與Excel可能已設置的floating point mode有關 - 這意味着您的程序計算的浮點數因承載程序集(DLL)的程序(Excel)而略有不同。這可能會影響計算結果的方式,或者如何/什麼值被自動強制爲零。
要絕對確保你不會碰到不同的浮點模式和/或錯誤的問題,你應該檢查的平等,而通過檢查值非常接近。 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.
我也移植了重新解釋整數比較,如果你找到更適合(它具有較大的價值交易更加一致)。
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;
}
}
您也可以試試和NGen組裝,看看你是否可以解決兩種模式Excel有,或者它是如何託管的CLR。
你是什麼意思「失敗」?你是否遇到異常,是否表現緩慢或其他?代碼的功能在優化時不應改變。 – Botz3000 2012-03-06 17:26:22
如果啓用優化時失敗,則可能是錯誤的...請發佈代碼! – 2012-03-06 17:31:28
如果你已經試過'MethodImpl.NoOptimization'它仍然失敗,我懷疑你的問題是優化(我會懷疑這將是無論如何),這是別的東西。發佈一些代碼。 – 2012-03-06 17:50:16