int y = 27;
int h = 10;
y = y/h*h;
should give 20, or will compiler optimization cancel out h?
Hi,
I think it will work fine since y/h*h means (y/h)*h
and the operator / will drop the fractional part of divisions
between integers. Just be careful of checking the case of h==0
if you are going to use that expression as a general formula.
--
Vincenzo Mercuri
It will do what you want. The compiler is not free to make
optimizations that change the result of integer expressions.
Notice that for y = -27, you could get either -30 or -20.
That's another reason to use unsigned.
Other strictly equivalent options:
y = y-y%h;
y -= y%h;
If y is non-negative and h a power of two, there is also
y &= ~(h-1);
Francois Grieu
Yes, this is right for C90. Nevertheless compiling under C99
mode, you will always get -20
--
Vincenzo Mercuri
Multiplication and division associate left to right, so the compiler
can't optimise out the division - it must give the result 20 for the
above calculation.
Unfortunately, if you mean precisely what you say, y = y / h * h breaks
when y is an exact multiple of h. Say y = 27 and h = 9 - your calc gives
27, which isn't less than y's original value. It is quite possible, even
likely, that that's what you really meant. But, if you really meant that
you want to have the largest multiple of h that is *less than* y (not
less than or equal to y), you can do this instead:
y = ((y + h - 1) / h - 1) * h;
Beware overflow issues when using signed types. Also beware of negative
numbers - I haven't actually checked that the above will work with
negatives, and in fact it probably won't.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
or simply:
y = (y - 1) / h * h; :-)
(you had a great idea!)
--
Vincenzo Mercuri
I believe this would give the same result:
(y - 1) - (( y - 1) % h)
but without the multiply and divide.
--
Billy Mays
http://www.jpgdump.com <- My attempt at humor.
> On 7/12/2010 1:54 PM, Vincenzo Mercuri wrote:
>>
>> or simply:
>>
>> y = (y - 1) / h * h; :-)
>>
>> (you had a great idea!)
>>
>
>
> I believe this would give the same result:
>
> (y - 1) - (( y - 1) % h)
>
> but without the multiply and divide.
You think % is done without division?
It can be :)
/*******************************************************/
#include <stdio.h>
#include <stdint.h>
int main(int argc, char ** argv)
{
int y;
y = 31;
y = (((int64_t)(y-1) * 0x66666667LL) >> 34) ;
y = (y<<3) + (y<<1);
printf("%d\n", y);
return 0;
}
/*******************************************************/
Dean
Please don't top-post.
> What's C99?
<http://www.lmgtfy.com/?q=c99&l=1>
> <snip>
--
Peter
On 13 July, 05:55, noth...@geocities.com wrote:>
> On 07/12/2010 03:30:01:896 Vincenzo Mercuri <vincenzo.merc...@gmail.com> wrote:
<snip>
> > Yes, this is right for C90. Nevertheless compiling under C99
> > mode, you will always get -20
>
> What's C99?
The C programming language has been standardised originally by the
American standards organisation, ANSI. This standard was adopted,
essentially unchanged, by the International standards organistaion,
ISO. As the ANSI standard came out in 1989 it (and its ISO equivalent)
are often referred to as C89 (occaisionally as C90 (the date of ISO
adoption)). In 1999 ISO issued a new standard for C and this is often
referred to as C99. C99 tightened up some definitions including the
meaning of division for negative numbers.
Well, actually I don't know if the assembly implementation
of the '/' operator is so different from that of a set of
expressions with shift operators. But I think it is likely
the case. :-)
--
Vincenzo Mercuri
its quite common for compilers to substitute shifts for divides by
powers of 2