Where is the rough work done?
Author Message
Where is the rough work done?

Consider the following hypothetical function:

int PrintAmount(unsigned long amount)
{
short megaAmount  = (amount/100000000);
short kiloAmount  = (amount/100000) -megaAmount*1000;
short uniAmount   =
(amount/100) -kiloAmount*1000 -megaAmount*1000000;
short centiAmount = amount%100;

return printf("Amount is: %d,%03d,%03d.%02d\n", megaAmount,
kiloAmount, uniAmount, centiAmount);

Quote:
}

Now, I'm curious to know if the short values will be evaluated correctly,
particularly kiloAmount and uniAmount.

The reason I think there might be a problem is because you have the
situation:

short = long/long
short = long/long - (potential long)
short = long/short - (potential long) - long
short = long%short

Is it a problem to assign a short to an expression composed of longs as long
as the result fits into a short?

Regards,

Sat, 16 Mar 2002 03:00:00 GMT
Where is the rough work done?

Quote:

>Consider the following hypothetical function:

>int PrintAmount(unsigned long amount)
>{
>        short megaAmount  = (amount/100000000);
>        short kiloAmount  = (amount/100000) -megaAmount*1000;
>        short uniAmount   =
>(amount/100) -kiloAmount*1000 -megaAmount*1000000;
>        short centiAmount = amount%100;

>        return printf("Amount is: %d,%03d,%03d.%02d\n", megaAmount,
>kiloAmount, uniAmount, centiAmount);
>}

>Now, I'm curious to know if the short values will be evaluated correctly,
>particularly kiloAmount and uniAmount.

>The reason I think there might be a problem is because you have the
>situation:

>short = long/long
>short = long/long - (potential long)
>short = long/short - (potential long) - long
>short = long%short

>Is it a problem to assign a short to an expression composed of longs as long
>as the result fits into a short?

No.

However, kiloAmount and uniAmount may still have problems.  The values you
have noted as (potential long) are actually shorts.  If either
megaAmount*1000 or kiloAmount*1000 overflows the size of a short, the
results are undefined.  Also, you indicate that you think
megaAmount*1000000 will be a long; it will be if 1000000 is a long, but
there's nothing in the standard that requires this (the standard specifies
a minimum size for each data type, but not a maximum, so 1000000 could be a
short).  If there's no overflow, the short will be promoted to a long in
order to combine it with the other longs in the expression.

You could change your code to:

short kiloAmount  = (amount/100000) -megaAmount*1000L;
short uniAmount   = (amount/100) -kiloAmount*1000L -megaAmount*1000000L;

By explicitly using a long in the multiplications, you force the results to
be longs as well.  Or you could do:

short kiloAmount  = (amount/100000) -(long)megaAmount*1000;
short uniAmount   = (amount/100) -(long)kiloAmount*1000 -(long)megaAmount*1000000;

--

*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Sat, 16 Mar 2002 03:00:00 GMT
Where is the rough work done?

Quote:

> >        short megaAmount  = (amount/100000000);
> >        short kiloAmount  = (amount/100000) -megaAmount*1000;
> >        short uniAmount   = (amount/100) -kiloAmount*1000 -megaAmount*1000000;
> >        short centiAmount = amount%100;
...
> >short = long/long
> >short = long/long - (potential long)
> >short = long/short - (potential long) - long
> >short = long%short

> The values you have noted as (potential long) are actually shorts.

The variables are shorts, which get promoted to (most likely) int.
The constants are ints or longs.  So the "potential long" expressions
are ints in the case of 1000, and int or long in the case of 1000000.

paul

Sat, 16 Mar 2002 03:00:00 GMT
Where is the rough work done?
On Tue, 28 Sep 1999 18:11:48 GMT, Barry Margolin

[...]

Quote:
>results are undefined.  Also, you indicate that you think
>megaAmount*1000000 will be a long; it will be if 1000000 is a long, but
>there's nothing in the standard that requires this (the standard specifies
>a minimum size for each data type, but not a maximum, so 1000000 could be a
>short).  If there's no overflow, the short will be promoted to a long in
>order to combine it with the other longs in the expression.

