All computer source code presented on this page, unless it includes attribution to another author, is provided by Ed Halley under the Artistic License. Use such code freely and without any expectation of support. I would like to know if you make anything cool with the code, or need questions answered.
python/
    bindings.py
    boards.py
    buzz.py
    caches.py
    cards.py
    constraints.py
    csql.py
    english.py
    getch.py
    getopts.py
    gizmos.py
    goals.py
    improv.py
    interpolations.py
    namespaces.py
    nihongo.py
    nodes.py
    octalplus.py
    patterns.py
    physics.py
    pids.py
    pieces.py
    quizzes.py
    recipes.py
    relays.py
    romaji.py
    ropen.py
    sheets.py
    stores.py
    strokes.py
    subscriptions.py
    svgbuild.py
    testing.py
    things.py
    timing.py
    ucsv.py
    useful.py
    uuid.py
    vectors.py
    weighted.py
java/
    CSVReader.java
    CSVWriter.java
    GlobFilenameFilter.java
    RegexFilenameFilter.java
    StringBufferOutputStream.java
    ThreadSet.java
    Throttle.java
    TracingThread.java
    Utf8ConsoleTest.java
    droid/
        ArrangeViewsTouchListener.java
        DownloadFileTask.java
perl/
    CVQM.pm
    Kana.pm
    Typo.pm
cxx/
    CCache.h
    equalish.cpp
Download equalish.cpp
// equalish.h : Functions for comparing floating-point numbers generically.
//

#ifndef __EQUALISH_H__
#define __EQUALISH_H__

// Inspired by the discussion found at:
// http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

/////////////////////////////////////////////////////////////////////////////

#define equalish AlmostEqual2sComplement

/////////////////////////////////////////////////////////////////////////////

bool AlmostEqualUlps(float A, float B, int maxUlps=10);
bool AlmostEqual2sComplement(float A, float B, int maxUlps=10);

#ifdef _DEBUG

bool test_equalish();

#endif // _DEBUG

/////////////////////////////////////////////////////////////////////////////

#endif // __EQUALISH_H__

//------------------------------------------------>8--( cut here )-----------
// equalish.cpp

#include "equalish.h"

bool AlmostEqualUlps(float A, float B, int maxUlps /* = 10 */)
{
    assert(sizeof(float) == sizeof(int));
    if (A == B)
        return true;
    int intDiff = abs(*(int*)&A - *(int*)&B);
    if (intDiff <= maxUlps)
        return true;
    return false;
}

bool AlmostEqual2sComplement(float A, float B, int maxUlps /* = 10 */)
{
    // Make sure maxUlps is non-negative and small enough that the
    // default NAN won't compare as equal to anything.
    assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
    int aInt = *(int*)&A;
    // Make aInt lexicographically ordered as a twos-complement int
    if (aInt < 0)
        aInt = 0x80000000 - aInt;
    // Make bInt lexicographically ordered as a twos-complement int
    int bInt = *(int*)&B;
    if (bInt < 0)
        bInt = 0x80000000 - bInt;
    int intDiff = abs(aInt - bInt);
    if (intDiff <= maxUlps)
        return true;
    return false;
}

/////////////////////////////////////////////////////////////////////////////

#ifdef _DEBUG

#include <stdio.h>

bool test_equalish()
{
        bool success = TRUE;

        try
        {
                int i;
                float f;
                for (i = 0, f = -1.0; f <= 1.0; f += 1.0/9.0, i++)
                {
                        // f is far enough from zero that tiny offsets are insignificant
                        assert(equalish(f - 0.000000000000001, f + 0.000000000000001));
                        if (i == 9) 
                        {
                                // f should be close to zero; tiny offsets are more significant
                                assert(!equalish(f - 0.000000000001, f + 0.0000000000001));
                        }
                }
        }
        catch(exception e)
        {
                printf("exception: %s\n", e.what());
                success = FALSE;
        }

        return success;
}

#endif // _DEBUG


Contact Ed Halley by email at ed@halley.cc.
Text, code, layout and artwork are Copyright © 1996-2013 Ed Halley.
Copying in whole or in part, with author attribution, is expressly allowed.
Any references to trademarks are illustrative and are controlled by their respective owners.
Make donations with PayPal - it's fast, free and secure!