- **C Programming**
(*http://www.velocityreviews.com/forums/f42-c-programming.html*)

- - **Portable way to mask the LSB**
(*http://www.velocityreviews.com/forums/t724360-portable-way-to-mask-the-lsb.html*)

Portable way to mask the LSBHello,
I just realize that I'm not sure how to do this in a portable way. Consider this piece of code: unsigned long u; /* ... */ u = u & ~1; /* mask the LSB */ In my understanding, this only works if the value of the expression '~1' is -2. So it depends on how object with signed integer type are encoded (2's complement, 1's complement ...). Is this correct ? If so, how should I rewrite the code to make it portable ? u = u & ~1UL; u = u & ~(unsigned long)1; or u = u & (ULONG_MAX - 1); Are these alternatives correct ? Thanks |

Re: Portable way to mask the LSBOn Sat, 29 May 2010 05:32:12 -0700, Francis Moreau wrote:
> Hello, > > I just realize that I'm not sure how to do this in a portable way. > > Consider this piece of code: > > unsigned long u; > /* ... */ > u = u & ~1; /* mask the LSB */ > > In my understanding, this only works if the value of the expression '~1' > is -2. So it depends on how object with signed integer type are encoded > (2's complement, 1's complement ...). > > Is this correct ? > > If so, how should I rewrite the code to make it portable ? > > u = u & ~1UL; This one seems reasonable to me. > u = u & ~(unsigned long)1; > or > u = u & (ULONG_MAX - 1); > > Are these alternatives correct ? > > Thanks Don't forget u = ((u >>1) <<1); HTH, AvK |

Re: Portable way to mask the LSBOn 5/29/2010 8:32 AM, Francis Moreau wrote:
> Hello, > > I just realize that I'm not sure how to do this in a portable way. > > Consider this piece of code: > > unsigned long u; > /* ... */ > u = u& ~1; /* mask the LSB */ > > In my understanding, this only works if the value of the expression > '~1' is -2. So it depends on how object with signed integer type are > encoded (2's complement, 1's complement ...). > > Is this correct ? Yes. `~1' yields the bitwise complement of `1', consisting of a low-order zero bit and all the other bits set (including the sign bit). The numeric value of this batch of bits depends on how the system encodes negative integers: You could get -2 (two's complement), -1 (ones' complement), or 1-INT_MAX (signed magnitude). To apply the `&', `~1' is first converted to unsigned long, and this conversion is defined in terms of the numeric values of `~1' and of `ULONG_MAX'. Since there are three possible values for `~1', there are three possible outcomes for the conversion (only one outcome on any one machine, of course). > If so, how should I rewrite the code to make it portable ? > > u = u& ~1UL; > u = u& ~(unsigned long)1; > or > u = u& (ULONG_MAX - 1); > > Are these alternatives correct ? Yes. I would vote for `u &= ~1UL'. More generally, to clear the k'th bit, `u &= ~(1UL << k)'. -- Eric Sosman esosman@ieee-dot-org.invalid |

Re: Portable way to mask the LSBOn 29 mai, 15:06, Moi <r...@invalid.address.org> wrote:
> On Sat, 29 May 2010 05:32:12 -0700, Francis Moreau wrote: > > Hello, > > > I just realize that I'm not sure how to do this in a portable way. > > > Consider this piece of code: > > > * * unsigned long u; > > * * /* ... */ > > * * u = u & ~1; /* mask the LSB */ > > > In my understanding, this only works if the value of the expression '~1' > > is -2. So it depends on how object with signed integer type are encoded > > (2's complement, 1's complement ...). > > > Is this correct ? > > > If so, how should I rewrite the code to make it portable ? > > > * * u = u & ~1UL; > > This one seems reasonable to me. > > > * * u = u & ~(unsigned long)1; > > or > > * * u = u & (ULONG_MAX - 1); > > > Are these alternatives correct ? > > > Thanks > > Don't forget > u = ((u >>1) <<1); Do you think that this version could be faster ? Thanks |

Re: Portable way to mask the LSBOn Sun, 30 May 2010 12:44:45 -0700, Francis Moreau wrote:
> On 29 mai, 15:06, Moi <r...@invalid.address.org> wrote: >> On Sat, 29 May 2010 05:32:12 -0700, Francis Moreau wrote: >> > Hello, >> >> > I just realize that I'm not sure how to do this in a portable way. >> >> > Consider this piece of code: >> >> > Â* Â* unsigned long u; >> > Â* Â* /* ... */ >> > Â* Â* u = u & ~1; /* mask the LSB */ >> >> > In my understanding, this only works if the value of the expression >> > '~1' is -2. So it depends on how object with signed integer type are >> > encoded (2's complement, 1's complement ...). >> >> > Is this correct ? >> >> > If so, how should I rewrite the code to make it portable ? >> >> > Â* Â* u = u & ~1UL; >> >> This one seems reasonable to me. >> >> > Â* Â* u = u & ~(unsigned long)1; >> > or >> > Â* Â* u = u & (ULONG_MAX - 1); >> >> > Are these alternatives correct ? >> >> > Thanks >> >> Don't forget >> u = ((u >>1) <<1); > > Do you think that this version could be faster ? No. Basically, I don't care about speed. In trivial operations like this, it is the speed of access to the memory (or caches) that dominates the overall speed. In all cases it winds down to fetch+"some operations"+ one store. My suggestion has the advantage that there is no possible size mismatch; other ways to perform the same operation may be sensitive to the size of the bitmask-constant (~1 vs ~1ul vs ~1ull). Also, the bitmask constant may be compiled into a literal constant in the instruction stream, which may cost a 32 bit or 64 bit constant to be emitted. (GCC on intel mostly uses immediate 0xfe which gets sign-extended) BTW: GCC -O6 compiles my shiftR-shiftL code into exactly the same instruction sequence as the &= ~1 or &= -1ull - versions. HTH, AvK |

Re: Portable way to mask the LSBOn May 30, 5:10*pm, Moi <r...@invalid.address.org> wrote:
> BTW: GCC -O6 compiles my shiftR-shiftL code into exactly the same > instruction sequence as the &= ~1 or &= -1ull - versions. There is no such thing as -O6 in GCC. It goes up to 3 only. I suggest you read the GCC manpage sometime. Tom |

Re: Portable way to mask the LSBOn 31 mai, 12:56, Tom St Denis <t...@iahu.ca> wrote:
> On May 30, 5:10*pm, Moi <r...@invalid.address.org> wrote: > > > BTW: GCC -O6 compiles my shiftR-shiftL code into exactly the same > > instruction sequence as the &= ~1 or &= -1ull - versions. > > There is no such thing as -O6 in GCC. *It goes up to 3 only. > > I suggest you read the GCC manpage sometime. Next time I suggest you just stop sending such useless posts. |

Re: Portable way to mask the LSBTom St Denis <tom@iahu.ca> writes:
> On May 30, 5:10Â*pm, Moi <r...@invalid.address.org> wrote: >> BTW: GCC -O6 compiles my shiftR-shiftL code into exactly the same >> instruction sequence as the &= ~1 or &= -1ull - versions. > > There is no such thing as -O6 in GCC. It goes up to 3 only. > > I suggest you read the GCC manpage sometime. <OT> gcc quietly accepts "-O6". It doesn't seem to be documented, but as far as I can tell it's equivalent to "-O3". In fact, -On for any n greater than 3 appears to be equivalent to "-O3". </OT> -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |

All times are GMT. The time now is 12:36 PM. |

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.

SEO by vBSEO ©2010, Crawlability, Inc.