But 1000000 cannot be a short.  It can only be int, long, or
unsigned long.

Furthermore, there is no such thing as an expression whose type is
short.  So even if the expression were megaAmount*(short)1000000, both
megaAmount and (whatever is left of) 1000000 would first be promoted
to int.

I'm sensitive to these issues because I've done a fair amount of
porting 16-bit int code to 32-bit int platforms...

Other than that, your information is correct (AFAICT).  Regards,

-=Dave
Just my (10-010) cents
I can barely speak for myself, so I certainly can't speak for B-Tree.
Change is inevitable.  Progress is not.

Sat, 16 Mar 2002 03:00:00 GMT
Where is the rough work done?

Quote:
> On Tue, 28 Sep 1999 18:11:48 GMT, Barry Margolin

> [...]
> >results are undefined.  Also, you indicate that you think
> >megaAmount*1000000 will be a long; it will be if 1000000 is a long, but
> >there's nothing in the standard that requires this (the standard
specifies
> >a minimum size for each data type, but not a maximum, so 1000000 could
be a
> >short).  If there's no overflow, the short will be promoted to a long in
> >order to combine it with the other longs in the expression.

> But 1000000 cannot be a short.  It can only be int, long, or
> unsigned long.

Why so? I believe I am right in saying that short is a 64-bit type on Cray
machines. If so (ICBW after all), it should be able to hold values even
greater than 9000000000000000000, so 1000000 shouldn't even begin to
stretch its capabilities.

<snip>

--
Richard Heathfield

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.

Sat, 16 Mar 2002 03:00:00 GMT
Where is the rough work done?

Quote:

> > But 1000000 cannot be a short.  It can only be int, long, or
> > unsigned long.

> Why so? I believe I am right in saying that short is a 64-bit type on Cray
> machines. If so (ICBW after all), it should be able to hold values even
> greater than 9000000000000000000, so 1000000 shouldn't even begin to
> stretch its capabilities.

1000000 might within the range of a short, but if you write 1000000 in
a program, it is not a short.  C provides no way to write a short
constant without using a cast.
--
"I should killfile you where you stand, worthless human." --Kaz

Sat, 16 Mar 2002 03:00:00 GMT
Where is the rough work done?
On Tue, 28 Sep 1999 13:46:09 -0700, "Dann Corbit"

Quote:

[...]
>> But 1000000 cannot be a short.  It can only be int, long, or
>> unsigned long.
>I thought that short had to be able to support *AT LEAST* +/- 32767 but that
>it could (in fact) be much larger.  Is this incorrect?  E.g.:
>char <= short <= int <= long

We're both right, but I guess should have been clearer.

The type of an uncast integer constant must be int, unsigned, long, or
unsigned long.  If you write the value 1000000 in a C program, it is
an integer constant that can be any of the types except unsigned.
From the top of my head, and assuming 16-bit int and 32-bit long, 1
will be int, 32768 will be long, 0x8000 will be unsigned, 0x10000 will
be long, and 2147483648 will be unsigned long.

Regards,

-=Dave
Just my (10-010) cents
I can barely speak for myself, so I certainly can't speak for B-Tree.
Change is inevitable.  Progress is not.

Sat, 16 Mar 2002 03:00:00 GMT
Where is the rough work done?

Quote:

> > > But 1000000 cannot be a short.  It can only be int, long, or
> > > unsigned long.

> > Why so? I believe I am right in saying that short is a 64-bit type on
Cray
> > machines. If so (ICBW after all), it should be able to hold values even
> > greater than 9000000000000000000, so 1000000 shouldn't even begin to
> > stretch its capabilities.

> 1000000 might within the range of a short, but if you write 1000000 in
> a program, it is not a short.  C provides no way to write a short
> constant without using a cast.

Correct, Ben; thank you. I was thinking of short variables, not short
constants. My objection is correct, of course, but only in the context of a
different original posting. What he /should/ have said was "But 1000000
cannot be stored in a short." If he had got it wrong, my correction would
have been perfectly in order.

