472,958 Members | 2,152 Online

I'm working on a program for my C++ class and have it all written and
working except for one part. I need to compare two numeric variables to
determine decimal accuracy between them. For example:

pi = 3.14159...
mynum = 3.14226...

The mynum is accurate to 2 decimal places compared to pi. I could figure
this out easy with a char array since I could just take a character one at
a time from each array and compare it. However with a numeric variable I'm
coming up short trying to figure this out.

I've had other ideas, but I can't seem to make any of them work right so I
figured I'd go back to my original idea which is to figure out where in
memory the variable is stored using a pointer. Then read each digit in
individually and compare it with the same digit in the same position in the
other variable. If they are equal, add 1 to the precision variable. If
they're not, then leave the loop and the accuracy is whatever precision is
equal to.

I've spent quite a few hours tonight looking in all the C++ books I own and
searching both the Internet and Usenet but to no avail. I suppose I'm
looking for a way to do what I was able to in BASIC all those years ago
like the peek command which would return whatever was in a specific memory
location.

I'm not looking to be given an answer to my problem, just a nudge in the
right direction so I can find it myself. Thanks to any help anyone can
provide.

Dave
--
You can talk about us, but you can't talk without us!
US Army Signal Corps!!

http://www.geocities.com/davidcasey98

Remove IH8SPAM to reply by email!
Jul 22 '05 #1
10 2285
David Casey wrote in news:1w***************@sgtcaseycableone.net in
comp.lang.c++:
I'm not looking to be given an answer to my problem, just a nudge in the
right direction so I can find it myself. Thanks to any help anyone can
provide.

Ok some nudges:

1) C++ float, double and long double types *don't* store there values
as a sequence of char's (at least on any platform I've heard about :).

2) The standard iostreams library alows you to "print" float's to
stream's (see #include <sstream> and std::stringstream).

3) There is also std::sprintf() - but only if you like living
dangerously :)

HTH.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #2
On 20 Oct 2004 03:53:29 GMT, Rob Williscroft wrote in
<news:Xn**********************************@130.133 .1.4>:
Ok some nudges:

1) C++ float, double and long double types *don't* store there values
as a sequence of char's (at least on any platform I've heard about :).
Ah, okay. I can't believe I didn't realize that already. Thanks!
2) The standard iostreams library alows you to "print" float's to
stream's (see #include <sstream> and std::stringstream).

3) There is also std::sprintf() - but only if you like living
dangerously :)

Both of those are a bit ahead of the point my class is in now. I could
probably figure them out but the teacher has already told me to only put in
the programs what we've talked about in class. She is just now talking

Ah well, I'm still tinkering with a math approach to my problem right now.
That is probably where the answer is. I just wasn't sure about the memory
approach, but now I see it won't work how I was thinking.

Thanks!

Dave
Who already knows how to use functions.
--
You can talk about us, but you can't talk without us!
US Army Signal Corps!!

http://www.geocities.com/davidcasey98

Remove IH8SPAM to reply by email!
Jul 22 '05 #3
David Casey wrote:
I'm working on a program for my C++ class and have it all written and
working except for one part. I need to compare two numeric variables to
determine decimal accuracy between them. For example:

pi = 3.14159...
mynum = 3.14226...

The mynum is accurate to 2 decimal places compared to pi. I could figure
this out easy with a char array since I could just take a character one at
a time from each array and compare it. However with a numeric variable I'm
coming up short trying to figure this out.

I've had other ideas, but I can't seem to make any of them work right so I
figured I'd go back to my original idea which is to figure out where in
memory the variable is stored using a pointer. Then read each digit in
individually and compare it with the same digit in the same position in the
other variable. If they are equal, add 1 to the precision variable. If
they're not, then leave the loop and the accuracy is whatever precision is
equal to.

I've spent quite a few hours tonight looking in all the C++ books I own and
searching both the Internet and Usenet but to no avail. I suppose I'm
looking for a way to do what I was able to in BASIC all those years ago
like the peek command which would return whatever was in a specific memory
location.

I'm not looking to be given an answer to my problem, just a nudge in the
right direction so I can find it myself. Thanks to any help anyone can
provide.

If a=0.000000123 and b=0.00000012499 is it accurate to 8 decimal places?

if a=123.1 and b=123.2 is it accurate to 0 decimal places?

Or is it more likely you care about accuracy to a number of significant
digits e.g.

- a=0.000000123 and b=0.00000012499 is accurate to 2 significant digits
- a=123.1 and b=123.2 is it accurate to 3 significant digits

Note that 1+int(log10 X) will give you the location of the first
significant digit of a number. Dividing a number by 10^(int(log10 X))
will give you a "normalized number", if take the normalized correct
answer and the normalized "guess" subtract them and find (-int(log10 X))
of the result, it will probably be very close to the number you're
looking for. You'll need to worry about sign (can't take log of
negative numbers too easily).

