473,394 Members | 1,717 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

x == 0 && (x & -1) != 0 for negative zero?

As far as I can tell, (x & -1) is nonzero if the integer x is
negative zero. So for signed types, x == 0 does not guarantee
(x & foo) == 0. Is that right? (Not that I expect to ever
encounter a non-two's-complement machine. Just wondering.)

--
Hallvard
Sep 11 '07 #1
23 4327
I wrote:
As far as I can tell, (x & -1) is nonzero if the integer x is
negative zero.
Er, for one's complement anyway. To get weirdness with
sign/magnitude as well, we'd need x == 0 && (x ^ 1) < 0.
Or (x >1) != 0, but that's implementation-defined.
So for signed types, x == 0 does not guarantee
(x & foo) == 0. Is that right? (Not that I expect to ever
encounter a non-two's-complement machine. Just wondering.)
--
Hallvard
Sep 11 '07 #2
Hallvard B Furuseth wrote:
I wrote:
>As far as I can tell, (x & -1) is nonzero if the integer x is
negative zero.

Er, for one's complement anyway. To get weirdness with
sign/magnitude as well, we'd need x == 0 && (x ^ 1) < 0.
Or (x >1) != 0, but that's implementation-defined.
>So for signed types, x == 0 does not guarantee
(x & foo) == 0. Is that right? (Not that I expect to ever
encounter a non-two's-complement machine. Just wondering.)
Why would you ever use bitwise operations on signed operands? Bitwise
logic implies that you've got some bitmap, the natural (and the C) model
for it is an unsigned type. [And I suppose you meant (unsigned)-1.]
-- Ark

Sep 12 '07 #3
Ark Khasin writes:
>Hallvard B Furuseth wrote:
>>I wrote:
>>As far as I can tell, (x & -1) is nonzero if the integer x is
negative zero.

Er, for one's complement anyway. To get weirdness with
sign/magnitude as well, we'd need x == 0 && (x ^ 1) < 0.
Or (x >1) != 0, but that's implementation-defined.
>>So for signed types, x == 0 does not guarantee
(x & foo) == 0. Is that right? (Not that I expect to ever
encounter a non-two's-complement machine. Just wondering.)

Why would you ever use bitwise operations on signed operands? Bitwise
logic implies that you've got some bitmap, the natural (and the C) model
for it is an unsigned type.
Bitwise logic implies that bitwise operations are useful at the moment.
Could be just for e.g. 'a & 15' instead of 'a / 16'.

Bit operations on signed integers are common enough, e.g. if one knows
that only a fwe of the least siginificant bits are used.

Also the choice of type for a variable depends on all the ways it's
used, including things like the API for passing it, how it's
read/written, and what other integer types it will meet.
[And I suppose you meant (unsigned)-1.]
No, (unsigned)-1 is not signed.

--
Hallvard
Sep 13 '07 #4
Hallvard B Furuseth wrote:
Bitwise logic implies that bitwise operations are useful at the moment.
Could be just for e.g. 'a & 15' instead of 'a / 16'.
Those are not the same (think of negative a). `a & 15U` is the same as
`a / 16U` if sizeof(a) <=sizeof(unsigned). But I want to see a compiler
that doesn't optimize the latter.
>
Bit operations on signed integers are common enough,
which doesn't make it a good practice
e.g. if one knows
that only a fwe of the least siginificant bits are used.
>
Also the choice of type for a variable depends on all the ways it's
used, including things like the API for passing it, how it's
read/written, and what other integer types it will meet.
Yes. Designing good API is not for the faint of heart. Which fact
doesn't change the point.

-- Ark
Sep 16 '07 #5
Ark Khasin wrote:
>
Hallvard B Furuseth wrote:
Bitwise logic implies that bitwise operations
are useful at the moment.
Could be just for e.g. 'a & 15' instead of 'a / 16'.
Those are not the same (think of negative a). `a & 15U` is the same as
`a / 16U` if sizeof(a) <=sizeof(unsigned).
But I want to see a compiler
that doesn't optimize the latter.
(a & 15) is closer to (a % 16) than to (a / 16)

--
pete
Sep 16 '07 #6
Ark Khasin writes:
>Hallvard B Furuseth wrote:
>Bitwise logic implies that bitwise operations are useful at the moment.
Could be just for e.g. 'a & 15' instead of 'a / 16'.
Duh, a%16 as pete says.
Those are not the same (think of negative a).
They are the same if you know, which you sometimes do, that
a is nonnegtive. _Unless_ (negative zero) & 15 can be 15.
(...)
>Bit operations on signed integers are common enough,
which doesn't make it a good practice
What is not good practice is to make a strict rule out of a general
guideline like "be careful about signed bit operations". Or "avoid
goto".
>e.g. if one knows
that only a fwe of the least siginificant bits are used.
>Also the choice of type for a variable depends on all the ways it's
used, including things like the API for passing it, how it's
read/written, and what other integer types it will meet.

Yes. Designing good API is not for the faint of heart.
Indeed. And two things to keep in mind is that (a) the API can be more
important than how a function works internally, and (b) the API may
anyway be imposed by something or someone else.
Which fact doesn't change the point.
The point is that I asked a technical question about code which
occurs every now and then, and I wondered if that code is correct.

--
Hallvard
Sep 17 '07 #7
"Hallvard B Furuseth" <h.**********@usit.uio.noa écrit dans le message de
news: hb**************@bombur.uio.no...
Ark Khasin writes:
>>Hallvard B Furuseth wrote:
>>Bitwise logic implies that bitwise operations are useful at the moment.
Could be just for e.g. 'a & 15' instead of 'a / 16'.

Duh, a%16 as pete says.
>Those are not the same (think of negative a).

They are the same if you know, which you sometimes do, that
a is nonnegtive.
You the programmer may know that, but if the compiler cannot determine for
sure that the value is always positive, it has to generate code that can
handle all cases. Since division truncates toward zero, ASR (arithmetic
right shift for division) or bitmask (for modulo) is not a solution, it has
to be corrected for negative values, which can be done through appropriate
bit trickery (on 2s complement architectures ;-).
If you know a can only hold positive values, you can tell the compiler by
casting it as unsigned (how ugly!) or you can use the shift or mask
operations (if the divisor is an explicit power of two).
_Unless_ (negative zero) & 15 can be 15.
I don't think that's possible.
but negative_zero >4 invokes UB anyway.
>>Bit operations on signed integers are common enough,
which doesn't make it a good practice

What is not good practice is to make a strict rule out of a general
guideline like "be careful about signed bit operations". Or "avoid
goto".
There is one good thing about right shifting negative values: the result is
implementation defined, not undefined behaviour. You can rely on this
operation having consistent behaviour for a given implementation.

--
Chqrlie.
Sep 18 '07 #8
Charlie Gordon writes:
>"Hallvard B Furuseth" <h.**********@usit.uio.noa écrit dans le message de
news: hb**************@bombur.uio.no...
>Ark Khasin writes:
>>>Hallvard B Furuseth wrote:
Bitwise logic implies that bitwise operations are useful at the moment.
Could be just for e.g. 'a & 15' instead of 'a / 16'.

Duh, a%16 as pete says.
>>Those are not the same (think of negative a).

They are the same if you know, which you sometimes do, that
a is nonnegtive.

You the programmer may know that, but if the compiler cannot determine
for sure that the value is always positive, it has to generate code
that can handle all cases. (...) If you know a can only hold positive
values, you can tell the compiler by casting it as unsigned (how
ugly!) or you can use the shift or mask operations (if the divisor is
an explicit power of two).
Yes. So despite purist "don't use bit operations on signed values",
doing that does make sense at times and is done at times.

Except, that should be "nonnegative", not "positive" (which means larger
than zero), and of course the compiler sometimes can know if a value is
nonnegative, regardless of its signedness.
>_Unless_ (negative zero) & 15 can be 15.

I don't think that's possible.
Why not? Does the standard say? That's what I'm asking about.
but negative_zero >4 invokes UB anyway.
I suspect so, yes. Which is one reason I asked about the
"gentler" bit operations, & and |. (If even they can
produce nonzero, certainly >can.)

--
Hallvard
Sep 18 '07 #9
Hallvard B Furuseth wrote:
Charlie Gordon writes:
>"Hallvard B Furuseth" <h.**********@usit.uio.noa écrit:
.... snip ...
>
>>_Unless_ (negative zero) & 15 can be 15.

I don't think that's possible.

Why not? Does the standard say? That's what I'm asking about.
>but negative_zero >4 invokes UB anyway.

I suspect so, yes. Which is one reason I asked about the
"gentler" bit operations, & and |. (If even they can produce
nonzero, certainly >can.)
The only form -0 can take, in an int, ignoring padding bits and
expressing the result as a hex 16 bit value (for other lengths
insert more copies of the middle bits) are:

0x0000 2's complement
0xFFFF 1's complement
0x8000 sign/magnitude.

Since these are the only representations allowed in C, it is
obvious that a masking operation can only produce 15 for a 1's
complement machine.

With any luck, this will exterminate this thread.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 19 '07 #10
On Tue, 18 Sep 2007 16:57:50 -0400, CBFalconer wrote:
The only form -0 can take, in an int, ignoring padding bits and
expressing the result as a hex 16 bit value (for other lengths insert
more copies of the middle bits) are:

0x0000 2's complement
0xFFFF 1's complement
0x8000 sign/magnitude.
The only forms negative zero can take are:

0xFFFF 1s' complement
0x8000 sign/magnitude.

Negative zero doesn't exist in 2's complement. And the only forms -0 can
take are:

0x0000 2's complement
0x0000 1s' complement
0x0000 sign/magnitude.

since -0 is not negative zero regardless of representation.
Sep 19 '07 #11
Op Wed, 19 Sep 2007 16:49:08 +0000 (UTC) schreef $)CHarald van D)&k:

<snip>
Negative zero doesn't exist in 2's complement. And the only forms -0 can
+0 ;-)
take are:

0x0000 2's complement
0x0000 1s' complement
0x0000 sign/magnitude.

since -0 is not negative zero regardless of representation.
+0
--
Coos
Sep 19 '07 #12
On Wed, 19 Sep 2007 19:03:07 +0200, Coos Haak wrote:
Op Wed, 19 Sep 2007 16:49:08 +0000 (UTC) schreef $)CHarald van D)
&k:
>
<snip>
>Negative zero doesn't exist in 2's complement. And the only forms -0
can
+0
;-)
>take are:

