Newbye quetion: Why a double can store more number than a long ?

Discussion in 'C Programming' started by jose luis fernandez diaz, May 3, 2004.

  1. Hi,

    My OS is:

    cronos:jdiaz:tmp>uname -a
    HP-UX cronos B.11.11 U 9000/800 820960681 unlimited-user license


    I compile in 64-bits mode the program below:

    cronos:jdiaz:tmp>cat kk.C
    #include <iostream.h>
    #include <limits>

    int main()
    {
    long l_min = numeric_limits<long>::min();
    long l_max = numeric_limits<long>::max();
    double d_min = numeric_limits<double>::min();
    double d_max = numeric_limits<double>::max();
    cout << sizeof(long) << " " << sizeof(double) << endl;
    cout << l_min << " " << l_max << " " << d_min << " " << d_max <<
    endl;


    return 0;
    }
    cronos:jdiaz:tmp>a.out
    8 8
    -9223372036854775808 9223372036854775807 2.22507e-308 1.79769e+308



    The double and long types have the same size, but the double limits
    are bigger. Can anyone explein this to me ?

    Thanks,
    Jose Luis.
     
    jose luis fernandez diaz, May 3, 2004
    #1
    1. Advertising

  2. jose luis fernandez diaz

    Lew Pitcher Guest

    Re: Newbye quetion: Why a double can store more number than a long?

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    jose luis fernandez diaz wrote:
    > Hi,
    >
    > My OS is:
    >
    > cronos:jdiaz:tmp>uname -a
    > HP-UX cronos B.11.11 U 9000/800 820960681 unlimited-user license
    >
    >
    > I compile in 64-bits mode the program below:
    >
    > cronos:jdiaz:tmp>cat kk.C
    > #include <iostream.h>
    > #include <limits>
    >
    > int main()
    > {
    > long l_min = numeric_limits<long>::min();
    > long l_max = numeric_limits<long>::max();

    [snip]

    Well, since you are using a different language from C, we in the comp.lang.c
    newsgroup cannot assist you. Your question does not relate to C, and should be
    (presumably, from the crossposting, was) asked in a forum related to the
    language in which you wrote your example. This appears to be C++, so that forum
    would be comp.lang.c++.


    - --
    Lew Pitcher
    IT Consultant, Enterprise Application Architecture,
    Enterprise Technology Solutions, TD Bank Financial Group

    (Opinions expressed are my own, not my employers')
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.4 (MingW32)

    iD8DBQFAljf6agVFX4UWr64RAnujAJwJ4mOsZZ9THxxul4vwzrvTo/acYwCcDLiJ
    +EqfYBtEqbJjlf/u1b7p2DQ=
    =7HZL
    -----END PGP SIGNATURE-----
     
    Lew Pitcher, May 3, 2004
    #2
    1. Advertising

  3. jose luis fernandez diaz wrote:
    >
    > Hi,
    >
    > My OS is:
    >
    > cronos:jdiaz:tmp>uname -a
    > HP-UX cronos B.11.11 U 9000/800 820960681 unlimited-user license
    >
    > I compile in 64-bits mode the program below:
    >
    > cronos:jdiaz:tmp>cat kk.C
    > #include <iostream.h>
    > #include <limits>
    >
    > int main()
    > {
    > long l_min = numeric_limits<long>::min();
    > long l_max = numeric_limits<long>::max();
    > double d_min = numeric_limits<double>::min();
    > double d_max = numeric_limits<double>::max();
    > cout << sizeof(long) << " " << sizeof(double) << endl;
    > cout << l_min << " " << l_max << " " << d_min << " " << d_max <<
    > endl;
    >
    > return 0;
    > }
    > cronos:jdiaz:tmp>a.out
    > 8 8
    > -9223372036854775808 9223372036854775807 2.22507e-308 1.79769e+308
    >
    > The double and long types have the same size, but the double limits
    > are bigger. Can anyone explein this to me ?


    Well.

    1.79769E308

    does not mean that the number is accurate to the last digit. It means

    1797690000000000000000....000000.....000000
    and the next smallest number is probably something like
    1797680000000000000000....000000.....000000

    so there are large gaps between numbers. Those gaps get smaller when
    the numbers get smaller.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, May 3, 2004
    #3
  4. jose luis fernandez diaz

    Jeff Schwab Guest

    Re: Newbye quetion: Why a double can store more number than a long?

    jose luis fernandez diaz wrote:
    > Hi,
    >
    > My OS is:
    >
    > cronos:jdiaz:tmp>uname -a
    > HP-UX cronos B.11.11 U 9000/800 820960681 unlimited-user license
    >
    >
    > I compile in 64-bits mode the program below:
    >
    > cronos:jdiaz:tmp>cat kk.C
    > #include <iostream.h>


    #include <iostream> // No ".h" extension.

    > #include <limits>
    >
    > int main()
    > {


    using namespace std;

    > long l_min = numeric_limits<long>::min();
    > long l_max = numeric_limits<long>::max();
    > double d_min = numeric_limits<double>::min();
    > double d_max = numeric_limits<double>::max();
    > cout << sizeof(long) << " " << sizeof(double) << endl;
    > cout << l_min << " " << l_max << " " << d_min << " " << d_max <<
    > endl;
    >
    >
    > return 0;
    > }
    > cronos:jdiaz:tmp>a.out
    > 8 8
    > -9223372036854775808 9223372036854775807 2.22507e-308 1.79769e+308
    >
    >
    >
    > The double and long types have the same size, but the double limits
    > are bigger. Can anyone explein this to me ?


    Typically, some of the bits representing a double are interpreted as an
    exponent, and the rest as a multiplier. Floating-point math results in
    approximate results, whereas any operation closed over the field of
    integers will give an exact result when applied to long int's (if we
    discount {over,under}flow).

    http://en.wikipedia.org/wiki/IEEE_floating-point_standard
     
    Jeff Schwab, May 3, 2004
    #4
  5. <posted & mailed>

    The code below isn't C language code, but the question still applies.

    A double can represent larger numbers because it lacks the resolution of the
    long type. For a long integer, you have one number with absolute precision
    for each integer within the range. For a double, you have exactly the same
    number of values as the long, but on average, the difference between each
    individual value and the next is much greater. Instead of counting by 1's,
    you are counting by tens of thousands.

    It may be easier to understand if you think about it this way, a integer
    simply stores a number. A double uses the same number of bits to store two
    numbers: one an integer, and one to tell it where to stick the decimal
    point. The range of integers (where there is precision) is much smaller
    because only a portion of the double is used to store the integral part
    (mantissa) while another portion of the bits is used to store the position
    of the decimal point (exponent). That's a simplification, but you get the
    idea.

    Integers are perfectly precise with a narrow range, and doubles are, on
    average, very imprecise but cover a much wider range. Both doubles and
    integers (in this case, since they are the same number of bits on your
    system) have the same number of values.

    jose luis fernandez diaz wrote:

    > Hi,
    >
    > My OS is:
    >
    > cronos:jdiaz:tmp>uname -a
    > HP-UX cronos B.11.11 U 9000/800 820960681 unlimited-user license
    >
    >
    > I compile in 64-bits mode the program below:
    >
    > cronos:jdiaz:tmp>cat kk.C
    > #include <iostream.h>
    > #include <limits>
    >
    > int main()
    > {
    > long l_min = numeric_limits<long>::min();
    > long l_max = numeric_limits<long>::max();
    > double d_min = numeric_limits<double>::min();
    > double d_max = numeric_limits<double>::max();
    > cout << sizeof(long) << " " << sizeof(double) << endl;
    > cout << l_min << " " << l_max << " " << d_min << " " << d_max <<
    > endl;
    >
    >
    > return 0;
    > }
    > cronos:jdiaz:tmp>a.out
    > 8 8
    > -9223372036854775808 9223372036854775807 2.22507e-308 1.79769e+308
    >
    >
    >
    > The double and long types have the same size, but the double limits
    > are bigger. Can anyone explein this to me ?
    >
    > Thanks,
    > Jose Luis.


    --
    remove .spam from address to reply by e-mail.
     
    James McIninch, May 3, 2004
    #5
  6. jose luis fernandez diaz

    Terry Guest

    "Lew Pitcher" <> wrote in message
    news:MHqlc.17455$...
    > -----BEGIN PGP SIGNED MESSAGE-----
    > Hash: SHA1
    >
    > jose luis fernandez diaz wrote:
    > > Hi,
    > >
    > > My OS is:
    > >
    > > cronos:jdiaz:tmp>uname -a
    > > HP-UX cronos B.11.11 U 9000/800 820960681 unlimited-user license
    > >
    > >
    > > I compile in 64-bits mode the program below:
    > >
    > > cronos:jdiaz:tmp>cat kk.C
    > > #include <iostream.h>
    > > #include <limits>
    > >
    > > int main()
    > > {
    > > long l_min = numeric_limits<long>::min();
    > > long l_max = numeric_limits<long>::max();

    > [snip]
    >
    > Well, since you are using a different language from C, we in the

    comp.lang.c
    > newsgroup cannot assist you. Your question does not relate to C, and

    should be
    > (presumably, from the crossposting, was) asked in a forum related to the
    > language in which you wrote your example. This appears to be C++, so that

    forum
    > would be comp.lang.c++.
    >
    >
    > - --
    > Lew Pitcher
    > IT Consultant, Enterprise Application Architecture,
    > Enterprise Technology Solutions, TD Bank Financial Group
    >


    Not very helpful.

    Regards
     
    Terry, May 3, 2004
    #6
  7. jose luis fernandez diaz

    CBFalconer Guest

    jose luis fernandez diaz wrote:
    >
    > I compile in 64-bits mode the program below:
    >
    > cronos:jdiaz:tmp>cat kk.C
    > #include <iostream.h>
    > #include <limits>
    >
    > int main()
    > {
    > long l_min = numeric_limits<long>::min();
    > long l_max = numeric_limits<long>::max();
    > double d_min = numeric_limits<double>::min();
    > double d_max = numeric_limits<double>::max();
    > cout << sizeof(long) << " " << sizeof(double) << endl;
    > cout << l_min << " " << l_max << " " << d_min << " " << d_max << endl;
    >
    > return 0;
    > }


    C++ is off topic on c.l.c. Please refrain from any such
    cross-postings.

    --
    Some useful references:
    <http://www.ungerhu.com/jxh/clc.welcome.txt>
    <http://www.eskimo.com/~scs/C-faq/top.html>
    <http://benpfaff.org/writings/clc/off-topic.html>
    <http://anubis.dkuug.dk/jtc1/sc22/wg14/www/docs/n869/> (C99)
     
    CBFalconer, May 3, 2004
    #7
  8. jose luis fernandez diaz

    Flash Gordon Guest

    Re: Newbye quetion: Why a double can store more number than a long?

    On Mon, 3 May 2004 17:09:27 +0100
    "Terry" <> wrote:

    <snip C++ code and redirect to comp.lang.c++>

    > Not very helpful.


    Seemed helpful to me. It contained no incorrect information and told the
    OP where help would be available.
    --
    Flash Gordon
    Sometimes I think shooting would be far too good for some people.
    Although my email address says spam, it is real and I read it.
     
    Flash Gordon, May 3, 2004
    #8
  9. jose luis fernandez diaz

    Jack Klein Guest

    Jack Klein, May 4, 2004
    #9
  10. Hi,

    I have made the program below to try to understand how a floating
    point number is made by my computer (HP-UX cronos B.11.11 U 9000/800):

    #include <stdio.h>
    #include <math.h>

    union
    {
    float f;
    unsigned char uc[sizeof(float)];
    } f_union;


    int main()
    {
    f_union.f=1.0F;

    unsigned char u1=1, u2;
    u1 <<= sizeof(unsigned char)*8-1;

    for (int i=0; i < sizeof(float); ++i)
    {
    u2=f_union.uc;
    for(int j=0; j<sizeof(unsigned char)*8; j++)
    {
    printf("%d", ((u1 & u2)!=0));
    u2 <<= 1;
    }
    }
    printf("\n");

    int exp;
    double man = frexp(f_union.f, &exp);
    printf("%lf %d\n%f\n", man, exp,f_union.f);


    return 0;
    }


    but I didn't. Perhaps the program is wrong. Here are some outputs:

    00111111100000000000000000000000
    0.500000 1
    1.000000

    01000000000000000000000000000000
    0.500000 2
    2.000000

    01000000010000000000000000000000
    0.750000 2
    3.000000


    01000000100000000000000000000000
    0.500000 3
    4.000000

    01000000101000000000000000000000
    0.625000 3
    5.000000

    01000001000000000000000000000000
    0.500000 4
    8.000000




    Any hint are welcome.

    Thanks,
    Jose Luis.

    (jose luis fernandez diaz) wrote in message news:<>...
    > Hi,
    >
    > My OS is:
    >
    > cronos:jdiaz:tmp>uname -a
    > HP-UX cronos B.11.11 U 9000/800 820960681 unlimited-user license
    >
    >
    > I compile in 64-bits mode the program below:
    >
    > cronos:jdiaz:tmp>cat kk.C
    > #include <iostream.h>
    > #include <limits>
    >
    > int main()
    > {
    > long l_min = numeric_limits<long>::min();
    > long l_max = numeric_limits<long>::max();
    > double d_min = numeric_limits<double>::min();
    > double d_max = numeric_limits<double>::max();
    > cout << sizeof(long) << " " << sizeof(double) << endl;
    > cout << l_min << " " << l_max << " " << d_min << " " << d_max <<
    > endl;
    >
    >
    > return 0;
    > }
    > cronos:jdiaz:tmp>a.out
    > 8 8
    > -9223372036854775808 9223372036854775807 2.22507e-308 1.79769e+308
    >
    >
    >
    > The double and long types have the same size, but the double limits
    > are bigger. Can anyone explein this to me ?
    >
    > Thanks,
    > Jose Luis.
     
    jose luis fernandez diaz, May 4, 2004
    #10
  11. jose luis fernandez diaz wrote:
    >
    > Hi,
    >
    > I have made the program below to try to understand how a floating
    > point number is made by my computer (HP-UX cronos B.11.11 U 9000/800):
    >


    Your program won't help you in understanding what's the deal with
    floating point numbers and why they have a greater range then eg. long.

    Let us simplify the whole thing in a more familiar environment.
    Assume you are my 'computer'. But I will allow you to calulate
    with 5 digits only (and no sign for simplicity)

    If you use those 5 digits for 'long' only , you can use those 5
    digits to count from 00000 to 99999, so your range is 100000 numbers.
    But you can do different also. You can divide the available 5 digits
    into a mantissa and an exponent. Say you use 2 digits for the exponent
    and the remaining 3 digits for the mantissa (you are familiar with
    sientific notation, are you?). So eg. a number 100 can be represented
    in various ways:

    number scientific not. our notation
    **************************************
    100 100 * 10^0 100 00
    100 10 * 10^1 010 01
    100 1 * 10^2 001 02

    Note: in the column 'our notation', no representation uses more then
    5 digits which fits perfectly to what I allowed to you :)

    Now lets see some other numbers.
    Say you need to represent 1000 in 'out notation'. How can you do that?
    Well you can eg. do 001 03. That would be 1 * 10^3. Or you could do
    010 02 (10 * 10^2), or 100 01 (100 * 10^1). Fine. But now try to represent
    1001 in 'out notation'. You can't. That's because the only way to get there
    would be to increment the mantissa. Let's see whats happening then:

    (1000) 001 03 -> (~1001) 002 03 -> 2 * 10^3 -> 2000
    (1000) 010 02 -> (~1001) 011 02 -> 11 * 10^2 -> 1100
    (1000) 100 01 -> (~1001) 101 01 -> 101 * 10^1 -> 1010

    You see, using only 5 digits, it is impossible to get at the number 1001. You can
    get 1000 and you can get 1010, but no numbers inbetween. It follows from the fact
    that you reserve some of the available 5 digits to represent an exponent, which
    drops the 'range' of numbers representable with the remaining 3 digits. But you
    get the freedome to move the comma around by fiddeling with the exponent. Using
    those 5 digit 'scientific notation' it is easy to represent

    1000 -> 100 01
    10000 -> 100 02
    100000 -> 100 03
    1000000 -> 100 04
    10000000 -> 100 05

    Right now we are way 'over' the upper limit for 5-digit-long, which was
    99999. But we bought this by reducing the granularity. We cannot represent
    all numbers in 10 millions, just some of them.

    100 05 -> 10000000
    101 05 -> 10100000

    All numbers between 10000000 and 10100000 are not representable by our 5 digit
    scheme but need to be approximated by either 10000000 or 10100000.

    Back to your computer. It doesn't use only 5 digits, but much more. Also the
    exponent is not taken to base 10, but to base 2. This reduces the effect you
    just saw. But the principle is still the same. You buy the greater range
    by reducing the granularity.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, May 4, 2004
    #11
  12. Ok. I understand.

    Regards,
    Jose Luis.

    Karl Heinz Buchegger <> wrote in message news:<>...
    > jose luis fernandez diaz wrote:
    > >
    > > Hi,
    > >
    > > I have made the program below to try to understand how a floating
    > > point number is made by my computer (HP-UX cronos B.11.11 U 9000/800):
    > >

    >
    > Your program won't help you in understanding what's the deal with
    > floating point numbers and why they have a greater range then eg. long.
    >
    > Let us simplify the whole thing in a more familiar environment.
    > Assume you are my 'computer'. But I will allow you to calulate
    > with 5 digits only (and no sign for simplicity)
    >
    > If you use those 5 digits for 'long' only , you can use those 5
    > digits to count from 00000 to 99999, so your range is 100000 numbers.
    > But you can do different also. You can divide the available 5 digits
    > into a mantissa and an exponent. Say you use 2 digits for the exponent
    > and the remaining 3 digits for the mantissa (you are familiar with
    > sientific notation, are you?). So eg. a number 100 can be represented
    > in various ways:
    >
    > number scientific not. our notation
    > **************************************
    > 100 100 * 10^0 100 00
    > 100 10 * 10^1 010 01
    > 100 1 * 10^2 001 02
    >
    > Note: in the column 'our notation', no representation uses more then
    > 5 digits which fits perfectly to what I allowed to you :)
    >
    > Now lets see some other numbers.
    > Say you need to represent 1000 in 'out notation'. How can you do that?
    > Well you can eg. do 001 03. That would be 1 * 10^3. Or you could do
    > 010 02 (10 * 10^2), or 100 01 (100 * 10^1). Fine. But now try to represent
    > 1001 in 'out notation'. You can't. That's because the only way to get there
    > would be to increment the mantissa. Let's see whats happening then:
    >
    > (1000) 001 03 -> (~1001) 002 03 -> 2 * 10^3 -> 2000
    > (1000) 010 02 -> (~1001) 011 02 -> 11 * 10^2 -> 1100
    > (1000) 100 01 -> (~1001) 101 01 -> 101 * 10^1 -> 1010
    >
    > You see, using only 5 digits, it is impossible to get at the number 1001. You can
    > get 1000 and you can get 1010, but no numbers inbetween. It follows from the fact
    > that you reserve some of the available 5 digits to represent an exponent, which
    > drops the 'range' of numbers representable with the remaining 3 digits. But you
    > get the freedome to move the comma around by fiddeling with the exponent. Using
    > those 5 digit 'scientific notation' it is easy to represent
    >
    > 1000 -> 100 01
    > 10000 -> 100 02
    > 100000 -> 100 03
    > 1000000 -> 100 04
    > 10000000 -> 100 05
    >
    > Right now we are way 'over' the upper limit for 5-digit-long, which was
    > 99999. But we bought this by reducing the granularity. We cannot represent
    > all numbers in 10 millions, just some of them.
    >
    > 100 05 -> 10000000
    > 101 05 -> 10100000
    >
    > All numbers between 10000000 and 10100000 are not representable by our 5 digit
    > scheme but need to be approximated by either 10000000 or 10100000.
    >
    > Back to your computer. It doesn't use only 5 digits, but much more. Also the
    > exponent is not taken to base 10, but to base 2. This reduces the effect you
    > just saw. But the principle is still the same. You buy the greater range
    > by reducing the granularity.
     
    jose luis fernandez diaz, May 4, 2004
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jose luis fernandez diaz
    Replies:
    13
    Views:
    2,993
    Abhishek
    May 5, 2004
  2. Sydex
    Replies:
    12
    Views:
    6,564
    Victor Bazarov
    Feb 17, 2005
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,074
    Smokey Grindel
    Dec 2, 2006
  4. Steven D'Aprano
    Replies:
    0
    Views:
    116
    Steven D'Aprano
    Dec 23, 2013
  5. Replies:
    3
    Views:
    98
    Gary Herron
    Dec 23, 2013
Loading...

Share This Page