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

0 Members and 1 Guest are viewing this topic.

Bryco

  • Water Moccasin
  • Posts: 1883
Fuzz and doubles.
« on: May 10, 2007, 10:57:42 PM »
I couldn't find this on this board, but coming from vba I use it all the time.
Is it a concern?
If so has anyone got the ulps method to work?
I would say my main reason to need it is to test a value against zero or pi.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Fuzz and doubles.
« Reply #1 on: May 10, 2007, 11:57:55 PM »
OK, I'll play ..

Whats the ulps Method ?

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

LE

  • Guest
Re: Fuzz and doubles.
« Reply #2 on: May 11, 2007, 12:03:07 AM »
I couldn't find this on this board, but coming from vba I use it all the time.
Is it a concern?
If so has anyone got the ulps method to work?
I would say my main reason to need it is to test a value against zero or pi.

Do a combination of Math.Abs(num2 - num1) <= fuzz [where fuzz is Double fuzz = 0.0001 or whatever] unless there is some built-in function in C#, that I have no idea.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Fuzz and doubles.
« Reply #3 on: May 11, 2007, 12:08:27 AM »
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.

Well if there is a way I don't need it I won't bother playing with it. I just dont know.

Code: [Select]
'Reading           http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm


'Paul Marshall http://www.cadvault.com/forums/showthread.php?t=15869&page=4&pp=10
Public Function IsEqual(ByVal a As Single, ByVal B As Single, maxUlps As Long) As Boolean
    ' Make sure maxUlps is non-negative and small enough that the
    ' default NAN won't compare as equal to anything.
    'maxUlps = 5  'I use this
    If Not (maxUlps > 0 And maxUlps < 4& * 1024 * 1024) Then
        Debug.Print "maxUlps out of range"
        Stop
    End If
    Dim aInt As Long 'originally integer
    CopyMemory aInt, a, 4
    ' Make aInt lexicographically ordered as a twos-complement int
    If aInt < 0 Then
        aInt = &H80000000 - aInt
    End If
    ' Make bInt lexicographically ordered as a twos-complement int
    Dim bInt As Long 'originally integer
    CopyMemory bInt, B, 4
    If bInt < 0 Then
        bInt = &H80000000 - bInt
    End If
    ' We need the range of an unsigned Long but
    '   there are no unsigned types available in VB
    '   (other than Byte).
    Dim intDiff As Currency
    intDiff = Abs(CCur(aInt) - bInt)
    Debug.Print a, "Long      " & aInt, bInt, intDiff
    If intDiff <= maxUlps Then
        IsEqual = True
    Else
        IsEqual = False
    End If
End Function

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Fuzz and doubles.
« Reply #4 on: May 11, 2007, 12:11:17 AM »
Le that's what I do in vba and it works fine for me as I work in small numbers. But ulps seem to give a well rounded solution.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Fuzz and doubles.
« Reply #5 on: May 11, 2007, 12:16:51 AM »
ahhh ...

 Ulps ~= Units in the Last Place
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Fuzz and doubles.
« Reply #6 on: May 11, 2007, 12:31:12 AM »
It looks nice, even the percentage comparison looks better that the basic test that I use. I don't know if it works for doubles as they show floats, I just spent 5 minutes trying to find what was wrong with something that I knew was correct to find out that "If" (the one I've been typing for years ) doesn't work but "if" does. Ahhhhhhh! Any way I'll test the code out for doubles some time before xmas.

Glenn R

  • Guest
