GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 26-Apr-2006, 12:57
earachefl earachefl is offline
Member
 
Join Date: Feb 2006
Posts: 178
earachefl is on a distinguished road

Question re comparing large numbers


I'm trying to compare a float with a really large number, 99,999,999,999,999,999,999 to be exact. Don't ask, it's a textbook assignment which I'm modifying somewhat.
CPP / C++ / C Code:
float aNumber;
cin >> aNumber;
if (aNumber > n)
If n is greater than approx. 2,100,000,000, I get a warning:
Quote:
main.cpp:31: warning: this decimal constant is unsigned only in ISO C90


If n is greater than approx. 4,000,000,000, I get error message:
Quote:
main.cpp:31: error: integer constant is too large for 'long' type
If FLT_MAX can handle up to 340282346638528859811704183484516925440.000000
how can I compare such large numbers?

Using XCode 2.2, Mac OS 10.4.5
  #2  
Old 26-Apr-2006, 14:04
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,720
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Question re comparing large numbers


Quote:
Originally Posted by earachefl
I'm trying to compare a float with a really large number, 99,999,999,999,999,999,999 to be exact.


My first question is: how are numerical data represented in your machine? In particular, what data type holds the numeric representation of 99,999,999,999,999,999,999?

Most machines these days are binary, and that's what I will cover here:

To represent that number exactly will require more than 66 bits (2 to the 66 power is something like 7.4 times 10 to the 19 power, and 2 to the 67 power is something like 1.5 times to 10 the 20 power and your number is somewhat greater than 9.9 times 10 to the 19 power).

So, unless your implementation has integer data types with more than 66 bits or floating data types whose fractional part is greater than 66 bits, the task can not be carried out with any built-in arithmetic operations (including comparisons). Period. Full stop.


Quote:
Originally Posted by earachefl

If FLT_MAX can handle up to 340282346638528859811704183484516925440.000000
how can I compare such large numbers?

In typical installations, a float data type consists of a 32-bit binary floating point number, where 24 bits are used for the fractional part and 8 bits are used for the sign and exponent. The maximum magnitude of a floating point number in such a system is approximately 3.40282 times 10 to the 38 power. (A sneaky little trick lets the magnitude be represented by something like 25 bits, equivalent to about six or seven decimal digits.)

Now, if you set a variable equal to FLT_MAX and tell the compiler to print its value using fixed representation, you might see something like 340282346638528859811704183484516925440.000000, but you have to understand that just because it shows you something like 38 or 39 decimal digits, that doesn't mean that the value has 38 correct significant digits. (Note that different compilers may give different values for the non-significant digits, depending on how their output conversion routines are implemented.)

This is important:
You can do floating arithmetic and print out 38 decimal digits (or more if you really want to), but that doesn't mean that there are 38 correct significant digits. In fact given that numbers can be represented with six or seven significant decimal digits, that doesn't mean that the result of arithmetic operations will always have six or seven correct significant digits.

