char -> int

Discussion in 'C Programming' started by ern, Sep 27, 2005.

  1. ern

    ern Guest

    Anybody know a quick and dirty function for going from "547.6458679" to
    the integer version 548 ?

    i.e.

    int returnIntegerEquivalent(char * charNum){
    int intNum;
    //Do some stuff...
    return intNum;
    }

    I was using the Windows stuff before (ie _gcvt() and atof()).
    Thanks,
    ern, Sep 27, 2005
    #1
    1. Advertising

  2. ern

    John Bode Guest

    ern wrote:
    > Anybody know a quick and dirty function for going from "547.6458679" to
    > the integer version 548 ?
    >
    > i.e.
    >


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

    > int returnIntegerEquivalent(char * charNum){
    > int intNum;


    double dNum = strtod(charNum, NULL);
    if (ceil(dNum) - dNum > 0.5)
    intNum = (int) floor(dNum);
    else
    intNum = (int) ceil(dNum);

    > return intNum;
    > }
    >
    > I was using the Windows stuff before (ie _gcvt() and atof()).
    > Thanks,
    John Bode, Sep 27, 2005
    #2
    1. Advertising

  3. "ern" <> wrote in message
    news:...
    > Anybody know a quick and dirty function for going from "547.6458679" to
    > the integer version 548 ?


    rounding to +infinity is done with ceil()
    examples:
    547.6 -> 548
    547.4 -> 548
    547 -> 547
    -547.4 -> -547
    -547.6 -> -547

    rounding to -infinity is done with floor()
    examples:
    547.6 -> 547
    547.4 -> 547
    547 -> 547
    -547.4 -> -548
    -547.6 -> -548

    truncating the fractional part is done by converting/casting to integer
    type:
    547.6 -> 547
    547.4 -> 547
    547 -> 547
    -547.4 -> -547
    -547.6 -> -547

    rounding to the nearest integer can be achieved from truncating if 0.5 is
    first [added to]/[subtracted from] the number being rounded:
    547.6+0.5 -> 548
    547.4+0.5 -> 547
    547+0.5 -> 547
    -547.4-0.5 -> -547
    -547.6-0.5 -> -548

    Something like that,
    Alex
    Alexei A. Frounze, Sep 27, 2005
    #3
  4. ern

    tedu Guest

    ern wrote:
    > Anybody know a quick and dirty function for going from "547.6458679" to
    > the integer version 548 ?
    >
    > i.e.
    >
    > int returnIntegerEquivalent(char * charNum){
    > int intNum;
    > //Do some stuff...


    intNum = atof(charNum) + 0.5;

    > return intNum;
    > }
    >
    > I was using the Windows stuff before (ie _gcvt() and atof()).
    > Thanks,
    tedu, Sep 27, 2005
    #4
  5. "ern" <> wrote in message
    news:...
    > Anybody know a quick and dirty function for going from "547.6458679" to
    > the integer version 548 ?
    >
    > i.e.
    >
    > int returnIntegerEquivalent(char * charNum){
    > int intNum;
    > //Do some stuff...
    > return intNum;
    > }
    >
    > I was using the Windows stuff before (ie _gcvt() and atof()).
    > Thanks,
    >


    I'm not sure how "dirty" (or quick, for that matter) it is, but you'll
    probably want to look into the strtol() function:
    http://ccs.ucsd.edu/c/stdlib.html#strtol. More intuitively, you could
    convert the string to a (double) using the related strtod() function
    (http://ccs.ucsd.edu/c/stdlib.html#strtod), and then cast the result to an
    (int), especially since you have to do that anyway with strtol() unless you
    declare "intNUM" of type (long).

    -Charles
    Charles M. Reinke, Sep 27, 2005
    #5
  6. ern wrote:
    > Anybody know a quick and dirty function for going from "547.6458679" to
    > the integer version 548 ?
    >
    > i.e.
    >
    > int returnIntegerEquivalent(char * charNum){
    > int intNum;
    > //Do some stuff...
    > return intNum;
    > }
    >
    > I was using the Windows stuff before (ie _gcvt() and atof()).
    > Thanks,
    >

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

    /* making no assumption that s represents an value in the range of an
    int, but accepting that some initial portion is supposed to represent
    a legal double value. 0 is returned (with errno set) if a problem occurs
    with the string to float conversion. */

    double floatingstring2floatingint(const char *s)
    {
    double x, fp, ip;
    int sign = 1;
    errno = 0;
    x = strtod(s, 0);
    if (errno)
    return 0;
    if (x < 0) {
    sign = -1;
    x = -x;
    }
    fp = modf(x, &ip);
    if (fp >= .5)
    ip++;
    return sign * ip;
    }

    int main(void)
    {
    char s[] = "547.6458679";
    char t[] = "-547.6458679";
    printf("The initial string (s) is \"%s\n", s);
    printf("floatingstring2floatingint(s) returns %g\n",
    floatingstring2floatingint(s));
    printf("The initial string (t) is \"%s\n", t);
    printf("floatingstring2floatingint(t) returns %g\n",
    floatingstring2floatingint(t));
    return 0;
    }



    The initial string (s) is "547.6458679
    floatingstring2floatingint(s) returns 548
    The initial string (t) is "-547.6458679
    floatingstring2floatingint(t) returns -548
    Martin Ambuhl, Sep 27, 2005
    #6
  7. "Charles M. Reinke" <> wrote in message
    news:dhcbhs$cgl$...
    > "ern" <> wrote in message
    > news:...
    > > Anybody know a quick and dirty function for going from "547.6458679" to
    > > the integer version 548 ?
    > >
    > > i.e.
    > >
    > > int returnIntegerEquivalent(char * charNum){
    > > int intNum;
    > > //Do some stuff...
    > > return intNum;
    > > }
    > >
    > > I was using the Windows stuff before (ie _gcvt() and atof()).
    > > Thanks,
    > >

    >
    > I'm not sure how "dirty" (or quick, for that matter) it is, but you'll
    > probably want to look into the strtol() function:
    > http://ccs.ucsd.edu/c/stdlib.html#strtol. More intuitively, you could
    > convert the string to a (double) using the related strtod() function
    > (http://ccs.ucsd.edu/c/stdlib.html#strtod), and then cast the result to an
    > (int), especially since you have to do that anyway with strtol() unless

    you
    > declare "intNUM" of type (long).
    >
    > -Charles
    >


    After sending my inital response I realized that the proper solution could
    be a little complicated, hence the following code:
    holomask>cat h.c
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>

    int returnIntegerEquivalent(char *charNum) {
    int intNum;
    char *str_test;

    intNum = floor(strtod(charNum, &str_test)+0.5);
    if(charNum==str_test)
    printf("Error converting string.\n");

    return intNum;
    } /* returnIntegerEquivalent */

    int main(void) {
    int intNum;
    char charNum[]="547.6458679";

    intNum = returnIntegerEquivalent(charNum);
    printf("test string: %s\ninteger value: %d\n", charNum, intNum);

    return 0;
    } /* main */
    holomask>gcc -Wall -ansi -pedantic -lm -o h.exe h.c
    holomask>h.exe
    test string: 547.6458679
    integer value: 548
    Charles M. Reinke, Sep 27, 2005
    #7
  8. "Charles M. Reinke" <> wrote in
    news:dhch41$esl$:

    > intNum = floor(strtod(charNum, &str_test)+0.5);
    > if(charNum==str_test)
    > printf("Error converting string.\n");


    In cases like this, it might be more useful to test that the string
    contained nothing other than a valid number. For example, the test above
    would not raise an error if

    "547.64.58679"

    was passed to it.

    Thus, a test like

    if( *str_test ) {
    /* error */
    }

    might be more useful in practice.

    Sinan
    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)
    A. Sinan Unur, Sep 28, 2005
    #8
  9. "A. Sinan Unur" <> wrote in message
    news:Xns96DEC24772422asu1cornelledu@127.0.0.1...
    > In cases like this, it might be more useful to test that the string
    > contained nothing other than a valid number. For example, the test above
    > would not raise an error if
    >
    > "547.64.58679"
    >
    > was passed to it.


    Agreed.

    > Thus, a test like
    >
    > if( *str_test ) {
    > /* error */
    > }
    >
    > might be more useful in practice.
    >
    > Sinan
    >


    Point well taken. ;-)

    -Charles
    Charles M. Reinke, Sep 28, 2005
    #9
  10. "Charles M. Reinke" <> wrote in
    news:dhcl7a$gne$:

    >
    > "A. Sinan Unur" <> wrote in message
    > news:Xns96DEC24772422asu1cornelledu@127.0.0.1...
    >> In cases like this, it might be more useful to test that the string
    >> contained nothing other than a valid number. For example, the test
    >> above would not raise an error if
    >>
    >> "547.64.58679"
    >>
    >> was passed to it.

    >
    > Agreed.
    >
    >> Thus, a test like
    >>
    >> if( *str_test ) {
    >> /* error */
    >> }
    >>
    >> might be more useful in practice.


    ....

    >
    > Point well taken. ;-)


    I should note that this requires str_test to be initialized.

    char *str_test = charNum;

    should be good enough.

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Sep 28, 2005
    #10
  11. ern

    Baxter Guest

    Yep. That's the quick and dirty method.

    What I find interesting is that in none of the other examples in this thread
    to they address the additional rounding rules if the value is .5 - as in
    "547.500". As I recall, round up on even, down on odd.

    --
    ---------------------------------------------------------------------
    DataGet & PocketLog www.dataget.com
    Data Collectors www.baxcode.com
    --------------------------------------------------------------------



    "tedu" <> wrote in message
    news:...
    > ern wrote:
    > > Anybody know a quick and dirty function for going from "547.6458679" to
    > > the integer version 548 ?
    > >
    > > i.e.
    > >
    > > int returnIntegerEquivalent(char * charNum){
    > > int intNum;
    > > //Do some stuff...

    >
    > intNum = atof(charNum) + 0.5;
    >
    > > return intNum;
    > > }
    > >
    > > I was using the Windows stuff before (ie _gcvt() and atof()).
    > > Thanks,

    >
    Baxter, Sep 28, 2005
    #11
  12. ern

    Jack Klein Guest

    On 27 Sep 2005 13:42:54 -0700, "tedu" <> wrote in
    comp.lang.c:

    > ern wrote:
    > > Anybody know a quick and dirty function for going from "547.6458679" to
    > > the integer version 548 ?
    > >
    > > i.e.
    > >
    > > int returnIntegerEquivalent(char * charNum){
    > > int intNum;
    > > //Do some stuff...

    >
    > intNum = atof(charNum) + 0.5;


    No, very bad! Seriously undefined behavior possible, for two reasons.

    > > return intNum;


    First the ato... functions are all old hacks that should never be
    used. They produce undefined behavior if the converted result is
    outside the range of the destination type. That's why the C standard
    added the strto... functions that have defined behavior with any input
    other than a null pointer.

    Second, even if the value doesn't overflow and atof() returns a valid
    double, the integer part of that double might be outside the range
    that can be represented in a signed int. Boom, undefined behavior.

    Finally there is the minor point that this does 5/4 rounding to a
    greater magnitude for positive numbers but to a lesser magnitude for
    negative ones.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Sep 28, 2005
    #12
  13. "Baxter" <> wrote in message
    news:...
    > What I find interesting is that in none of the other examples in this

    thread
    > to they address the additional rounding rules if the value is .5 - as in
    > "547.500". As I recall, round up on even, down on odd.


    Not many know or simply remember (if ever learned) this Gauss
    correction-on-rounding rule.
    The rule is to round a number having the fractional equal to 0.5 to the
    nearest even integer.
    Examples:
    2.5 -> 2 (not 3)
    3.5 -> 4
    -3.5 -> -4
    -2.5 -> -2 (not -3)
    It's perfectly OK to change this to the opposite (rount to the nearest odd
    integer):
    2.5 -> 3
    3.5 -> 3 (not 4)
    -3.5 -> -3 (not -4)
    -2.5 -> -3
    The absolute value of the rounding error is the same in both cases (0.5),
    but if this additional correction is enforced, rounding errors of such
    numbers tend to compensate each other on summation/subtraction.

    Alex
    Alexei A. Frounze, Sep 28, 2005
    #13
  14. ern

    Netocrat Guest

    On Wed, 28 Sep 2005 10:38:59 +0400, Alexei A. Frounze wrote:
    [...]
    > [T]his Gauss correction-on-rounding rule... is to round a number having
    > the fractional equal to 0.5 to the nearest even integer.
    > [R]ounding errors of such numbers tend to compensate each other on
    > summation/subtraction.


    Beauty in effective simplicity.

    --
    http://members.dodo.com.au/~netocrat
    Netocrat, Sep 28, 2005
    #14
    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. Schnoffos
    Replies:
    2
    Views:
    1,208
    Martien Verbruggen
    Jun 27, 2003
  2. trey

    newbie: char* int and char *int

    trey, Sep 10, 2003, in forum: C Programming
    Replies:
    7
    Views:
    403
    Irrwahn Grausewitz
    Sep 10, 2003
  3. Hal Styli
    Replies:
    14
    Views:
    1,629
    Old Wolf
    Jan 20, 2004
  4. lovecreatesbeauty
    Replies:
    1
    Views:
    1,043
    Ian Collins
    May 9, 2006
  5. gert
    Replies:
    20
    Views:
    1,156
Loading...

Share This Page