0x0000 2's complement
0x0000 1s' complement
0x0000 sign/magnitude.

since -0 is not negative zero regardless of representation.
+0
My point was that -0 is always the same thing as +0. -0 is not allowed to
give you a negative zero.
Sep 19 '07 #13
$)CHarald van D)&k wrote:
CBFalconer wrote:
>The only form -0 can take, in an int, ignoring padding bits and
expressing the result as a hex 16 bit value (for other lengths
insert more copies of the middle bits) are:

0x0000 2's complement
0xFFFF 1's complement
0x8000 sign/magnitude.

The only forms negative zero can take are:

0xFFFF 1s' complement
0x8000 sign/magnitude.

Negative zero doesn't exist in 2's complement. And the only forms
-0 can take are:
No, in 2's complement (-ve zero == +ve zero). Both are zero.
However, in all systems, ((-0 + +0) == 0) :-)

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 20 '07 #14
In article <fc**********@news6.zwoll1.ov.home.nl=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0Fk?= <tr*****@gmail.comwrites:
My point was that -0 is always the same thing as +0. -0 is not allowed to
give you a negative zero.
Where in the standard is that stated? Note that on 1's complement
machines negative and positive zero compare as equal.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Sep 20 '07 #15
Dik T. Winter wrote:
In article <fc**********@news6.zwoll1.ov.home.nl>
=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0Fk?=
<tr*****@gmail.comwrites:
My point was that -0 is always the same thing as +0. -0 is
not allowed to give you a negative zero.

