Author Topic: Fuzz and doubles.  (Read 10377 times)

0 Members and 1 Guest are viewing this topic.

Chuck Gabriel

  • Guest
Re: Fuzz and doubles.
« Reply #30 on: May 11, 2007, 09:23:50 PM »
Hmm.  Declaring an int without initializing it ( int i; ) causes a compiler error in VC# 2005 Express on my machine.  The error is "Use of unassigned local variable 'i'."


Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Fuzz and doubles.
« Reply #31 on: May 11, 2007, 09:36:47 PM »
MSVS2005 compiles and runs it Chuck. Weird, heh ? 

Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

Chuck Gabriel

  • Guest
Re: Fuzz and doubles.
« Reply #32 on: May 11, 2007, 09:40:27 PM »
MSVS2005 compiles and runs it Chuck. Weird, heh ? 

I haven't applied the service pack.  I suppose that could explain it.

LE

  • Guest
Re: Fuzz and doubles.
« Reply #33 on: May 11, 2007, 09:41:33 PM »
I s'pose another debate is
should it be

if (Math.Abs(num1 - num2) < 1.0e-8)

or

if (Math.Abs(num1 - num2) <= 1.0e-8)


I also study the page Bryco linked in one of his posts (some moooons ago), before I was using (and still in some of my c++ routines)

Code: [Select]
#define EPS 1e-05
#define Absolute(a)  ((a) >= 0.0 ? (a) : -(a))
#define EQN(x,y) (Absolute((x) - (y)) <= EPS)
#define EQNPLUS(x, y)(EQN(x,y) || x > y)
#define EQNMINUS(x,y)(EQN(x,y) || x < y)
// For checking near equal floating-point values
#define EPSILON 0.001 //0.0000000001 //0.0001   // tolerance.
#define DOUBLE_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))

Then after all the reading in here:

http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

Code: [Select]
static bool eqDoubles(double i1, double i2, double ftol)
{
double nom, denom, error;
nom = fabs(i1 - i2);
denom = fabs(i1) + fabs(i2);
if (denom != 0)
{
error = 2* nom / denom;
return (error <= ftol);
}
return TRUE;
}

That by simple changing fabs for Math.Abs and TRUE for true to be ported to C#

LE

  • Guest
Re: Fuzz and doubles.
« Reply #34 on: May 11, 2007, 09:49:55 PM »
Hmm.  Declaring an int without initializing it ( int i; ) causes a compiler error in VC# 2005 Express on my machine.  The error is "Use of unassigned local variable 'i'."

using VS2005 pro.... and gets compiled.

Chuck Gabriel

  • Guest
Re: Fuzz and doubles.
« Reply #35 on: May 11, 2007, 09:53:59 PM »
Here is an excerpt from the documentation for the error I receive.

Quote
The C# compiler does not allow the use of uninitialized variables. If the compiler detects the use of a variable that might not have been initialized, it generates CS0165.

LE

  • Guest
Re: Fuzz and doubles.
« Reply #36 on: May 11, 2007, 10:00:11 PM »
Chuck;

I never had the chance to use the express version... but can you change the warning level? to 4 and see if works... maybe...

Chuck Gabriel

  • Guest
Re: Fuzz and doubles.
« Reply #37 on: May 11, 2007, 10:02:16 PM »
Chuck;

I never had the chance to use the express version... but can you change the warning level? to 4 and see if works... maybe...

The warning level defaults to 4.  I changed it to 0 (and made sure 'report warnings as errors' was turned off), but it didn't make any difference.  Results are the same in Debug mode and Release mode.

LE

  • Guest
Re: Fuzz and doubles.
« Reply #38 on: May 11, 2007, 10:14:03 PM »
this is what I have on mine... see if helps :)
« Last Edit: May 15, 2007, 10:30:13 PM by LE »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Fuzz and doubles.
« Reply #39 on: May 11, 2007, 10:20:10 PM »
AHHHHH ...

I see the misunderstanding ..

The Variable can be declared without initializing

but must be subsequently assigned to before it can be used.

In Bryco's original code the initial assignment of false to B was not needed ... as I mentioned.

The subsequent assignment in the if conditional block satisfies the compiler specifications.

I should have been more explicit.



code added :

so the code block could change to ;
 
Code: [Select]
   public static bool FuzzyStuff(double num1,double num2)
    {
            bool B;       
           // bla bla ..
            B = (Math.Abs(num1 - num2) < 1.0e-8);
            return B;
     }

or simply
 
Code: [Select]
   public static bool FuzzyStuff(double num1,double num2)
    {
             return (Math.Abs(num1 - num2) < 1.0e-8);
    }
« Last Edit: May 11, 2007, 10:33:23 PM by Kerry Brown »
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

Chuck Gabriel

  • Guest
Re: Fuzz and doubles.
« Reply #40 on: May 11, 2007, 10:38:09 PM »
Aha.  Thanks for clearing that up for me Kerry.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Fuzz and doubles.
« Reply #41 on: May 11, 2007, 10:51:02 PM »
You're welcome.

My mess, had to clean it up  :|

Just noticed your next post is No. 1000 .. Make the most of it :-)
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

Bryco

  • Water Moccasin
  • Posts: 1851
Re: Fuzz and doubles.
« Reply #42 on: May 13, 2007, 04:30:36 PM »
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)
Code: [Select]
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
Quote
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.

TonyT

  • Guest
Re: Fuzz and doubles.
« Reply #43 on: May 13, 2007, 06:21:41 PM »
Well this was something that can't be done in vba but apparantly works fine in the C's.
The post isn't exactly how it was posted as I've messed with it trying to get a big enough integer.
<snip>

I'll take it from this, that you've not yet discovered Int64 ?


Bryco

  • Water Moccasin
  • Posts: 1851
Re: Fuzz and doubles.
« Reply #44 on: May 13, 2007, 06:31:53 PM »
Not in vba Tony,
I see them in C# and the article recommended using them for doubles instaed of the 32 ints for floats.