Thank's for the help all.
I like the inline method as it makes debugging easier (If I ever figure out how to do that)
but I needed to know how to work with globals anyway.
The ulps stuff I'm not to sure about.
I've played with it a bit more and so far I'm not sure that it is needed.
(Of course this may not be corrrect)
namespace And1
{
using System;
using System.Windows.Forms;
using System.Diagnostics;
public class Chere
{
static int Main()
{
const int aa = 1;
float b ;
float a ;
for (int i = -48; i <= 10; i++)
{
a = (float)Math.Pow(10, i);
b = a+aa ;
Console.WriteLine(i);
isEqual(a, b, 5);
}
// These are here to show the numbers print like the article.
//b = 4.2038954e-045f; //3
//a = 1.4012985e-045f; //1
//isEqual(a, b, 5);
//b = 1.99999976f; //1073741822
//a = 2.00000000f; //1073741824
//isEqual(a, b, 1);
return 0;
}
unsafe static int Pointer(float Fl)
{
int i=*(int*)&Fl;
return i;
}
static bool isEqual(float A, float B, int maxUlps)
{
//Comparison showing the usual method
Console.WriteLine("A-B:{0}-{1}={2} ans={3}",A,B,Math.Abs(A - B), Math.Abs(A - B) <0.1e-10);
Debug.Assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
//int aInt = *(int*)&A;
int aInt = Pointer(A);
// Make aInt lexicographically ordered as a twos-complement int
if (aInt < 0)
{
aInt = (int)(0x80000000 - aInt);
}
int bInt = Pointer(B);
if (bInt < 0)
{
bInt = (int)(0x80000000 - bInt);
}
int intDiff =Math.Abs(aInt - bInt);
Console.WriteLine("Ulps: {0}-{1}={2} ans={3}", aInt,bInt,intDiff, intDiff <= maxUlps);
if (intDiff <= maxUlps)
return true;
return false;
}
}
}
In build you need to check unsafe code.(Sounding pretty dubious already,eh!)
Here's a screen shot
A-B:100000-100001=1 ans=False
Ulps: 1203982336-1203982464=128 ans=False
6
A-B:1000000-1000001=1 ans=False
Ulps: 1232348160-1232348176=16 ans=False
7
A-B:1E+07-1E+07=1 ans=False
Ulps: 1259902592-1259902593=1 ans=True
8
A-B:1E+08-1E+08=0 ans=True
Ulps: 1287568416-1287568416=0 ans=True
9
A-B:1E+09-1E+09=0 ans=True
Ulps: 1315859240-1315859240=0 ans=True
10
A-B:1E+10-1E+10=0 ans=True
Ulps: 1343554297-1343554297=0 ans=True
What we have at 8 is both the Ulps and standard version reading true.
So at 9 digits the 1 in 1.000000001 (this doesn't happen with a double at this precision) automagically changes to a zero. So the need for ulps seems less important.
Going the other way (closer to zero) by setting const float aa = 1e-40f; you'll see 5 ulps are way to accurate.