(I hate to repeat myself but this is really, really, really important: There is a difference between "six significant digits" and "six correct significant digits.)

You could try something like the following:
CPP / C++ / C Code:
#include <iostream>
#include <iomanip>
#include <float.h>
using namespace std;

int main()
{
  float f1, f2;
  int i;

  f1 = FLT_MAX;
  f2 = f1-1000000;

  cout << "f1 = " << f1 << endl;
  cout << "f2 = " << f1 << endl;
  cout << endl;
  cout << "Using \"fixed\":" << endl;
  cout << fixed;
  cout << "f1 = " << f1 << endl;
  cout << "f2 = " << f2 << endl;

  f2 = f1;
  i = 0;
  do {
    f1 /= 2.0;
    f2 = f1 - 1;
    // uncomment the following lines to see what it looks like
    // each time through the loop
#if 0
    cout << ++i << endl;
    cout << "f1 = " << f1 << endl
         << "f2 = " << f2 << endl << endl;
#endif
  } while (f1 == f2);

  cout << endl;
  cout << "After the loop: f1= " << f1 << ", f2 = " << f2 << endl;

  f1 = 32554430.0;
  f2 = 32554426.0;
  cout << "f1 = " << f1 << ", f2 = " << f2 << endl;

  return 0;
}

For GNU g++ I got:
Code:
f1 = 3.40282e+38 f2 = 3.40282e+38 Using "fixed": f1 = 340282346638528859811704183484516925440.000000 f2 = 340282346638528859811704183484516925440.000000 After the loop: f1= 33554430.000000, f2 = 33554428.000000 f1 = 32554430.000000, f2 = 32554426.000000

Runs with code from Microsoft and Borland compilers gave similar results, but the outputw with the "fixed" format were different. (As I mentioned, the non-significant parts of the conversion routine outputs might be different.)

Note that with "normal" floating output it shows f1 and f2 to be the same number even though f2 was set equal to f1-1. (Total loss of significance when subtracting nearly-equal floating point numbers is a common occurrence in numerical analysis, and represents a situation for which you must be eternally vigilant.)


Then I go through a loop and set f2 = f1-1 each time and quit when the program sees that they are different (dividing the magnitudes by two for each pass through the loop. After about 103 times through the loop, it finally breaks, but note that the value printed for f1 is not f1-1. (Roundoff error when adding/subtracting small numbers to large numbers is also a source of error in numerical analysis.

Regards,

Dave

Postscript:

If you are interested in (or if you have the need for) dealing with numbers that have more significant digits that your machine/compiler implementation can handle, you could look into some of the "large number" packages that are available. Such as the GNU Multiprecision Package. You can find out more here: GMP Home page
Last edited by davekw7x : 26-Apr-2006 at 14:36.
  #3  
Old 26-Apr-2006, 14:30
earachefl earachefl is offline
Member
 
Join Date: Feb 2006
Posts: 178
earachefl is on a distinguished road

Re: Question re comparing large numbers


Thanks for the most excellent answer. You really showed the effects of floating-point math in a way that my textbook hasn't. It's interesting to know that just using a different compiler can make large-number math possible - I was under the impression that a processor's limits were set in stone, and that one would have to go to a supercomputer for higher level processing.

On a side note, I wish the GMPBench results were updated to include the new Intel DuoCore Macs.
  #4  
Old 26-Apr-2006, 14:41
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,720
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Question re comparing large numbers


Quote:
Originally Posted by earachefl
Thanks for the most excellent answer. You really showed the effects of floating-point math in a way that my textbook hasn't. It's interesting to know that just using a different compiler can make large-number math possible - I was under the impression that a processor's limits were set in stone, and that one would have to go to a supercomputer for higher level processing.

The tradoff: software implementation of arithmetic on non-native data types takes more time. The limitation of integer size in GMP is the amount of memory that your compiler can address with your system (the numbers are in arrays of structs that grow "automatically" as more precision is needed). For example if you multiply two 50-digit decimal integers the result may be as large as 100 decimal digits. It's all done behind the scenes once you declare and initialize your gmp integer data variables. It just blows me away.

Quote:
Originally Posted by earachefl
On a side note, I wish the GMPBench results were updated to include the new Intel DuoCore Macs.

Sounds like a good project for someone with sufficient

1. Hardware
2. Interest
3. Time

Regards,

Dave
  #5  
Old 01-May-2006, 08:15
cjavac#c++_vbP cjavac#c++_vbP is offline
Junior Member
 
Join Date: Mar 2006
Location: Miami, FL
Posts: 42
cjavac#c++_vbP is on a distinguished road

Re: Question re comparing large numbers


interesting question and answers.
 
 

Recent GIDBlogDeveloping GUIs with wxPython (Part 2) by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Binary number systems: BCD, twos complement, ones complement, etc. machinated Miscellaneous Programming Forum 6 08-Feb-2006 10:51
subscript error in coding warborules C Programming Language 6 27-Nov-2005 17:16
Large numbers... Bruno Couto C Programming Language 2 30-Sep-2005 07:23
Linear Search eccoflame C Programming Language 3 19-Apr-2005 08:36
Simple question on arrays--please help! brookeville C++ Forum 16 17-Nov-2004 23:23

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 20:50.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.