Where in the standard is that stated? Note that on 1's
complement machines negative and positive zero compare as
equal.
| 6.2.6.2 (Representations of) Integer types, p3.
| If the implementation supports negative zeros, they shall be
| generated only by:
| — the &, |, ^, ~, <<, and >operators with arguments that
| produce such a value;
| — the +, -, *, /, and % operators where one argument is a
| negative zero and the result is zero;
| — compound assignment operators based on the above cases.
| It is unspecified whether these cases actually generate a
| negative zero or a normal zero, and whether a negative zero
| becomes a normal zero when stored in an object.

That forbids -0 to be negative zero.

Ralf
Sep 20 '07 #16
On Wed, 19 Sep 2007 22:09:41 -0400, CBFalconer wrote:
$)CHarald van D)&k wrote:
>CBFalconer wrote:
>>The only form -0 can take, in an int, ignoring padding bits and
expressing the result as a hex 16 bit value (for other lengths insert
more copies of the middle bits) are:

0x0000 2's complement
0xFFFF 1's complement
0x8000 sign/magnitude.

The only forms negative zero can take are:

0xFFFF 1s' complement
0x8000 sign/magnitude.

Negative zero doesn't exist in 2's complement. And the only forms -0
can take are:

No, in 2's complement (-ve zero == +ve zero). Both are zero.
This is the definition of negative zero, from 6.2.6.2p2:
"Which of these applies is implementation-defined, as is whether the
value with sign bit 1 and all value bits zero (for the first two), or
with sign bit and all value bits 1 (for ones' complement), is a trap
representation or a normal value. In the case of sign and magnitude and
ones' complement, if this representation is a normal value it is called a
/negative zero/."

Negative zero doesn't exist in 2's complement. It's not equal to positive
zero. It simply doesn't exist.
However,
in all systems, ((-0 + +0) == 0) :-)
Yes, because -0 is the same thing as +0 and plain 0, and because negative
zero compares equal to normal zero. But negative zero plus normal zero is
allowed to give you a negative zero.
Sep 20 '07 #17
Op Thu, 20 Sep 2007 16:56:14 +0000 (UTC) schreef Ralf Damaschke:
Dik T. Winter wrote:
>In article <fc**********@news6.zwoll1.ov.home.nl>
=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0Fk?=
<tr*****@gmail.comwrites:
>>My point was that -0 is always the same thing as +0. -0 is
not allowed to give you a negative zero.