If you could get to the mantissa and exponent of the number you're
looking for, you could possibly make you're life very easy. Usually,
floating point numbers are already normalized, so (in most cases - not
all) simple difference of the mantissa and "find first set" will get you
an answer, except it will be in binary significant digits (which can be
converted to decimal significant digits by division by log10(2).

Oooh - frexp seems to do it.

#include [itex]

int exp;
double mantissa = std::frexp( double(x), &exp );

When exp is at the limits of what the double can store, the mantissa is
not normalized, so you can simply call frexp twice and compare the
exponents to be equal both times. Then you can subtract the 2 resulting
mantissas and call std::frexp on the result and the exponent on the
third call will be the negative of the number of significant binary
digits which you can convert to decimal by the siggestion I made earlier.
Jul 22 '05 #4
On Tue, 19 Oct 2004 21:26:51 -0700, Gianni Mariani wrote in
<news:PZ********************@speakeasy.net>:

[snip!]
When exp is at the limits of what the double can store, the mantissa is
not normalized, so you can simply call frexp twice and compare the
exponents to be equal both times. Then you can subtract the 2 resulting
mantissas and call std::frexp on the result and the exponent on the
third call will be the negative of the number of significant binary
digits which you can convert to decimal by the siggestion I made earlier.

I hadn't thought of using stuff like that, but I have found a way which
works great and is about as simple as you can get.

Okay, the variables I'm comparing are a constant which in my program I call
cons_pi and it equals 3.14159265358979. The user enters an integer number
for how many times they want to do that calculation to figure out pi (4/1 -
4/3 + 4/5 - 4/7 etc.). That calculation is placed into calc_pi. Both
these numbers are long doubles to get as many decimal places as I can.

Anyway, the teacher wants us to figure the accuracy of our calculated value
which is where I was stuck trying to figure out a way to compare the two
numeric values.

Well, I decided to multiply each value starting with 10 and then comparing
the int() of each of the variables. If the variables are equal then that
is one position of accuracy and the do-while loop continues while
incrementing the accuracy variable by 1 and incrementing the multiply
variable times 10. If the variables are not equal then there is no more
accuracy possible with the calculated value so flag is set to on and the
do-while loop ends returning the accuracy variable to main().

I just ran from 1 to 50 one-by-one and then various values up to
100,000,000 and it works great. After I clean up the code and give it the
once over again I'll set the program to run through 2,147,483,647 and head
off to bed. Maybe it will be done in the morning when I get up to go to
class. ;-)

It seems I was trying a bit too hard looking for a difficult method to get
the job done with it really ended up being a heck of a lot easier.

Dave
Now I can get to sleep. :-)
--
You can talk about us, but you can't talk without us!
US Army Signal Corps!!

http://www.geocities.com/davidcasey98

Remove IH8SPAM to reply by email!
Jul 22 '05 #5
David Casey wrote:

On Tue, 19 Oct 2004 21:26:51 -0700, Gianni Mariani wrote in
<news:PZ********************@speakeasy.net>:

[snip!]
When exp is at the limits of what the double can store, the mantissa is
not normalized, so you can simply call frexp twice and compare the
exponents to be equal both times. Then you can subtract the 2 resulting
mantissas and call std::frexp on the result and the exponent on the
third call will be the negative of the number of significant binary
digits which you can convert to decimal by the siggestion I made earlier.

I hadn't thought of using stuff like that, but I have found a way which
works great and is about as simple as you can get.

Okay, the variables I'm comparing are a constant which in my program I call
cons_pi and it equals 3.14159265358979. The user enters an integer number
for how many times they want to do that calculation to figure out pi (4/1 -
4/3 + 4/5 - 4/7 etc.). That calculation is placed into calc_pi. Both
these numbers are long doubles to get as many decimal places as I can.

Anyway, the teacher wants us to figure the accuracy of our calculated value
which is where I was stuck trying to figure out a way to compare the two
numeric values.

Why not simply subtract one from the other?
This gives you a measure how 'close' they are.

Hint: You might also want to apply log() to this difference.

--
Karl Heinz Buchegger
Jul 22 '05 #6
On Wed, 20 Oct 2004 10:59:04 +0200, Karl Heinz Buchegger wrote in
I hadn't thought of using stuff like that, but I have found a way which
works great and is about as simple as you can get.

Okay, the variables I'm comparing are a constant which in my program I call
cons_pi and it equals 3.14159265358979. The user enters an integer number
for how many times they want to do that calculation to figure out pi (4/1 -
4/3 + 4/5 - 4/7 etc.). That calculation is placed into calc_pi. Both
these numbers are long doubles to get as many decimal places as I can.

Anyway, the teacher wants us to figure the accuracy of our calculated value
which is where I was stuck trying to figure out a way to compare the two
numeric values.
Why not simply subtract one from the other?
This gives you a measure how 'close' they are.

I tried that already. I don't need the difference between the two, but how
many decimal places are the same in each variable. By multiplying each by
10, 100, 1000, 10000, etc. as needed and taking the int() of each one and
comparing them, it works out great.
Hint: You might also want to apply log() to this difference.

I'll look into that, but the way I came up with is working fine.

