# how to convert double to short ?

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

1. ### AlanGuest

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

2. ### Richard HeathfieldGuest

[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

3. ### Mark GordonGuest

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
4. ### Tim WoodallGuest

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

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,

6. ### Mark GordonGuest

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
7. ### Mark GordonGuest

On Sat, 18 Oct 2003 12:59:35 +0200

> 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
8. ### Richard HeathfieldGuest

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
9. ### Tim WoodallGuest

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
10. ### MartijnGuest

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

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
11. ### Robert SabocanecGuest

"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
12. ### Dan PopGuest

Re: how to convert double to short ?

In <> Mark Gordon <> writes:

>On Sat, 18 Oct 2003 12:59:35 +0200
>
>> 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
13. ### Alan BalmerGuest

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