Where in the standard is that stated? Note that on 1's
complement machines negative and positive zero compare as
equal.

| 6.2.6.2 (Representations of) Integer types, p3.
| If the implementation supports negative zeros, they shall be
| generated only by:
| ¡X the &, |, ^, ~, <<, and >operators with arguments that
| produce such a value;
| ¡X the +, -, *, /, and % operators where one argument is a
| negative zero and the result is zero;
| ¡X compound assignment operators based on the above cases.
| It is unspecified whether these cases actually generate a
| negative zero or a normal zero, and whether a negative zero
| becomes a normal zero when stored in an object.

That forbids -0 to be negative zero.
In 1-complement, a row of only zero-bits represents zero (+0).
A row of only one-bits represents minus zero (-0).
The last sentence of 6.2.6.2 leaves _unspecified_ whether minus zero
becomes plus zero. It doesn't forbid it either.
--
Coos
Sep 20 '07 #18
On Thu, 20 Sep 2007 19:32:46 +0200, Coos Haak wrote:
Op Thu, 20 Sep 2007 16:56:14 +0000 (UTC) schreef Ralf Damaschke:
>Dik T. Winter wrote:
>>In article <fc**********@news6.zwoll1.ov.home.nl>
=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0Fk?=
<tr*****@gmail.comwrites:
My point was that -0 is always the same thing as +0. -0 is not
allowed to give you a negative zero.

Where in the standard is that stated? Note that on 1's complement
machines negative and positive zero compare as equal.

| 6.2.6.2 (Representations of) Integer types, p3. | If the
implementation supports negative zeros, they shall be | generated only
by:
| — the &, |, ^, ~, <<, and >operators with arguments that | produce
such a value;
| — the +, -, *, /, and % operators where one argument is a | negative
zero and the result is zero; | — compound assignment operators based on
the above cases. | It is unspecified whether these cases actually
generate a | negative zero or a normal zero, and whether a negative zero
| becomes a normal zero when stored in an object.

That forbids -0 to be negative zero.

In 1-complement, a row of only zero-bits represents zero (+0). A row of
only one-bits represents minus zero (-0). The last sentence of 6.2.6.2
leaves _unspecified_ whether minus zero becomes plus zero. It doesn't
forbid it either.
Correct, but that doesn't matter here. It's the first sentence that
matters: -0 (negated plain zero) has none of the bitwise operators, and
doesn't have a negative zero as an operand to any other operator, so it's
not allowed to be negative zero.
Sep 20 '07 #19
CBFalconer writes:
Since these are the only representations allowed in C, it is
obvious that a masking operation can only produce 15 for a 1's
complement machine.
Well, yes. What I wondered was if it _can_ produce 15, or if
I've missed something and it can produce 0:

In C89, I can't find anything so I guess anything goes.
In C99, 6.2.6.2p3 says what can _generate_ negative zero and
that it's unspecified whether that becomes normal zero when
stored in an object. I find nothing else which says an
existing negative zero can be converted to normal zero.
With any luck, this will exterminate this thread.
Har har.

