Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   how to convert double to short ? (http://www.velocityreviews.com/forums/t315834-how-to-convert-double-to-short.html)

Alan 10-18-2003 07:46 AM

how to convert double to short ?
 
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?




Richard Heathfield 10-18-2003 08:32 AM

Re: how to convert double to short ?
 
[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 : binary@eton.powernet.co.uk
"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

Mark Gordon 10-18-2003 09:02 AM

Re: how to convert double to short ?
 
On Sat, 18 Oct 2003 15:46:54 +0800
"Alan" <alanrobbiebower@hotmail.com> 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.

Tim Woodall 10-18-2003 10:58 AM

Re: how to convert double to short ?
 
On Sat, 18 Oct 2003 08:32:07 +0000 (UTC),
Richard Heathfield <dontmail@address.co.uk.invalid> 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/

Sidney Cadot 10-18-2003 10:59 AM

Re: how to convert double to short ?
 
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


Mark Gordon 10-18-2003 11:35 AM

Re: how to convert double to short ?
 
On Sat, 18 Oct 2003 10:58:32 +0000 (UTC)
Tim Woodall <devnull@locofungus.org> wrote:

> On Sat, 18 Oct 2003 08:32:07 +0000 (UTC),
> Richard Heathfield <dontmail@address.co.uk.invalid> 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 10-18-2003 11:45 AM

Re: how to convert double to short ?
 
On Sat, 18 Oct 2003 12:59:35 +0200
Sidney Cadot <sidney@jigsaw.nl> 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.

Richard Heathfield 10-18-2003 05:52 PM

Re: how to convert double to short ?
 
Tim Woodall wrote:

> On Sat, 18 Oct 2003 08:32:07 +0000 (UTC),
> Richard Heathfield <dontmail@address.co.uk.invalid> 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 : binary@eton.powernet.co.uk
"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

Tim Woodall 10-18-2003 07:43 PM

Re: how to convert double to short ?
 
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 <devnull@locofungus.org> wrote:
> On Sat, 18 Oct 2003 08:32:07 +0000 (UTC),
> Richard Heathfield <dontmail@address.co.uk.invalid> 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/

Martijn 10-19-2003 02:11 PM

Re: how to convert double to short ?
 
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




All times are GMT. The time now is 11:56 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.