Re: Fuzz and doubles.
« Reply #7 on: May 11, 2007, 01:33:28 AM »
I just spent 5 minutes trying to find what was wrong with something that I knew was correct to find out that "If" (the one I've been typing for years ) doesn't work but "if" does. Ahhhhhhh!

Hehe...welcome to the beautifull world of case based languages. Once you get used to it, you'll never go back...trust me  :evil:

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Fuzz and doubles.
« Reply #8 on: May 11, 2007, 01:42:29 AM »
Bryce, confirming the case fun ... though didn't the VB IDE take over and change case for you ??

I still regularly put a parenthesis in front of the (if ....
and just as regularly type ;; instead of // for a comment ... sometimes I think that some of the synapses are welded shut.  :|
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8690
  • AKA Daniel
Re: Fuzz and doubles.
« Reply #9 on: May 11, 2007, 02:16:21 AM »
I still regularly put a parenthesis in front of the (if ....
and just as regularly type ;; instead of // for a comment ...

Oh man, I do this too

Chuck Gabriel

  • Guest
Re: Fuzz and doubles.
« Reply #10 on: May 11, 2007, 08:08:37 AM »
Bryce, confirming the case fun ... though didn't the VB IDE take over and change case for you ??

I still regularly put a parenthesis in front of the (if ....
and just as regularly type ;; instead of // for a comment ... sometimes I think that some of the synapses are welded shut.  :|

I frequently catch myself putting commas between function arguments in lisp code.

We need one syntax to rule them all. :-)

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Fuzz and doubles.
« Reply #11 on: May 11, 2007, 09:48:23 AM »
Hehe, I'm glad that it's not just me.
Kerry the vbaide forces the capital I in If,

actually I had just copied
Code: [Select]
Function Rd(num1 As Variant, num2 As Variant) As Boolean
    Dim dRet As Double
    dRet = num1 - num2
    If Abs(dRet) < 0.00000001 Then Rd = True
End Function
to C# thinking that nothing could be easier.
(Morphs into Hatch for a minute)
Oops no boolean in help, ok got it bool.
Abs, no no help on that. Ah add using system.Math.Abs
Oh, better not call this class Math then, changes it to MyMath.
public static bool Rd(double num1,double num2), why is the )lighting up? static public bool Rd, nope still red (Wonders if it the order makes any difference)
static bool Rd, still red static void. Oh need to put the bracket thing on the next line. (It lights up the ")" as it's wrong in the future, as in the next line)
Code: [Select]
    public static bool Rd(double num1,double num2)
    {
        double dRet = num1 - num2;
        bool B=false;
        If (math.Abs(dRet) < 0.00000001)
        {
          B= true;
        }
        else
        {
            B= false;
        }
        return B;
    }
It's red on the if line, staring at for 5 mins with hatred does little to fix it,finally If.
This is when I posted to make sure I even need this function.
I've still got to figure out the top line
double num1,double num2 needs to be maybe object num1,object num2? as it is not always a double being fed to the function.
Right now $250 for the standard edition sounds like a cheap investment to take some of the agro out of learning this program.

sinc

  • Guest
Re: Fuzz and doubles.
« Reply #12 on: May 11, 2007, 12:23:23 PM »
What are you using for an IDE?  C# syntax typically has the "if" in all lower-case letters.

Typically, I don't use a special function for this.  I will just include a line like the following right where it belongs in the code:

Code: [Select]
if (Math.Abs(num1 - num2) < fuzz)
{
    [other code...]
}

...where "fuzz" is a global constant.  This is straight-forward, simple, and easy-to-read.  If I saw a code with an "Rd()" function, that would constantly throw me, because my mind would want to interpret it as Round().

If you want to make one function that can handle different types, you would probably just want to overload the method, rather than use type "object".  This is easier to code, easier to read, and has less run-time overhead than one method that tries to handle multiple types.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Fuzz and doubles.
« Reply #13 on: May 11, 2007, 01:24:22 PM »
Sinc that sounds like the GO, (if I can figure out the global part.)
Yes the C# ide is awesome, I just copied in this code in and the If stays as it is.
Kerry's comment about learn C# language first then learn how to use it with cad is of course spot on.
But, but, but. (Grosshopper learn to love the pain.)

sinc

  • Guest
Re: Fuzz and doubles.
« Reply #14 on: May 11, 2007, 04:21:10 PM »
There are a number of ways to do the global thing.  I'm not really sure of the best way in C#.  Maybe someone with more C# experience can chime in.

In the past, I've usually used #define directives to define a variable in the compiler.

But lately with C#, I've been using a "container class" and static variables to hold my global defaults, as in the attached sample.  For example, assuming the attached sample is a class in my project, I might access the NOD key for my application's standard Named Object Dictionary using something like this:

         Database db = Application.DocumentManager.MdiActiveDocument.Database;
         using (Transaction tr = db.TransactionManager.StartTransaction()) {
            DBDictionary NOD = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite);
            DBDictionary spDict;
            try {
               spDict = (DBDictionary)tr.GetObject(NOD.GetAt(SincpacDefaults.ApplicationNODKey), OpenMode.ForRead);
            }
         }

The benefit to this last way is that I can change the global defaults without affecting any other code.  This is more of a benefit if you have a larger project, and compile the code into multiple DLLs.  If you ever change any of your defaults, you only need to recompile the DLL that contains this class, and all other code remains unaffected.  With a compiler directive you would need to recompile everything if it changed.  I might be overthinking this, but it seems to work well.

Code: [Select]
/*
 * Created by SharpDevelop.
 * User: Sinc
 * Date: 4/6/2007
 * Time: 9:35 PM
 */

using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AECC.Interop.Land;
using Civil3DUtilities;

namespace Sincpac
{
/// <summary>
/// Description of SincpacDefaults.
/// </summary>
public class SincpacDefaults
{
// Name of subsection for storing Global values
private const string globalRegistryKeyName = "Sincpac";

// Similar to above; contains the name of the dictionary in the NOD
private const string applicationNODKey = "SINCPAC-C3D";

public static string GlobalRegistryKeyName
{
get { return globalRegistryKeyName; }
}

public static string ApplicationNODKey
{
get { return applicationNODKey; }
}
}
}