--
Hallvard
Sep 20 '07 #20
iRo
In data Wed, 19 Sep 2007 16:49:08 +0000 (UTC), $)CHarald van D)&k
<tr*****@gmail.com scrisse:
>On Tue, 18 Sep 2007 16:57:50 -0400, CBFalconer wrote:
>The only form -0 can take, in an int, ignoring padding bits and
expressing the result as a hex 16 bit value (for other lengths insert
more copies of the middle bits) are:

0x0000 2's complement
0xFFFF 1's complement
0x8000 sign/magnitude.

The only forms negative zero can take are:

0xFFFF 1s' complement
0x8000 sign/magnitude.

Negative zero doesn't exist in 2's complement. And the only forms -0 can
take are:

0x0000 2's complement
0x0000 1s' complement
0x0000 sign/magnitude.

since -0 is not negative zero regardless of representation.
pheraps: unsigned i=0; --i;

so it should be "--0" and not "-0"
Sep 21 '07 #21
iRo <xy*@not.inusewrites:
In data Wed, 19 Sep 2007 16:49:08 +0000 (UTC), $)CHarald van D)&k
<tr*****@gmail.com scrisse:
[...]
>>Negative zero doesn't exist in 2's complement. And the only forms -0 can
take are:

0x0000 2's complement
0x0000 1s' complement
0x0000 sign/magnitude.

since -0 is not negative zero regardless of representation.

pheraps: unsigned i=0; --i;
I'm not sure what you're trying to say here. The above decrements i,
setting it to UINT_MAX.
so it should be "--0" and not "-0"
--0 is illegal, since "--" is a single token. Did you mean to apply
unary '-' twice? If so, you can write it as '- -0', or as '-(-0)'
(or, equivalently, just as 0).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 21 '07 #22
iRo wrote:
>
.... snip ...
>
pheraps: unsigned i=0; --i;

so it should be "--0" and not "-0"
You just generated UINT_MAX.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 21 '07 #23
CBFalconer <cb********@yahoo.comwrote:
iRo wrote:
pheraps: unsigned i=0; --i;

so it should be "--0" and not "-0"

You just generated UINT_MAX.
No, he didn't. He generated a constraint violation: the constant 0 is
not a modifiable lvalue.
--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com
Fix your .sig.

Richard
Sep 24 '07 #24

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

39
by: Zak McGregor | last post by:
Hi all Are there any good solutions to aligning form field names and input boxes without resorting to tables? I am struggling to do this nicely at the moment. Thanks Ciao Zak
6
by: Tom Watson | last post by:
I know that K&R I exists. Wonderful reference. I know K&R II exists, even bought a couple. ANSI C (C89) is a wonderful thing. Works fine. Now that we have had C99 (or whatever it is called...
10
by: Peter Dunker | last post by:
Hi, I will check a String which should contain a HEX value. I know that strtol is the right function for this job. But what happens when I will check a hex string with 8 bytes? That I can...
12
by: Merrill & Michele | last post by:
It's very difficult to do an exercise with elementary tools. It took me about fifteen minutes to get exercise 1-7: #include <stdio.h> int main(int orange, char **apple) { int c; c=-5;...
27
by: Daniel Vallstrom | last post by:
I'm having problems with inconsistent floating point behavior resulting in e.g. assert( x > 0.0 && putchar('\n') && x == 0.0 ); holding. (Actually, my problem is the dual one where I get...
4
&&
by: plmanikandan | last post by:
Hi, I am have basic doubt in && operator for example what happens when we manipulate negative value and postive value using 'AND' operation void main() int j=-10,int k=11,c=0;
23
by: Jorge Peixoto | last post by:
In the answer to question 12.42 of the C FAQ, we have this code: putc((unsigned)((s.i32 >24) & 0xff), fp); putc((unsigned)((s.i32 >16) & 0xff), fp); putc((unsigned)((s.i32 >8) & 0xff), fp);...
8
by: RN1 | last post by:
The book I am referring to learn ASP states the following about the Int & Fix VBScript Maths functions: ========================================= Both Int & Fix return the integer portion of the...
88
by: santosh | last post by:
Hello all, In K&R2 one exercise asks the reader to compute and print the limits for the basic integer types. This is trivial for unsigned types. But is it possible for signed types without...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.