--
Richard Heathfield

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.

Sun, 17 Mar 2002 03:00:00 GMT
Where is the rough work done?

Quote:
>But 1000000 cannot be a short.  It can only be int, long, or
>unsigned long.

I think you should go and check your facts.  The only requirements are
of the form of a minimum range of values for each fundamental type
together with requirements of the kind 'all values of short shall be
representable as ints.

I think you should be careful to distinguish between values and
literals.  The literal 1000000 has the requirement you state.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

Sun, 17 Mar 2002 03:00:00 GMT
Where is the rough work done?

Quote:

> Consider the following hypothetical function:

> int PrintAmount(unsigned long amount)
> {
>         short megaAmount  = (amount/100000000);
>         short kiloAmount  = (amount/100000) -megaAmount*1000;
>         short uniAmount   =
> (amount/100) -kiloAmount*1000 -megaAmount*1000000;
>         short centiAmount = amount%100;

>         return printf("Amount is: %d,%03d,%03d.%02d\n", megaAmount,
> kiloAmount, uniAmount, centiAmount);
> }

You might avoid a number of problems if you write it
this way

int PrintAmount(unsigned long amount)
{
short megaAmount;
short kiloAmount;
short uniAmount;
short centiAmount;

centiAmount=amount%100; amount/=100;
uniAmount=amount%10; amount/=10;
kiloAmount=amount%1000; amount/=1000;
megaAmount=amount%1000; amount/=1000;
return printf("Amount is: %hd,%03hd,%03hd.%02hd\n", megaAmount,
kiloAmount, uniAmount, centiAmount);
}

Note the %hd format for printing shorts.
(nice portability trap if you go from SI32 to S16I32)

--

Graz, Austria   www.hls-software.com

Sun, 17 Mar 2002 03:00:00 GMT
Where is the rough work done?

Quote:
>>But 1000000 cannot be a short.  It can only be int, long, or
>>unsigned long.

>I think you should go and check your facts.  The only requirements are
>of the form of a minimum range of values for each fundamental type
>together with requirements of the kind 'all values of short shall be
>representable as ints.

>I think you should be careful to distinguish between values and
>literals.  The literal 1000000 has the requirement you state.

I think you should check yours - the 1000000 *was* a literal in this

--

Fax: +44 20 8371 1037 |                      | Web:  <http://www.davros.org>

Sun, 17 Mar 2002 03:00:00 GMT
Where is the rough work done?

Quote:

> C provides no way to write a short constant without using a cast.

Which turns out to cause a real problem in implementing part of
<inttypes.h> (the constant-forming macros).

Sun, 17 Mar 2002 03:00:00 GMT
Where is the rough work done?

Quote:

> > C provides no way to write a short constant without using a cast.

> Which turns out to cause a real problem in implementing part of
> <inttypes.h> (the constant-forming macros).

What is the typical solution?  (I'm curious.)
--
"Large amounts of money tend to quench any scruples I might be having."
-- Stephan Wilms

Mon, 18 Mar 2002 03:00:00 GMT
Where is the rough work done?

Quote:

> > > C provides no way to write a short constant without using a cast.
> > Which turns out to cause a real problem in implementing part of
> > <inttypes.h> (the constant-forming macros).
> What is the typical solution?  (I'm curious.)

A conforming C9x implementation will have to use some implementation-
dependent extension.  So far as I know there is no existing practice
for this.  The problem is that the spec is flawed -- the type of the
integer constant produced should not *have* to be precisely that of
the corresponding type.  As observed in another recent thread, there
is no standard way of writing an integer constant of a type with
width less than int.

One solution would be to patch up the spec before it is too late.
Another approach would be to define a standard way to denote
integer constants with narrow widths (char and short).
I'll try to get this addressed at the upcoming WG14 meeting.

Mon, 18 Mar 2002 03:00:00 GMT

 Page 1 of 2 [ 25 post ] Go to page: [1] [2]

Relevant Pages