what does this double conversion mean (unsigned long)(unsigned int)

Discussion in 'C Programming' started by CFAN, Apr 3, 2007.

  1. CFAN

    CFAN Guest

    Here is a example of double-type-conversion
    char * __cdecl _itoa (
    int val,
    char *buf,
    int radix
    )
    {
    if (radix == 10 && val < 0)
    xtoa((unsigned long)val, buf, radix, 1);
    else
    xtoa((unsigned long)(unsigned int)val, buf, radix, 0);
    return buf;
    }

    and why need this type of conversion
    CFAN, Apr 3, 2007
    #1
    1. Advertising

  2. CFAN

    Richard Bos Guest

    "CFAN" <> wrote:

    > Here is a example of double-type-conversion


    Which is silly.

    > char * __cdecl _itoa (

    This ^^^^^^^ does not exist at all in C, and shouldn't be
    there, and this ^^^^^ is an identifier which you're not allowed to use
    for a function name.

    > int val,
    > char *buf,
    > int radix
    > )


    Unless you put comments after the parameters, this is a painfully stupid
    way to lay out a function parameter list.

    > {
    > if (radix == 10 && val < 0)
    > xtoa((unsigned long)val, buf, radix, 1);

    This function ^^^^ does not exist in ISO C, and
    this cast ^^^^^^^^^^^^^^^ is completely unnecessary or even
    wrong unless xtoa() is declared unwisely or not at all.
    If xtoa(), as defined by your program, takes an unsigned long as its
    first argument, that cast should be unnecessary; if it doesn't, that
    cast does the wrong thing.

    > else
    > xtoa((unsigned long)(unsigned int)val, buf, radix, 0);

    As well as the above, ^^^^^^^^^^^^^^^^^^^^^^^^^^ these casts are
    completely mindless. Or rather, they should be. One can dream up
    imaginary scenarios in which they do something good, to do with the edge
    cases of negative values passed to functions expecting small, not large,
    positive ones, but really, write proper functions. And then document why
    they cast.

    > return buf;
    > }
    >
    > and why need this type of conversion


    You shouldn't.

    Richard
    Richard Bos, Apr 3, 2007
    #2
    1. Advertising

  3. CFAN wrote:
    >
    > Here is a example of double-type-conversion

    [...]
    > int val,

    [...]
    > xtoa((unsigned long)val, buf, radix, 1);


    Here, if val is negative, and sizeof(long)>sizeof(int), the conversion
    from int to unsigned long will sign-extend the int before treating
    the result as unsigned.

    > else
    > xtoa((unsigned long)(unsigned int)val, buf, radix, 0);


    Here, val will not be sign-extended, as you are telling the compiler
    to treat the value as unsigned, and then convert to unsigned long.

    [...]
    > and why need this type of conversion


    Is there a reason you need to convert a signed int to an unsigned
    long? If you can think of a reason why you need to do such a
    conversion, and control the sign-extending aspects, then you will
    have your answer.

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
    Kenneth Brody, Apr 3, 2007
    #3
  4. CFAN

    Eric Sosman Guest

    Re: what does this double conversion mean (unsigned long)(unsignedint)

    CFAN wrote On 04/03/07 08:05,:
    > Here is a example of double-type-conversion
    > char * __cdecl _itoa (
    > int val,
    > char *buf,
    > int radix
    > )
    > {
    > if (radix == 10 && val < 0)
    > xtoa((unsigned long)val, buf, radix, 1);
    > else
    > xtoa((unsigned long)(unsigned int)val, buf, radix, 0);
    > return buf;
    > }
    >
    > and why need this type of conversion


    Suppose you're using a system where unsigned long is
    wider than unsigned int -- 32 and 16 bits, for example.
    Suppose also that `val' is negative one. Then

    (unsigned long)val == 4294967295ul
    (unsigned int)val == 65535u
    (unsigned long)(unsigned int)val == 65535ul

    In the code above, I'd guess that the xtoa() function
    takes an unsigned long as its first argument. There may
    or may not be a prototype for xtoa() in scope; if there
    is, both (unsigned long) casts are unnecessary because the
    compiler would perform the conversion automatically. But
    a direct conversion from int to unsigned long could give a
    different result than conversion from int to unsigned int
    and then to unsigned long; perhaps the programmer wants
    to avoid the huge numbers that a negative `val' would yield
    if converted directly.

    I have no idea why "base 10, negative" is treated
    differently from "base 8, positive." That's something
    you'll need to ask the programmer about.

    --
    Eric Sosman, Apr 3, 2007
    #4
  5. On Apr 3, 8:05 am, "CFAN" <> wrote:
    > Here is a example of double-type-conversion
    > char * __cdecl _itoa (
    > int val,
    > char *buf,
    > int radix
    > )
    > {
    > if (radix == 10 && val < 0)
    > xtoa((unsigned long)val, buf, radix, 1);
    > else
    > xtoa((unsigned long)(unsigned int)val, buf, radix, 0);
    > return buf;
    >
    > }
    >
    > and why need this type of conversion


    This code(possibly) makes implementation specific assumptions
    and uses the implementation name space (on the other hand
    it may be part of an implementation).


    Consider the case where long and int do not have the same size
    (say int is 16 bits and long is 32)

    then
    (unsigned int) (-1) = 0xFFFFFFFF



    (unsigned long) (-1) = 0xFFFFFFFFFFFFFFFF

    So if you want _itoa to print out FFFFFFFF when passed a signed int
    value -1 and a radix of 16, you need the double cast.

    If long and int have the same size then the cast is unneeded but
    harmless.

    The code assumes that if you are printing in decimal you want
    to print out negative integers, but if you are printing in something
    else you only use positive integers, so if something looks like a
    negative
    integer it is really a big positive integer (but no bigger than an
    int).

    A couple of comments would be a GOOD THING.

    - William Hughes
    William Hughes, Apr 3, 2007
    #5
  6. Re: what does this double conversion mean (unsigned long)(unsignedint)

    CFAN wrote:
    > Here is a example of double-type-conversion
    > char * __cdecl _itoa (
    > int val,
    > char *buf,
    > int radix
    > )
    > {
    > if (radix == 10 && val < 0)
    > xtoa((unsigned long)val, buf, radix, 1);
    > else
    > xtoa((unsigned long)(unsigned int)val, buf, radix, 0);
    > return buf;
    > }
    >
    > and why need this type of conversion


    You don't. See if the following answers your question:
    #include <stdio.h>
    #include <limits.h>

    /* mha: Let's first give a prototype for the non-standard function
    xtoa */
    inline void xtoa(unsigned long, char *, int, int);

    /* mha: remove meaningless invasion of implementation namespace __cdecl,
    rename similar _itoa */
    char *tst_itoa(int val, char *buf, int radix)
    {
    if (radix == 10 && val < 0)
    /* mha: remove useless cast */
    xtoa(val, buf, radix, 1);
    else
    /* mha: remove useless casts */
    xtoa(val, buf, radix, 0);
    return buf;
    }

    /* mha: supply the missing non-standard xtoa */
    inline void xtoa(unsigned long value, char *buffer, int unused1,
    int unused2)
    {
    sprintf(buffer, "%lu", value);
    }

    /* mha: to make a complete compilable program: */
    int main(void)
    {
    char buff[BUFSIZ];
    unsigned long foo = ULONG_MAX;
    tst_itoa(foo, buff, 10);
    printf("For foo=%lu, tst_itoa filled buff with \"%s\"\n", foo,
    buff);
    return 0;
    }


    [output]
    For foo=4294967295, tst_itoa filled buff with "4294967295"
    Martin Ambuhl, Apr 3, 2007
    #6
  7. CFAN

    Tor Rustad Guest

    Re: what does this double conversion mean (unsigned long)(unsignedint)

    CFAN wrote:
    > Here is a example of double-type-conversion
    > char * __cdecl _itoa (
    > int val,
    > char *buf,
    > int radix
    > )
    > {
    > if (radix == 10 && val < 0)
    > xtoa((unsigned long)val, buf, radix, 1);
    > else
    > xtoa((unsigned long)(unsigned int)val, buf, radix, 0);
    > return buf;
    > }
    >
    > and why need this type of conversion
    >


    __cdecl specify the calling convention used by Microsoft C compilers,
    look up their MSDN documentation, which is even available online AFAIK.

    --
    Tor
    Tor Rustad, Apr 4, 2007
    #7
    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. George Marsaglia

    Assigning unsigned long to unsigned long long

    George Marsaglia, Jul 8, 2003, in forum: C Programming
    Replies:
    1
    Views:
    674
    Eric Sosman
    Jul 8, 2003
  2. G Fernandes
    Replies:
    2
    Views:
    490
    Lawrence Kirby
    Feb 16, 2005
  3. Daniel Rudy

    unsigned long long int to long double

    Daniel Rudy, Sep 19, 2005, in forum: C Programming
    Replies:
    5
    Views:
    1,186
    Peter Shaggy Haywood
    Sep 20, 2005
  4. pereges

    Promoting unsigned long int to long int

    pereges, Jun 30, 2008, in forum: C Programming
    Replies:
    112
    Views:
    2,080
    David Thompson
    Jul 28, 2008
  5. pozz
    Replies:
    12
    Views:
    738
    Tim Rentsch
    Mar 20, 2011
Loading...

Share This Page