how to convert double to short ?

A

Alan

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?
 
R

Richard Heathfield

[Followups set to acllcc++]
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;
}
 
M

Mark Gordon

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.
 
T

Tim Woodall

[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]
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.
 
S

Sidney Cadot

Mark said:
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
 
M

Mark Gordon

[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]
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 ;-)
 
M

Mark Gordon

Mark said:
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.
 
R

Richard Heathfield

Tim said:
[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...
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.
 
T

Tim Woodall

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

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.
 
M

Martijn

Tim said:
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,
 
D

Dan Pop

In said:
Mark said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,439
Members
44,829
Latest member
PIXThurman

Latest Threads

Top