how to convert double to short ?

Discussion in 'C Programming' started by Alan, Oct 18, 2003.

  1. Alan

    Alan Guest

    how to convert double to short ?
    for example, I want to convert

    double doubleVal1 = 15000.1;
    double doubleVal2 = 12000.0;
    short shortVal;

    shortVal = doubleVal1 - doubleVal2;

    I want the result of shortVal = 3000 and store as short instead of double
    value 3000.1
    how can I do that?
     
    Alan, Oct 18, 2003
    #1
    1. Advertising

  2. [Followups set to acllcc++]

    Alan wrote:

    > how to convert double to short ?
    > for example, I want to convert
    >
    > double doubleVal1 = 15000.1;
    > double doubleVal2 = 12000.0;
    > short shortVal;
    >
    > shortVal = doubleVal1 - doubleVal2;
    >
    > I want the result of shortVal = 3000 and store as short instead of
    > double value 3000.1
    > how can I do that?


    double doubleVal1 = 15000.1;
    double doubleVal2 = 12000.0;
    short shortVal;

    shortVal = doubleVal1 - doubleVal2;

    This is not a flippant answer.

    Here is a more robust way to do the same thing:

    #include <limits.h>
    #include <stdio.h>

    int main(void)
    {
    double doubleVal1 = 15000.1;
    double doubleVal2 = 12000.0;
    short shortVal;

    if(doubleVal1 - doubleVal2 < USHRT_MAX)
    {
    shortVal = doubleVal1 - doubleVal2;
    }
    else
    {
    printf("Can't assign to shortVal - result is too large.\n");
    }
    return 0;
    }

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Oct 18, 2003
    #2
    1. Advertising

  3. Alan

    Mark Gordon Guest

    On Sat, 18 Oct 2003 15:46:54 +0800
    "Alan" <> wrote:

    > how to convert double to short ?
    > for example, I want to convert
    >
    > double doubleVal1 = 15000.1;
    > double doubleVal2 = 12000.0;
    > short shortVal;
    >
    > shortVal = doubleVal1 - doubleVal2;
    >
    > I want the result of shortVal = 3000 and store as short instead of
    > double value 3000.1
    > how can I do that?


    If you don't care about the direction of rounding you've just done it.
    If you do care about the direction of rounding look up floor/ceil and if
    using C99 round.
    --
    Mark Gordon
    Paid to be a Geek & a Senior Software Developer
    Although my email address says spamtrap, it is real and I read it.
     
    Mark Gordon, Oct 18, 2003
    #3
  4. Alan

    Tim Woodall Guest

    On Sat, 18 Oct 2003 08:32:07 +0000 (UTC),
    Richard Heathfield <> wrote:
    > [Followups set to acllcc++]
    >

    [ignored as I don't read acllc++ and I don't have time to read
    all the posts in clc as it is]
    <snip>
    >
    > Here is a more robust way to do the same thing:
    >
    > #include <limits.h>
    > #include <stdio.h>
    >
    > int main(void)
    > {
    > double doubleVal1 = 15000.1;
    > double doubleVal2 = 12000.0;
    > short shortVal;
    >
    > if(doubleVal1 - doubleVal2 < USHRT_MAX)
    > {
    > shortVal = doubleVal1 - doubleVal2;
    > }
    > else
    > {
    > printf("Can't assign to shortVal - result is too large.\n");
    > }
    > return 0;
    > }
    >

    Wow, I think I have spotted two mistakes in one of Richards posts.
    (Mind you the next reply to this will have Richard spotting four
    mistakes in my post :)

    Firstly, I think either the USHRT_MAX should be SHRT_MAX or
    shortVal should be unsigned.

    Secondly, if doubleVal1 - doubleVal2 is greater than USHRT_MAX but is
    less than USHRT_MAX+1 then the if will result in the "Can't assign"
    message while the assignment will be fine.

    So the if needs to read:

    if((unsigned short)(doubleVal1 - doubleVal2) < USHRT_MAX)

    I think this is still safe if shortVal is signed giving:

    if((short)(doubleVal1 - doubleVal2) < SHRT_MAX)

    but I'm not going to run it on the DS9000 without confirmation first :)
    (obviously there should also be a test for the lower bound in the
    general case but I have continued the assumption that doubleVal1>doubleVal2)

    Regards,

    Tim.

    --
    God said, "div D = rho, div B = 0, curl E = - @B/@t, curl H = J + @D/@t,"
    and there was light.

    http://tjw.hn.org/ http://www.locofungus.btinternet.co.uk/
     
    Tim Woodall, Oct 18, 2003
    #4
  5. Alan

    Sidney Cadot Guest

    Mark Gordon wrote:

    >>how to convert double to short ?
    >>[snip]


    > If you don't care about the direction of rounding you've just done it.


    For C99 at least the rounding direction of implicit conversions and
    casts from floating-point types to integer types is defined as
    towards-zero, i.e. truncating (6.3.1.4 clause 1). I don't have a C89
    standard handy, but I suspect the same is true there.

    Best regards,

    Sidney Cadot
     
    Sidney Cadot, Oct 18, 2003
    #5
  6. Alan

    Mark Gordon Guest

    On Sat, 18 Oct 2003 10:58:32 +0000 (UTC)
    Tim Woodall <> wrote:

    > On Sat, 18 Oct 2003 08:32:07 +0000 (UTC),
    > Richard Heathfield <> wrote:
    > > [Followups set to acllcc++]
    > >

    > [ignored as I don't read acllc++ and I don't have time to read
    > all the posts in clc as it is]
    > <snip>
    > >
    > > Here is a more robust way to do the same thing:
    > >
    > > #include <limits.h>
    > > #include <stdio.h>
    > >
    > > int main(void)
    > > {
    > > double doubleVal1 = 15000.1;
    > > double doubleVal2 = 12000.0;
    > > short shortVal;
    > >
    > > if(doubleVal1 - doubleVal2 < USHRT_MAX)
    > > {
    > > shortVal = doubleVal1 - doubleVal2;
    > > }
    > > else
    > > {
    > > printf("Can't assign to shortVal - result is too large.\n");
    > > }
    > > return 0;
    > > }
    > >

    > Wow, I think I have spotted two mistakes in one of Richards posts.
    > (Mind you the next reply to this will have Richard spotting four
    > mistakes in my post :)
    >
    > Firstly, I think either the USHRT_MAX should be SHRT_MAX or
    > shortVal should be unsigned.


    He also forgot to check for negative overflow.

    > Secondly, if doubleVal1 - doubleVal2 is greater than USHRT_MAX but is
    > less than USHRT_MAX+1 then the if will result in the "Can't assign"
    > message while the assignment will be fine.


    That's safe.

    > So the if needs to read:
    >
    > if((unsigned short)(doubleVal1 - doubleVal2) < USHRT_MAX)
    >
    > I think this is still safe if shortVal is signed giving:
    >
    > if((short)(doubleVal1 - doubleVal2) < SHRT_MAX)


    Definitely not I would have though since the overflow occurs when you do
    the cast.

    > but I'm not going to run it on the DS9000 without confirmation first
    > :)(obviously there should also be a test for the lower bound in the
    > general case but I have continued the assumption that
    > doubleVal1>doubleVal2)


    Never assume ;-)
    --
    Mark Gordon
    Paid to be a Geek & a Senior Software Developer
    Although my email address says spamtrap, it is real and I read it.
     
    Mark Gordon, Oct 18, 2003
    #6
  7. Alan

    Mark Gordon Guest

    On Sat, 18 Oct 2003 12:59:35 +0200
    Sidney Cadot <> wrote:

    > Mark Gordon wrote:
    >
    > >>how to convert double to short ?
    > >>[snip]

    >
    > > If you don't care about the direction of rounding you've just done
    > > it.

    >
    > For C99 at least the rounding direction of implicit conversions and
    > casts from floating-point types to integer types is defined as
    > towards-zero, i.e. truncating (6.3.1.4 clause 1). I don't have a C89
    > standard handy, but I suspect the same is true there.


    I thought than in C90 it was implementation defined. Based on what I
    have to hand I believe that float.h provides you with FLT_ROUNDS which
    gives you information about the rounding used.

    However I could be wrong as my copy of K&R2 is in the office.
    --
    Mark Gordon
    Paid to be a Geek & a Senior Software Developer
    Although my email address says spamtrap, it is real and I read it.
     
    Mark Gordon, Oct 18, 2003
    #7
  8. Tim Woodall wrote:

    > On Sat, 18 Oct 2003 08:32:07 +0000 (UTC),
    > Richard Heathfield <> wrote:
    >> [Followups set to acllcc++]
    >>

    > [ignored as I don't read acllc++ and I don't have time to read
    > all the posts in clc as it is]


    Fair enough. I've reinstated clc too...

    > <snip>
    >>
    >> if(doubleVal1 - doubleVal2 < USHRT_MAX)
    >> {
    >> shortVal = doubleVal1 - doubleVal2;
    >> }
    >> else
    >> {
    >> printf("Can't assign to shortVal - result is too large.\n");
    >> }
    >> return 0;
    >> }
    >>

    > Wow, I think I have spotted two mistakes in one of Richards posts.
    > (Mind you the next reply to this will have Richard spotting four
    > mistakes in my post :)


    Heh - I know it's not unheard of for me to do that, but this time, I'm gonna
    try shutting my eyes.

    >
    > Firstly, I think either the USHRT_MAX should be SHRT_MAX or
    > shortVal should be unsigned.


    Yes, I did actually mean SHRT_MAX. I so rarely use SHRT_MAX, though, that my
    fingers must have assured my brain that they knew what they were doing, and
    my brain must have believed them.

    > Secondly, if doubleVal1 - doubleVal2 is greater than USHRT_MAX but is
    > less than USHRT_MAX+1 then the if will result in the "Can't assign"
    > message while the assignment will be fine.
    >
    > So the if needs to read:
    >
    > if((unsigned short)(doubleVal1 - doubleVal2) < USHRT_MAX)


    Yes, I'll buy that (suitably munged to signed short). I was hoping to avoid
    the cast, though.

    >
    > I think this is still safe if shortVal is signed giving:
    >
    > if((short)(doubleVal1 - doubleVal2) < SHRT_MAX)


    Yes, that looks okay to me.

    > but I'm not going to run it on the DS9000 without confirmation first :)
    > (obviously there should also be a test for the lower bound in the
    > general case but I have continued the assumption that
    > doubleVal1>doubleVal2)


    ....which I didn't even realise I was assuming! Make that three mistakes.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Oct 18, 2003
    #8
  9. Alan

    Tim Woodall Guest

    Well I'm following up to my own post because neither of the other
    replies have castigated me :)

    On Sat, 18 Oct 2003 10:58:32 +0000 (UTC),
    Tim Woodall <> wrote:
    > On Sat, 18 Oct 2003 08:32:07 +0000 (UTC),
    > Richard Heathfield <> wrote:

    <snip>
    >> double doubleVal1 = 15000.1;
    >> double doubleVal2 = 12000.0;
    >> short shortVal;
    >>
    >> if(doubleVal1 - doubleVal2 < USHRT_MAX)

    <snip>
    >> else
    >> printf("Can't assign to shortVal - result is too large.\n");

    <snip>

    >>

    > Wow, I think I have spotted two mistakes in one of Richards posts.
    > (Mind you the next reply to this will have Richard spotting four
    > mistakes in my post :)
    >
    > Firstly, I think either the USHRT_MAX should be SHRT_MAX or
    > shortVal should be unsigned.
    >

    Well, I was ok until here.

    > Secondly, if doubleVal1 - doubleVal2 is greater than USHRT_MAX but is
    > less than USHRT_MAX+1 then the if will result in the "Can't assign"
    > message while the assignment will be fine.
    >

    And ok to here as well. If only I had stopped at this point :)


    > So the if needs to read:
    >
    > if((unsigned short)(doubleVal1 - doubleVal2) < USHRT_MAX)
    >


    Well.... I _think_ this is utter rubbish :-( Richards code at least
    worked except for a corner case.

    First of all the < should be <=. But even after that the cast will
    force the value to be 0..USHRT_MAX.

    I'm not sure this can be solved (in clc talk). If you make the assumption
    that UINT_MAX>USHRT_MAX then I think

    if(doubleVal1 - doubleVal2 <= USHRT_MAX+1) would do the trick.

    Maybe if(floor(doubleVal1 - doubleVal2) <= USHRT_MAX) is sufficient but I
    always start getting nervous when worrying about corner cases and floating
    point in the same breath .... especially if this has to work on the DS9000.


    > I think this is still safe if shortVal is signed giving:
    >
    > if((short)(doubleVal1 - doubleVal2) < SHRT_MAX)
    >

    And I don't know whether this is safe but I think not. Surely there is
    no difference between

    short s;
    double d=get_number_too_big_for_short();

    s=d; /*and*/
    s=(short)d;

    So both are demon fodder to a DS9000.

    Tim.


    --
    God said, "div D = rho, div B = 0, curl E = - @B/@t, curl H = J + @D/@t,"
    and there was light.

    http://tjw.hn.org/ http://www.locofungus.btinternet.co.uk/
     
    Tim Woodall, Oct 18, 2003
    #9
  10. Alan

    Martijn Guest

    Tim Woodall wrote:
    > if((short)(doubleVal1 - doubleVal2) < SHRT_MAX)


    I must admit I don't really know what I am talking about, but why is this
    safe, instead of

    if ( (doubleVal1 - doubleVal2) < (double)SHRT_MAX )

    I would think that in the cast to a short you may loose some information
    (thinking that the largest value of short is the largest value you could
    possibly fit into a the amount of bits that a short is made of - and thus
    overflow may be an issue).

    Thanks,

    --
    Martijn
    http://www.sereneconcepts.nl
     
    Martijn, Oct 19, 2003
    #10
  11. "Alan" <> wrote in message
    news:bmqs76$1mri$...
    > how to convert double to short ?
    > for example, I want to convert
    >
    > double doubleVal1 = 15000.1;
    > double doubleVal2 = 12000.0;
    > short shortVal;
    >
    > shortVal = doubleVal1 - doubleVal2;
    >
    > I want the result of shortVal = 3000 and store as short instead of

    double
    > value 3000.1
    > how can I do that?
    >

    You could try numeric_cast from boost library, it's simple for use,
    http://www.boost.org/libs/conversion/cast.htm#numeric_cast

    Robi
     
    Robert Sabocanec, Oct 20, 2003
    #11
  12. Alan

    Dan Pop Guest

    Re: how to convert double to short ?

    In <> Mark Gordon <> writes:

    >On Sat, 18 Oct 2003 12:59:35 +0200
    >Sidney Cadot <> wrote:
    >
    >> Mark Gordon wrote:
    >>
    >> >>how to convert double to short ?
    >> >>[snip]

    >>
    >> > If you don't care about the direction of rounding you've just done
    >> > it.

    >>
    >> For C99 at least the rounding direction of implicit conversions and
    >> casts from floating-point types to integer types is defined as
    >> towards-zero, i.e. truncating (6.3.1.4 clause 1). I don't have a C89
    >> standard handy, but I suspect the same is true there.

    >
    >I thought than in C90 it was implementation defined.


    Nope. C99 is no different from C89 on this particular issue.

    >Based on what I
    >have to hand I believe that float.h provides you with FLT_ROUNDS which
    >gives you information about the rounding used.


    It doesn't apply here.

    The rounding mode for floating-point addition is characterized by the
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    value of FLT_ROUNDS : -1 indeterminable, 0 toward zero, 1 to nearest, 2
    toward positive infinity, 3 toward negative infinity. All other values
    for FLT_ROUNDS characterize implementation-defined rounding behavior.

    The text relevant to this discussion is:

    3.2.1.3 Floating and integral

    When a value of floating type is converted to integral type, the
    fractional part is discarded. If the value of the integral part
    cannot be represented by the integral type, the behavior is
    undefined.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Oct 20, 2003
    #12
  13. Alan

    Alan Balmer Guest

    On Sat, 18 Oct 2003 15:46:54 +0800, "Alan"
    <> wrote:

    >how to convert double to short ?


    With fear and trepidation. Plus range checking.

    >for example, I want to convert
    >
    >double doubleVal1 = 15000.1;
    >double doubleVal2 = 12000.0;
    >short shortVal;
    >
    >shortVal = doubleVal1 - doubleVal2;
    >
    >I want the result of shortVal = 3000 and store as short instead of double
    >value 3000.1
    >how can I do that?
    >
    >


    --
    Al Balmer
    Balmer Consulting
     
    Alan Balmer, Oct 20, 2003
    #13
    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. Sydex
    Replies:
    12
    Views:
    6,508
    Victor Bazarov
    Feb 17, 2005
  2. David Geering

    longs, long longs, short short long ints . . . huh?!

    David Geering, Jan 8, 2007, in forum: C Programming
    Replies:
    15
    Views:
    565
    Keith Thompson
    Jan 11, 2007
  3. Replies:
    4
    Views:
    831
    Kaz Kylheku
    Oct 17, 2006
  4. Ioannis Vranos

    unsigned short, short literals

    Ioannis Vranos, Mar 4, 2008, in forum: C Programming
    Replies:
    5
    Views:
    684
    Eric Sosman
    Mar 5, 2008
  5. Andre
    Replies:
    5
    Views:
    542
    Keith Thompson
    Jul 17, 2012
Loading...

Share This Page