Dave
--
You can talk about us, but you can't talk without us!
US Army Signal Corps!!

http://www.geocities.com/davidcasey98

Remove IH8SPAM to reply by email!
Jul 22 '05 #7
David Casey wrote:

I hadn't thought of using stuff like that, but I have found a way which
works great and is about as simple as you can get.

great ...
just as well because what I suggested is probably too hard. It can give
you the number of binary significant digits easily but figuring out the
number of decimal significant digits is not that easy.
#include <cmath>

// returns number of the same significant binary digits
int accuracy( double correct, double guess )
{
if ( correct == guess )
{
return -1; // no real answer
}

if ( ( correct >= 0 ) != ( guess >= 0 ) )
{
return 0;
}

int correct_exp;
double correct_mantissa = std::frexp( correct, &correct_exp );
int guess_exp;
double guess_mantissa = std::frexp( guess, &guess_exp );

if ( correct_exp != guess_exp )
{
return 0;
}

correct_mantissa = std::frexp( correct_mantissa, &correct_exp );
guess_mantissa = std::frexp( guess_mantissa, &guess_exp );
if ( correct_exp != guess_exp )
{
return 0;
}

int diff_exponent;
std::frexp( correct_mantissa - guess_mantissa, &diff_exponent );

return - diff_exponent;
}

#include <iostream>

void testit( double correct, double guess )
{
static const double log10_2 = log(2.0)/log(10.0);

int this_accuracy = accuracy( correct, guess );

std::cout << "accuracy( " << correct << ", " << guess << " ) = " <<
this_accuracy << "\n";

// this is funny - a single bit is accurate to 1 decimal digit (i.e
//1.7 and 1.9
// hve only 1 bit accuracy but are also accurate to 1 decimal digit

// this conversion is not good enough
std::cout << "bogus significant digits = "
<< 1+int(( this_accuracy - 1 ) * log10_2) << "\n";

}

int main()
{

testit( 0.00011221, 0.0001122 );
testit( 3.14159, 3.14259 );
testit( log(3.14159)/log(10.0), log(3.14259)/log(10.0) );
}

Jul 22 '05 #8
David Casey wrote:

On Wed, 20 Oct 2004 10:59:04 +0200, Karl Heinz Buchegger wrote in
I hadn't thought of using stuff like that, but I have found a way which
works great and is about as simple as you can get.

Okay, the variables I'm comparing are a constant which in my program I call
cons_pi and it equals 3.14159265358979. The user enters an integer number
for how many times they want to do that calculation to figure out pi (4/1 -
4/3 + 4/5 - 4/7 etc.). That calculation is placed into calc_pi. Both
these numbers are long doubles to get as many decimal places as I can.

Anyway, the teacher wants us to figure the accuracy of our calculated value
which is where I was stuck trying to figure out a way to compare the two
numeric values.

Why not simply subtract one from the other?
This gives you a measure how 'close' they are.

I tried that already. I don't need the difference between the two, but how
many decimal places are the same in each variable.

I thought that you need that, that's why I hinted at the log()

3.141592654 vs. 3.16

3.141592654 - 3.16 -> -0.018407346
taking the absolute value of that 0.018407346
and the log (to base 10) of that: -1.735008
Hmm. -1.735008, make that positive 1.735008
and discard the fractional part: 1

3.141592654 vs. 3.1417999

3.141592654 - 3.1417999 -> -0.000206346
absolute value 0.000206346
log: -3.6854039
absolute value and fraction discarded: 3

Looks interesting, doesn't it?
--
Karl Heinz Buchegger
Jul 22 '05 #9

"Karl Heinz Buchegger" <kb******@gascad.at> schrieb im Newsbeitrag

3.141592654 vs. 3.16

3.141592654 - 3.16 -> -0.018407346
taking the absolute value of that 0.018407346
and the log (to base 10) of that: -1.735008
Hmm. -1.735008, make that positive 1.735008
and discard the fractional part: 1

3.141592654 vs. 3.1417999

3.141592654 - 3.1417999 -> -0.000206346
absolute value 0.000206346
log: -3.6854039
absolute value and fraction discarded: 3

Looks interesting, doesn't it?

Sure that's why logarithm for base10 is so useful when dealing with decimal
numbers. ;-)
Regards
Michael
Jul 22 '05 #10
David Casey <sg******@IH8SPAMcableone.net> wrote in message news:<1d***************@sgtcaseycableone.net>...
On Wed, 20 Oct 2004 10:59:04 +0200, Karl Heinz Buchegger wrote in

[unimportant...]
Why not simply subtract one from the other?
This gives you a measure how 'close' they are.

I tried that already. I don't need the difference between the two, but how
many decimal places are the same in each variable. By multiplying each by
10, 100, 1000, 10000, etc. as needed and taking the int() of each one and
comparing them, it works out great.
Hint: You might also want to apply log() to this difference.

I'll look into that, but the way I came up with is working fine.

Dave

You are not very bright, are you? On this thread you got twice the
same great answer to your problem and you still refuse to see it.
Learn to listen.

Dan
Jul 22 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.