Click here to Skip to main content
15,903,856 members
Please Sign up or sign in to vote.
3.67/5 (3 votes)
See more:
assembly code will do.I want to integrate it into my embarcadero c++ polygon clipping algorithm.
I need a c++ function which takes a double precision number and strips of the last n lsb bits from
a double.
I am only a occasional c++ programmer.
Posted
Updated 24-Aug-12 4:54am
v2
Comments
[no name] 24-Aug-12 9:44am    
Okay go right ahead and do that. Perhaps you meant to ask some sort of a question?
Christian Graus 24-Aug-12 9:46am    
Surely someone who can write a 'polygon clipping algorithm' can write a bit of code to strip bits from a number ?
[no name] 24-Aug-12 9:48am    
You would think that someone that has been a member of CP for the past 8+ years would know how to use the site by now.
Shunya 24-Aug-12 10:48am    
sorry,i come to the site rarely.
My need was how to write a c++ function like round which returns a value
back after stripping the last n lsb bits.Input is a double precision number.
Shunya 24-Aug-12 10:48am    
You think so?.

I suspect that the reason you think you want this, is because you're getting comparison errors from artifacts in the double precision math.

Numbers that should be mathematically equivalent according to the formulas they were produced from, are not equivalent in practice.

Stripping bits is a shortcut that won't solve the problem. It'll introduce it's own errors.

Applying error ranges to your operations, is the only reliable way to make this work.

Take a look at this function to see how it's done.

C++
bool AlmostEqualDoubles2(double nVal1, double nVal2, double nEpsilon)
{
	bool bRet = (((nVal2 - nEpsilon) < nVal1) && (nVal1 < (nVal2 + nEpsilon)));
	return bRet;
}

Reliable Floating Point Equality Comparison[^]

Or possibly..
C++
#define AlmostEqualDoubles2(nVal1, nVal2, nEpsilon) \
    ((((nVal2) - (nEpsilon)) < (nVal1)) && ((nVal1) < ((nVal2) + (nEpsilon))));
 
Share this answer
 
v3
Comments
Shunya 25-Aug-12 5:22am    
very right.
I was in my code, checking that both values have the same exponent,and if so
allowing the rest of the value to differ in the 2 lsbs.--This is NOT a elegant way to do comparision of IEEE numbers but I am exploring some extremely rare funny errors I get.I will NOT use this code in the routine later.
Something like this?

I'm not so sure you'll find it useful.

C++
// StripDoubleBits.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
    int nBits = 4;
    double OriginalValue = 1.0 / 9.0;
    double StrippedValue = OriginalValue;
    ((unsigned __int32 *) &StrippedValue)[1] &= (0xFFFFFFFF << nBits);

    printf("Original Hex Value = %08X%08X\n", ((unsigned __int32 *) &OriginalValue)[0], ((unsigned __int32 *) &OriginalValue)[1]);
    printf("Stripped Hex Value = %08X%08X\n", ((unsigned __int32 *) &StrippedValue)[0], ((unsigned __int32 *) &StrippedValue)[1]);

    printf("Original Value = %0.17f\n", OriginalValue);
    printf("Stripped Value = %0.17f\n", StrippedValue);

    return 0;
}
 
Share this answer
 
v3
I'm assuming you're using the MS compiler, but if not you may have to adjust the types (long long is the 64-bit integer type in the MS 32-bit compiler, which is why I used it here to match the size of double, but the size of primitives can vary between compilers).

C++
double stripBits(int n, double value) {
    long long intVal = *((long long*)&value); // Convert the value to the binary-equivalent integer type

    long long mask = ~0; // start mask at all 1's

    // set n bits to 0, starting at the end
    for (long long i = 0; i < n; ++i)
    {
        mask -= (1 << i);
    }

    intVal &= mask; // apply mask

    return *((double*)&intVal); // return value with mask applied as a double
}
 
Share this answer
 
Comments
Shunya 25-Aug-12 5:28am    
YES,THIS IS WHAT i WANTED.THANKS.
I convert the bit pattern to a 64 bit integer ,do the required bit clearance,
and convert to double again.!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900