From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 109fba,30e368bdb3310fe5 X-Google-Attributes: gid109fba,public X-Google-Thread: 1008e3,30e368bdb3310fe5 X-Google-Attributes: gid1008e3,public X-Google-Thread: 103376,30e368bdb3310fe5 X-Google-Attributes: gid103376,public X-Google-Thread: 1014db,30e368bdb3310fe5 X-Google-Attributes: gid1014db,public X-Google-Thread: f8c65,30e368bdb3310fe5 X-Google-Attributes: gidf8c65,public From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku) Subject: Re: Hungarian notation - whoops! Date: 1996/02/22 Message-ID: <4gip1iINNjd@keats.ugrad.cs.ubc.ca> X-Deja-AN: 140631016 references: <30C40F77.53B5@swsbbs.com> <4fms62$c0p@goanna.cs.rmit.EDU.AU> <4ft1ruINN6dr@keats.ugrad.cs.ubc.ca> <4g9255$74s@goanna.cs.rmit.EDU.AU> organization: Computer Science, University of B.C., Vancouver, B.C., Canada newsgroups: comp.lang.ada,comp.lang.c++,comp.lang.c,comp.lang.modula3,comp.lang.modula2 Date: 1996-02-22T00:00:00+00:00 List-Id: In article <4g9255$74s@goanna.cs.rmit.EDU.AU>, Richard A. O'Keefe wrote: >It so happens that the C standard was carefully crafted to allow >2s complement, 1s complement, AND sign-and-magnitude. > >I wrote: > But the fact that abs(x) may deliver a negative > number is something I have to live with the whole time. It does so for the largest negative value. This is documented. Unfortunately, as you claim, you do have to check that yourself. And of course, to know what the largest negative value is, you can use the standard #defined manifest constants. It's not like abs() returns a negative value for any old random input. The fact of the matter is that the additive inverse of the largest negative value under two's complement simply can't be represented in a two's complement word of the same size, yet the return value from abs() is a signed quantity. Shrug. I hear what you are saying though. >Kazimir Kyheku again completely misses the point by a country mile. > >>Not true. If you use the unsigned type, there is no such thing as overflow. >>It's called residue math. No operation between two unsigned numbers yields >>undefined results. The "X % Y" operation between unsigned numbers gives you the >>smallest positive residue of X with respect to Y. Nothing undefined or >>overflown about that. > >Kazimir, you will get a LOT further in life if you realise that people who >disagree with you sometimes know what they are talking about. > >The abs function in C is defined by the standard to take SIGNED int as >parameter and deliver SIGNED int as result. I am not claiming now, did You can cast it to an unsigned type. From K&R2 (A6.2): Any integer is converted to a given unsigned type by finding the smallest non-negative value that is congruent to that integer, modulo one more than the largest value that can be represented in the unsigned type. In a two's complement representation, this is equivalent to left-truncation if the bit pattern of the unsigned type is narrower, and to zero-filling unsigned values and sign-extending signed values if the unsigned type is wider. If the unsigned type you convert to is the same size as the signed return type from abs(), you will catch the the right absolute value in the conversion to unsigned without invoking undefined, or implementation-defined behavior. If the unsigned type is wider, of course, the sign extension will mess you up! And this does not address the "-x" problem, to which there is no solution under two's complement arithmetic. >pointers to get unsigned. I kid you not.) By the way, "X % 0" is still >undefined in unsigned arithmetic, so the claim that there is "nothing >undefined" about it is not true. That goes without saying. >Let me say it again: > > C, like many programming languages, has two mathematically > simple functions on ***SIGNED*** integers: > -x > abs(x) > An implementation of C, or any other such language, using > ones-complement or sign-and-magnitude arithmetic, easily > delivers correct outputs for all legal inputs to these operations. > An implementation of C, or any other such language, using > twos-complement arithmetic, EITHER delivers incorrect outputs > for some legal inputs OR requires checking which is in practice > seldom offered. For _one_ legal input. :) >Now, it so happens that a C compiler _is_ free to generate overflow checks >for signed integer arithmetic, so a twos-complement implementation COULD >guarantee "correct result or exception in all cases". This is occasionally >done for Pascal compilers. I have access to three C compilers (lcc, gcc, >and SPARCompiler cc) and if any of them has an option to check that signed >arithmetic is done correctly I would be most grateful to be told what it is. > >The practical consequence of this is that responsibility for ensuring that >the input to unary minus or absolute value is in range is passed onto the >programmer. It is that which I am complaining about. It doesn't make my >life as a programmer one teeny tiny bit easier. > >>The unsigned type is the ticket for portable integer modulo arithmetic. > >Modular arithmetic in Ada 95 *is* the ticket for portable hackery. >Unsigned arithmetic in C is indeed defined to be modulo 2**n for some >n, but the bounds on n are very very loose, and the price of portability >is much programmer-inserted masking. I didn't say that it wasn't. But the Ada compiler has to also do a little ``code explosion'' to ensure the same portability as your C with programmer inserted masking. >More importantly, while overflow in signed arithmetic is a run-time error, >unsigned arithmetic is very often a design-time error. > >For example, suppose I want to count the number of times some event occurs. >Unless I can *prove* at design time that the event can occur no more than >65535 times, use of 'unsigned int' in C is a design-time error. There is True. >at least one "commodity ISA" with a 300Mhz implementation getting close. >How long is a 32-bit unsigned counter usable with 3e8 events per second? > >A little over 14 seconds. > >Overflows aren't the problem. Restricted machine arithmetic is the problem. Not much you can do about the machine, as a programmer and supporting multi-precision arithmetic in any language imposes a lot of overhead and code explosion. The C standard does give you a minimum maximum unsigned integer of 2^32-1. If you need a counter that has more precision, you can use more such numbers. That it's a pain and inconvenience, I will not deny. I also won't deny that it will give poor performance on a machine where higher precision quantities can be directly manipulated. Hence we have C progams littered with #ifdefs. Ideally, you should be able to specify in a program the expected range for an integer, so that the compiler will either fail to translate, or generate the extra arithmetic code for maintaining the given precision. That sort of goes against the spirt of C, which is that operations are usually implemented using suitable idioms of the target architecture. It seems that this philosophy is ultimately the source of your (and other people's) understandable frustrations. >>You need unaligned access if you want to have packed character arrays. > >Sorry, but this simply isn't true. It may surprise you to know that Pascal You are right. I don't know why I wrote that, when later on I clearly contradicted that by saying that such access can be emulated with inline code, so you don't need the addressability or unaligned access at the hardware level. Let the second statement be taken as official. BTW do you have some sort of specific gripe with two's complement representations of integer arithmetic? --