How to tell if a number has decimal places different than 0

Discussion in 'C Programming' started by Gaijinco, Sep 26, 2005.

  1. Gaijinco

    Gaijinco Guest

    Sooner or later everytime I found recreational programming challenges I
    stumble with how I test if a number is has decimal places differnt than
    0?

    For example if I want to know if a number is a square number (i.e. a
    number which square root is a positive number as 4, 9, 16 have) I do
    something like:

    int square = sqrt(number);

    if((int)square==square)
    // number is a perfect square
    else
    // number is not a perfect square

    Is there a function or a language-specific-way to do this?
     
    Gaijinco, Sep 26, 2005
    #1
    1. Advertising

  2. Gaijinco wrote on 26/09/05 :
    > Sooner or later everytime I found recreational programming challenges I
    > stumble with how I test if a number is has decimal places differnt than
    > 0?
    >
    > For example if I want to know if a number is a square number (i.e. a
    > number which square root is a positive number as 4, 9, 16 have) I do
    > something like:
    >
    > int square = sqrt(number);
    >
    > if((int)square==square)
    > // number is a perfect square
    > else
    > // number is not a perfect square
    >
    > Is there a function or a language-specific-way to do this?


    fmod()

    --
    Emmanuel
    The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
    The C-library: http://www.dinkumware.com/refxc.html

    "It's specified. But anyone who writes code like that should be
    transmogrified into earthworms and fed to ducks." -- Chris Dollin CLC
     
    Emmanuel Delahaye, Sep 26, 2005
    #2
    1. Advertising

  3. Gaijinco wrote:
    > Sooner or later everytime I found recreational programming challenges I
    > stumble with how I test if a number is has decimal places differnt than
    > 0?
    >
    > For example if I want to know if a number is a square number (i.e. a
    > number which square root is a positive number as 4, 9, 16 have) I do
    > something like:
    >
    > int square = sqrt(number);
    >
    > if((int)square==square)
    > // number is a perfect square
    > else
    > // number is not a perfect square
    >
    > Is there a function or a language-specific-way to do this?
    >


    Language-specific? What do you mean by that?

    Your test is not perfect because it will fail when square is bigger than
    the biggest int. This test always works (within the limitations of
    floating point accuracy).

    #include <math>

    double square = sqrt(number);
    if (floor(square) == square)
    // number is a perfect square
    else
    // number is not a perfect square

    john
     
    John Harrison, Sep 26, 2005
    #3
  4. Gaijinco

    Eric Sosman Guest

    Gaijinco wrote On 09/26/05 16:07,:
    > Sooner or later everytime I found recreational programming challenges I
    > stumble with how I test if a number is has decimal places differnt than
    > 0?
    >
    > For example if I want to know if a number is a square number (i.e. a
    > number which square root is a positive number as 4, 9, 16 have) I do
    > something like:
    >
    > int square = sqrt(number);
    >
    > if((int)square==square)
    > // number is a perfect square


    .... and the test is a tautology.

    > else
    > // number is not a perfect square
    >
    > Is there a function or a language-specific-way to do this?


    The code you've shown will (if it doesn't invoke
    undefined behavior) declare that every number is a
    perfect square: 1, 2, 3.14, and even -42.

    To test whether a floating-point number is an
    integer with no fractional part, you could try

    if ((int)fpn == fpn) ...

    This runs into trouble when the magnitude of fpn
    is large, so large that its value is outside the range
    of numbers representable as `int'.

    As an improvement you might try

    if (fmod(fpn, 1.0) == 0.0) ...

    This is still vulnerable to the "graininess" of
    floating-point numbers, which are not mathematical real
    numbers with infinite precision.

    You cannot usually expect sqrt(fpn) to be the exact square
    root of fpn. sqrt(fpn) will be very close to the exact root,
    but will (in general) be just a little bit different from the
    true value. There could be several different fpn values for
    which sqrt(fpn) would deliver exactly the same slightly wrong
    answer: both sqrt(4.0) and sqrt(4.0 + tiny_number) might
    produce 2.0 as an answer. If you decide that a number is a
    perfect square if its computed square root turns out to be an
    integer, you will erroneously conclude that 4.0+tiny_number is
    a perfect square.

    A possibly more thorough test might compute the square
    root, test whether it's an integer, and then test whether
    its square equals the original number:

    double root = sqrt(number);
    if (fmod(root, 1.0) == 0.0 && root * root == number)

    .... but even this may have some problems. I am always uneasy
    when comparing floating-point quantities for exact equality,
    mostly because fpn's are usually regarded as approximations
    to begin with. You usually need an "approximately equal"
    test of some kind, and such a test isn't well suited to the
    purely yet/no nature of perfect squaredom.

    For "number-theoretic" calculations you'll usually be much
    better off using integers of some flavor. If the numbers grow
    large you may need to resort to a "bignum" package; several
    are available.

    --
     
    Eric Sosman, Sep 26, 2005
    #4
  5. On Mon, 26 Sep 2005 21:05:09 GMT, in comp.lang.c , John Harrison
    <> wrote:

    (of testing to see if a float is a perfect square)

    >This test always works (within the limitations of
    >floating point accuracy).


    I'd not be too sure of that. Remember floating point is not an exact
    representation.

    >double square = sqrt(number);
    >if (floor(square) == square)
    > // number is a perfect square
    >else
    > // number is not a perfect square

    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Mark McIntyre, Sep 26, 2005
    #5
  6. Mark McIntyre wrote:
    > On Mon, 26 Sep 2005 21:05:09 GMT, in comp.lang.c , John Harrison
    > <> wrote:
    >
    > (of testing to see if a float is a perfect square)
    >
    >
    >>This test always works (within the limitations of
    >>floating point accuracy).

    >
    >
    > I'd not be too sure of that. Remember floating point is not an exact
    > representation.


    That's why I said 'within the limitations of floating point accuracy'.
    My test always checks if a floating point number is integral. Obviously
    an integral return from sqrt does not necessarily mean the sqrt
    parameter was a perfect square.

    john
     
    John Harrison, Sep 26, 2005
    #6
  7. Gaijinco

    Eric Sosman Guest

    John Harrison wrote On 09/26/05 17:20,:
    > Mark McIntyre wrote:
    >
    >>On Mon, 26 Sep 2005 21:05:09 GMT, in comp.lang.c , John Harrison
    >><> wrote:
    >>
    >>(of testing to see if a float is a perfect square)
    >>
    >>
    >>
    >>>This test always works (within the limitations of
    >>>floating point accuracy).

    >>
    >>
    >>I'd not be too sure of that. Remember floating point is not an exact
    >>representation.

    >
    >
    > That's why I said 'within the limitations of floating point accuracy'.
    > My test always checks if a floating point number is integral. Obviously
    > an integral return from sqrt does not necessarily mean the sqrt
    > parameter was a perfect square.


    On the machine in front of me right now, sqrt(1.0)
    and sqrt(1.0000000000000002) both give 1.0 as the root.

    --
     
    Eric Sosman, Sep 26, 2005
    #7
  8. Gaijinco wrote:
    > Sooner or later everytime I found recreational programming challenges I
    > stumble with how I test if a number is has decimal places differnt than
    > 0?
    >
    > For example if I want to know if a number is a square number (i.e. a
    > number which square root is a positive number as 4, 9, 16 have) I do
    > something like:
    >
    > int square = sqrt(number);
    >
    > if((int)square==square)
    > // number is a perfect square
    > else
    > // number is not a perfect square
    >
    > Is there a function or a language-specific-way to do this?
    >


    using modf, you can test either the integral part or the fractional
    part. Look askance at any solution that involves ints.

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

    int main(void)
    {
    double x, fp, ip;
    int loop, cnt;
    srand(time(0));
    for (loop = cnt = 0; cnt < 10; loop++) {
    x = (int) (100. * rand() / (1. + RAND_MAX)) / 10.;
    fp = modf(x, &ip);
    if (ip != x || fp)
    continue;
    printf("%4d: x = %g, fractional part (fp) = %g,"
    "integer part (ip) = %g\n"
    " (ip %s x, fp %s 0)\n", loop, x, fp, ip,
    (ip == x) ? "==" : "!=", (fp == 0) ? "==" : "!=");
    cnt++;
    }
    return 0;
    }


    1: x = 8, fractional part (fp) = 0,integer part (ip) = 8
    (ip == x, fp == 0)
    36: x = 0, fractional part (fp) = 0,integer part (ip) = 0
    (ip == x, fp == 0)
    63: x = 6, fractional part (fp) = 0,integer part (ip) = 6
    (ip == x, fp == 0)
    70: x = 1, fractional part (fp) = 0,integer part (ip) = 1
    (ip == x, fp == 0)
    79: x = 5, fractional part (fp) = 0,integer part (ip) = 5
    (ip == x, fp == 0)
    87: x = 5, fractional part (fp) = 0,integer part (ip) = 5
    (ip == x, fp == 0)
    128: x = 4, fractional part (fp) = 0,integer part (ip) = 4
    (ip == x, fp == 0)
    147: x = 1, fractional part (fp) = 0,integer part (ip) = 1
    (ip == x, fp == 0)
    148: x = 8, fractional part (fp) = 0,integer part (ip) = 8
    (ip == x, fp == 0)
    162: x = 1, fractional part (fp) = 0,integer part (ip) = 1
    (ip == x, fp == 0)
     
    Martin Ambuhl, Sep 26, 2005
    #8
  9. >
    > On the machine in front of me right now, sqrt(1.0)
    > and sqrt(1.0000000000000002) both give 1.0 as the root.
    >


    Am I missing something? What point are you making?

    john
     
    John Harrison, Sep 26, 2005
    #9
  10. John Harrison <> writes:
    [...]
    > #include <math>
    >
    > double square = sqrt(number);
    > if (floor(square) == square)
    > // number is a perfect square
    > else
    > // number is not a perfect square


    I suggest that "square" is a really bad name for a variable that hold
    the result of a call to sqrt().

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Sep 26, 2005
    #10
  11. Gaijinco

    Pete Becker Guest

    Mark McIntyre wrote:
    >
    > I'd not be too sure of that. Remember floating point is not an exact
    > representation.
    >


    Floating point is exact. Unlike real numbers, it is not continuous.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, Sep 27, 2005
    #11
  12. Pete Becker wrote:

    > Mark McIntyre wrote:
    >
    >> I'd not be too sure of that.

    > Remember floating point is not an exact representation.
    >
    > Floating point is exact. Unlike real numbers, it is not continuous.


    In general, *finite precision* floating-point arithmetic is *inexact*.
    The set real numbers includes irrational numbers which have *no*
    finite precision digital representation in this universe --
    they exist only in the minds of mathematicians.
     
    E. Robert Tisdale, Sep 27, 2005
    #12
  13. Pete Becker <> writes:
    > Mark McIntyre wrote:
    >> I'd not be too sure of that. Remember floating point is not an exact
    >> representation.

    >
    > Floating point is exact. Unlike real numbers, it is not continuous.


    It depends on how you look at it. A given floating-point
    representation can be viewed either as an exact value, or as an
    inexact approximation of any of the infinitely many real numbers close
    to the exact represented value. The latter, though arguably
    incorrect, is probably the more common interpretation, especially
    given things like:

    double one_third = 1.0/3.0;

    Integers are usually considered to be exact because they typically
    aren't thought of as being approximations of nearby numbers; 42 really
    is 42, not an approximation of 42.0625.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Sep 27, 2005
    #13
  14. In article <dha13e$ko8$> writes:
    > Pete Becker wrote:
    > > Mark McIntyre wrote:
    > >
    > >> I'd not be too sure of that.

    > > Remember floating point is not an exact representation.
    > >
    > > Floating point is exact. Unlike real numbers, it is not continuous.

    >
    > In general, *finite precision* floating-point arithmetic is *inexact*.


    I think you misunderstand Pete Beckers meaning. Assuming IEEE, given
    two operands and an operation, it is precisely predictable what the
    result is. But I understand you are pretty good at misunderstanding.
    --
    dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
    home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
     
    Dik T. Winter, Sep 27, 2005
    #14
  15. Gaijinco

    Eric Sosman Guest

    John Harrison wrote:
    >>
    >> On the machine in front of me right now, sqrt(1.0)
    >> and sqrt(1.0000000000000002) both give 1.0 as the root.

    >
    > Am I missing something? What point are you making?


    Just giving a concrete example of the point you made
    (and snipped):

    >>> [...] Obviously
    >>> an integral return from sqrt does not necessarily mean the sqrt
    >>> parameter was a perfect square.


    --
    Eric Sosman
    lid
     
    Eric Sosman, Sep 27, 2005
    #15
  16. Gaijinco

    Howard Guest

    "John Harrison" <> wrote in message
    news:uCZZe.21801$...
    > Mark McIntyre wrote:
    >> On Mon, 26 Sep 2005 21:05:09 GMT, in comp.lang.c , John Harrison
    >> <> wrote:
    >>
    >> (of testing to see if a float is a perfect square)
    >>
    >>
    >>>This test always works (within the limitations of floating point
    >>>accuracy).

    >>
    >>
    >> I'd not be too sure of that. Remember floating point is not an exact
    >> representation.

    >
    > That's why I said 'within the limitations of floating point accuracy'. My
    > test always checks if a floating point number is integral. Obviously an
    > integral return from sqrt does not necessarily mean the sqrt parameter was
    > a perfect square.
    >
    > john


    I think a lot of the discussion here is assuming the the "number" variable
    being passed to the sqrt function is a random floating point variable. But,
    I think he was actually asking about testing _integers_, since no value
    containing a fractional part could _ever_ be the square of an integer. If
    we assume that "number" is itself an integer (even if it's stored in a
    float), then testing if the floor of the result of the sqrt call is equal to
    the result itself is a perfectly valid choice. The range of integers is
    sufficently small that there will never be a case where the result of the
    square root will appear to be exactly an integral number when in fact it is
    not. And, if we're dealing with a "number" variable that is actually
    floating point, then it makes sense to first check if that number is itself
    an integer (using floor or fmod) before testing if it's also the square of
    an integer.

    -Howard
     
    Howard, Sep 27, 2005
    #16
  17. Gaijinco

    Gaijinco Guest

    The issue at hand was that I would normally do this for testing if an
    integrer was a square number:

    bool square_number(int number){
    if(sqrt(number)==floor(sqrt(number)))
    return true;
    else
    return false;
    }

    However "sqrt(number)==floor(sqrt(number))" seemed an awkward way to
    test it, so I wasn't sure if there was a "clenear" way to do it.

    "fmod(sqrt(number),1.0)==0.0" seems to be an alternate but it isn't
    very clean to me.

    The facts about integers and operations were very intresting! Thank you.
     
    Gaijinco, Sep 27, 2005
    #17
  18. On Mon, 26 Sep 2005 21:20:26 GMT, in comp.lang.c , John Harrison
    <> wrote:

    >Mark McIntyre wrote:


    (of comparing an int and a float)

    >> I'd not be too sure of that. Remember floating point is not an exact
    >> representation.

    >
    >That's why I said 'within the limitations of floating point accuracy'.


    my point exactly.

    >My test always checks if a floating point number is integral.


    Well, it checks if the floating point number is integral given your
    first constraint.

    Its possible for (int)square <> square, even though 'square' /is/ a
    square number.

    As a general rule any expression involving comparison operators and
    floats should be regarded as /highly/ suspect.
    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Mark McIntyre, Sep 27, 2005
    #18
  19. On Mon, 26 Sep 2005 19:31:05 -0400, in comp.lang.c , Pete Becker
    <> wrote:

    >Mark McIntyre wrote:
    >>
    >> I'd not be too sure of that. Remember floating point is not an exact
    >> representation.
    >>

    >
    >Floating point is exact. Unlike real numbers, it is not continuous.


    Please exactly represent pi in a float.
    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Mark McIntyre, Sep 27, 2005
    #19
  20. Gaijinco

    Kai-Uwe Bux Guest

    Mark McIntyre wrote:

    > On Mon, 26 Sep 2005 19:31:05 -0400, in comp.lang.c , Pete Becker
    > <> wrote:
    >
    >>Mark McIntyre wrote:
    >>>
    >>> I'd not be too sure of that. Remember floating point is not an exact
    >>> representation.
    >>>

    >>
    >>Floating point is exact. Unlike real numbers, it is not continuous.

    >
    > Please exactly represent pi in a float.


    He said, it is not continuous. The point is:

    a) every float represents a unique real number and does so exactly.

    b) not every real number has a representation as a float.


    Of course you can *regard* a real number as an approximation to nearby real
    numbers. Thus, despite (a) being true, one can regard any double as an
    approximation to nearby real nubers. [Depending on context, we do the same
    using intergers: every time I encounter $250, it actually happens to mean
    $249.98+tax.]


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Sep 27, 2005
    #20
    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. Gizmo
    Replies:
    1
    Views:
    3,611
    Jakob Bieling
    Aug 31, 2003
  2. shez

    number of decimal places

    shez, Jan 20, 2005, in forum: C++
    Replies:
    4
    Views:
    6,767
    saurabh.unercat
    Feb 19, 2011
  3. Gaijinco
    Replies:
    27
    Views:
    1,092
    Anonymous 7843
    Sep 28, 2005
  4. harryos
    Replies:
    4
    Views:
    1,660
  5. Dr John Stockton

    Rounding a Number to a String with N decimal places

    Dr John Stockton, Aug 15, 2004, in forum: Javascript
    Replies:
    1
    Views:
    103
    G Roydor
    Aug 15, 2004
Loading...

Share This Page