jhsu@Neon.Stanford.EDU (Jeffrey H. Hsu) (07/17/90)
Fellow C hackers,
Here is a C question I was asked at a Microsoft interview (no, I didn't
get the job...).
How would you write a space efficient algorithm/function in C that
takes in an integer and returns 0 if signed and 1 if unsigned?
IsUnsigned(a)
int a;
{
}
I would appreciate answers from anyone.
Thanks,
Jeff
diamond@tkou02.enet.dec.com (diamond@tkovoa) (07/17/90)
In article <1990Jul16.214155.5087@Neon.Stanford.EDU> jhsu@Neon.Stanford.EDU (Jeffrey H. Hsu) writes: > Here is a C question I was asked at a ________t interview > How would you write a space efficient algorithm/function in C that >takes in an integer and returns 0 if signed and 1 if unsigned? > IsUnsigned(a) > int a; > { > } Uh, maybe /* Remember first to #define signed or #define unsigned. */ IsUnsigned(a) #ifdef signed int a; #else unsigned a; #endif { #ifdef signed return 0; #else return 1; #end } Doesn't sound like a job that a programmer would want..... -- Norman Diamond, Nihon DEC diamond@tkou02.enet.dec.com This is me speaking. If you want to hear the company speak, you need DECtalk.
darcy@druid.uucp (D'Arcy J.M. Cain) (07/18/90)
In article <1990Jul16.214155.5087@Neon.Stanford.EDU> jhsu@Neon.Stanford.EDU (Jeffrey H. Hsu) writes: > Here is a C question I was asked at a Microsoft interview (no, I didn't >get the job...). > How would you write a space efficient algorithm/function in C that >takes in an integer and returns 0 if signed and 1 if unsigned? > IsUnsigned(a) > int a; > { > } How about: #define IsUnsigned(a) 0 Since your declaration says that a is an int then you are saying it is always signed. -- D'Arcy J.M. Cain (darcy@druid) | Government: D'Arcy Cain Consulting | Organized crime with an attitude West Hill, Ontario, Canada | (416) 281-6094 |
karl@haddock.ima.isc.com (Karl Heuer) (07/19/90)
In article <1990Jul16.214155.5087@Neon.Stanford.EDU> jhsu@Neon.Stanford.EDU (Jeffrey H. Hsu) writes: >How would you write a space efficient algorithm/function in C that >takes in an integer and returns 0 if signed and 1 if unsigned? Define your terms. Is this to be a function or a macro? If a function, then its argument must have a type known at compile-time: what type is it? Is the goal to determine the signedness of the type of the argument, or the value? A non-trivial specification is to write a macro to find the signedness of the (promoted) type of its argument expression. One way to do this is #define IsUnsigned(x) (((x)*0-2)/2+1 != 0) Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
jak@sactoh0.UUCP (Jay A. Konigsberg) (07/19/90)
In article <1990Jul16.214155.5087@Neon.Stanford.EDU> jhsu@Neon.Stanford.EDU (Jeffrey H. Hsu) writes: > > How would you write a space efficient algorithm/function in C that >takes in an integer and returns 0 if signed and 1 if unsigned? > I would bet that they had something like this in mind. -------------------------------------------------------------------------- #define MASK 10000000 #define TRUE 1 #define FALSE 0 main() { signed(1) ? printf("unsigned\n") : printf("signed\n"); signed(-1) ? printf("unsigned\n") : printf("signed\n"); } signed(number) long number; { if( number & MASK ) return(FALSE); else return(TRUE); } -- ------------------------------------------------------------- Jay @ SAC-UNIX, Sacramento, Ca. UUCP=...pacbell!sactoh0!jak If something is worth doing, its worth doing correctly.
macphee@convex.COM (Scott C. Mac Phee) (07/19/90)
I would think what we are really looking for is :
o Assume (always) that the type we are checking is of type int.
int
IsUnsigned(x)
unsigned x ;
{
return(x&(1<<(sizeof(int)-1))) ;
}
Scott
Convex Computer Corporation
...uunet!convex!macphee
(214) 497-4772
karl@haddock.ima.isc.com (Karl Heuer) (07/20/90)
In article <3539@sactoh0.UUCP> jak@sactoh0.UUCP (Jay A. Konigsberg) writes: >I would bet that they had something like this in mind. > #define MASK 10000000 > signed(number) long number; { > if(number & MASK) return(FALSE); else return(TRUE); > } If that's what they had in mind, then `return (number >= 0)' is a trivial solution-- which doesn't depend on the unspecified internal representation of negative numbers, the number of bits in a long int, or remembering to specify the correct radix for the bitmask. Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
netnews@mtunh.ATT.COM (netnews dptg) (07/20/90)
How about this: IsUnsigned (a) int a; { return( !(a >> ((sizeof(int)*8)-1))); } The only real assumption that this function makes is that there are 8 bits in a byte (a fair assumption I think). If you don't care about portability (I do, though) and like to make more assumptions (like the size of the int on your system) you can make it even shorter: 4 byte int: IsUnsigned (a) int a; { return( !(a >> 31)); } 2 byte int: IsUnsigned (a) int a; { return( !(a >> 15)); } BTW: What you have experienced says much more about Microsoft than about yourself. Don't let it eat you. Ralph Hayon AT&T Bell Laboratories, Middletown, NJ
njk@diku.dk (Niels J|rgen Kruse) (07/20/90)
karl@haddock.ima.isc.com (Karl Heuer) writes: >In article <3539@sactoh0.UUCP> jak@sactoh0.UUCP (Jay A. Konigsberg) writes: >>I would bet that they had something like this in mind. >> #define MASK 10000000 >> signed(number) long number; { >> if(number & MASK) return(FALSE); else return(TRUE); >> } >If that's what they had in mind, then `return (number >= 0)' is a trivial >solution-- which doesn't depend on the unspecified internal representation of >negative numbers, the number of bits in a long int, or remembering to specify >the correct radix for the bitmask. Not to mension giving an integer argument to a function expecting long without prototype in scope and implementing the reverse operation of the one wanted (if it hadn't been for the missing 0x of course). Considering *********'s reputation for buggy code, they just _might_ have liked it. :-) ;-) If squeezing codesize is the big issue, something like this might be better: IsUnsigned (int number) { return ~(unsigned)number / ((unsigned)-1/2 + 1); } This will compile to 2 instructions on most machines with decent compilers (ignoring calling sequence stuff). Gcc on a Vax compiles it to: #NO_APP gcc_compiled.: .text .align 1 .globl _IsUnsigned _IsUnsigned: .word 0x0 mcoml 4(ap),r0 extzv $31,$1,r0,r0 ret But it really is a silly question. I would have been baffled too. Why would anybody ever want to write such a silly function? It is like those riddles, where you know that no matter what you answer, you misunderstood the question. -- Niels J|rgen Kruse DIKU Graduate njk@diku.dk
pmk@craycos.com (Peter Klausler) (07/21/90)
macphee@convex.COM proposes: > int > IsUnsigned(x) > unsigned x ; > { > return(x&(1<<(sizeof(int)-1))) ; > } From this code I can conclude that Convex uses a 1-bit character set and that a sign bit of 1 indicates a positive value, not a negative one. Amazing what's being done in hardware these days, no?
steve@groucho.ucar.edu (Steve Emmerson) (07/22/90)
I would have answered that they (the company) should have a very good reason not to fire the question's author (e.g. they did it deliberately, with malice aforethougt and not from stupidity). Steve Emmerson steve@unidata.ucar.edu ...!ncar!unidata!steve
cwebb@cbnewsk.att.com (charles.a.webb) (07/22/90)
jhsu@Neon.Stanford.EDU (Jeffrey H. Hsu) writes: > Here is a C question I was asked at a Microsoft interview (no, I didn't >get the job...). > How would you write a space efficient algorithm/function in C that >takes in an integer and returns 0 if signed and 1 if unsigned? > IsUnsigned(a) > int a; > { > } Do you really want to test if the int is signed vs unsigned, or positive or negative??? Karl gave an answer to the first question, and indicated that the second question was "trivial." >A non-trivial specification is to write a macro to find the signedness of the >(promoted) type of its argument expression. One way to do this is > #define IsUnsigned(x) (((x)*0-2)/2+1 != 0) > >Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint The answer to the pos vs neg value interpretation of the question can be trivial, but the trivial answer is likely to cause the compiler to generate a compare and branch instruction. If the branches are relatively costly on the machine in question, then perhaps a right shift and xor would be faster. Thus #define IsUnsigned(x) ((((unsigned)(x))>>31)^1) I would be willing to bet that there are some machines that can do this in two instructions - the shift and the xor..... This should be faster and more space efficient on those machines. Note, however, this is highly non-portable, and depends on the sizeof int. a *really* smart compiler should be able to this type of thing automagically, but in my (limited) experience, some compilers can be pretty myopic. If you know all the gory details about the timings of the assembler instructions generated for the particular machine, then you can decide which implementation is most efficient. However, I suspect that in most cases the shift and xor will be faster and more space efficient. (I have assumed a macro since it is silly to use a function call here, especially if the objective is speed!) I have to admit that I'd never have gotten the answer given by Karl (I'm no walking lint :-) However, I might question why you would need such a beast; if the code requires an unsigned int, then specify an unsigned int. IMHO, you should know the type of the expression at compile time, and not have to do this stuff (i.e. don't rely on the default signedness of an int, short or char - if it is important, explicitly declare it or use a cast.) Just some random thoughts. I'd be interested in other opinions. (email) Chip Webb AT&T Bell Labs cwebb@pixels.att.com att!pixels!cwebb (Standard disclaimers apply)
jak@sactoh0.UUCP (Jay A. Konigsberg) (07/22/90)
In article <1990Jul20.144241.2560@diku.dk> njk@diku.dk (Niels J|rgen Kruse) writes: >karl@haddock.ima.isc.com (Karl Heuer) writes: >>In article <3539@sactoh0.UUCP> jak@sactoh0.UUCP (Jay A. Konigsberg) writes: >>>I would bet that they had something like this in mind. >>> #define MASK 10000000 >>> signed(number) long number; { >>> if(number & MASK) return(FALSE); else return(TRUE); >>> } >>If that's what they had in mind, then `return (number >= 0)' is a trivial >>solution-- which doesn't depend on the unspecified internal representation of > >Not to mension giving an integer argument to a function >expecting long without prototype in scope and implementing the >reverse operation of the one wanted (if it hadn't been for the >missing 0x of course). > >Considering *********'s reputation for buggy code, they just >_might_ have liked it. :-) ;-) > >If squeezing codesize is the big issue, something like this >might be better: > >IsUnsigned (int number) { > return ~(unsigned)number / ((unsigned)-1/2 + 1); >} > Well, I'm not the original poster, but I am the one that posted the solution that did the num & MASK solution. Since I've discussed this topic with a local systems programmer/manager at a local company and dicovered that the correct answer is the simple one. Namely: if ( num < 0 ) return FALSE else return TRUE; This is both simple and portable. Still I liked the solution of (num & 1<< (sizeof(int)*8) ) even though it assumes that the sign is stored in the high order bit (which to my surprise isn't always the case). It will always mask that high order bit in a rather elegent fassion. It seems that the original poster left off an important part to the question. Why did you choose the algrothium you used? The question is designed to find people who will make things overly complacted or just don't know very much about how things work - thats where I got traped. I passed by the simple solution because the question seemed to imply that it wasn't the best. Oh well, thats why I read this group. In fact, the systems programmer liked the question so much, he said he was going to include it in his interviews in the future. Well, one good thing has come out of this anyway, I understand more of how C handles the values it stores and how it relates to the under- lying hardware. Gee, one down 9,999,999 to go :-) -- ------------------------------------------------------------- Jay @ SAC-UNIX, Sacramento, Ca. UUCP=...pacbell!sactoh0!jak If something is worth doing, its worth doing correctly.
mcdonald@aries.scs.uiuc.edu (Doug McDonald) (07/22/90)
In article <2936@mtung.ATT.COM> rdh@mtung.ATT.COM (Ralph Hayon) writes: >How about this: > > IsUnsigned (a) IS what is wanted here a decision as to the **TYPE** of the variable, signed or unsigned? I assume so. Then I don't see how a function is possible at all. IT has to have a defined type parameter. Period. On the other hand a macro should be possible on any given machine. But can a portable one be written? Portable to any size int (16 bit, 18 bit, 32 bit, 60 bit, 64 bit...), and to ones or twos complement (sign-magnitude?). This seems like an interesting and useful topic for comp.lang.c. To extend it a bit, how about macros for is_twos_complement() is_ones_complement() word_size(a), which returns the number of bits in a Doug McDonald
williams@umaxc.weeg.uiowa.edu (Kent Williams) (07/23/90)
What I want to know, is what do they mean by IsUnsigned? a. Was the number declared to be unsigned? -- No way to test this -- if it was unsigned, then the sign bit (in most implementation) is just another bit of significance. b. Is the number negative? That is the question everyone seems to be answering, which suggests something trivial like int IsUnsigned(int x) { return x >= 0; } for which most compilers will generate only two or three instructions. c. Something else -- who knows? I noticed a few people couldn't let the chance to do some MicroSoft bashing. C'mon -- worry about something important! They certainly have no monopoly on stupid interview questions. Kent Williams 'Look, I can understand "teenage mutant ninja williams@umaxc.weeg.uiowa.edu turtles", but I can't understand "mutually williams@herky.cs.uiowa.edu recursive inline functions".' - Paul Chisholm -- Kent Williams 'Look, I can understand "teenage mutant ninja williams@umaxc.weeg.uiowa.edu turtles", but I can't understand "mutually williams@herky.cs.uiowa.edu recursive inline functions".' - Paul Chisholm
rick@tetrauk.UUCP (Rick Jones) (07/25/90)
I'm suprised that very few people seems to have grasped what the question was about. I don't have a copy of the original posting, but as I remember the question was "how do you write a function or macro to determine if a variable is unsigned" (or something like that). The question was not "is the value negative", that is absurdly trivial, it was to test for the declaration style - maybe to find if an unqualified char is signed or unsigned, since it can be either. The red herring in the question is the word "function". You can't do it with a function, since the type of a function's formal parameter is defined within the function, it cannot be passed via the call. So the first answer is that it has to be a macro, which will operate on its argument according to the declaration of that argument. The essential characteristic of an unsigned value is that it can never be negative, and the essential characteristic of a signed value is that complementing its most significant bit will change its sign (assuming 2's complement representation, which is pretty safe). Since the other bits are irrelevant to this test, you can complement them all and get the same result. Therefore try the following: #define IsUnsigned(a) (a >= 0 && ~a >= 0) It does work - I've tested it. -- Rick Jones You gotta stand for something Tetra Ltd. Maidenhead, Berks Or you'll fall for anything rick@tetrauk.uucp (...!ukc!tetrauk.uucp!rick) - John Cougar Mellencamp
karl@haddock.ima.isc.com (Karl Heuer) (07/25/90)
In article <15303b1aa0bf26a8c5d4@canremote.uucp> john.russell@canremote.uucp (JOHN RUSSELL) writes: >[What if the idea was to avoid a branch?] If the macro is being used in a Boolean context, then you've got a branch anyway, and simply writing `x >= 0' is optimal. If it's being used in an arithmetic context, *and* if `f = (x >= 0)' generates an inefficient branch that can be avoided by rewriting it in terms of bit-twiddling, *and* if this difference is critical, then the company should be hiring somebody to fix the compiler rather than the source code. And the interviewee should not be expected to deduce all this from the question as asked! Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
karl@haddock.ima.isc.com (Karl Heuer) (07/25/90)
In article <615@tetrauk> rick@tetrauk.UUCP (Rick Jones) writes: >I'm suprised that very few people seems to have grasped what the question was >about. It's because the question was so poorly worded (as posted; I don't know if it was asked the same way). Maybe that was the intent: to see if the interviewee would give the correct response, "What do you mean?", rather than immediately starting to write code. >#define IsUnsigned(a) (a >= 0 && ~a >= 0) I think my version is more likely to fold into a compile-time constant. (I used `((a)*0-2)/2+1 != 0', which is intended to be fairly robust even against questionable compilers.) And why assume 2's-complement if you don't have to? Trivia question: under what circumstances will Rick's macro produce the wrong answer to the presumed question? Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
rick@.tetrauk.UUCP (Rick Jones) (07/26/90)
In article <17147@haddock.ima.isc.com> karl@kelp.ima.isc.com (Karl Heuer) writes: >In article <615@tetrauk> rick@tetrauk.UUCP (Rick Jones) writes: >> >>#define IsUnsigned(a) (a >= 0 && ~a >= 0) > >I think my version is more likely to fold into a compile-time constant. (I >used `((a)*0-2)/2+1 != 0', which is intended to be fairly robust even against >questionable compilers.) And why assume 2's-complement if you don't have to? I don't disagree. I just felt something simple and explicit was worth suggesting since so many people seemed to be going off on weird tangents on this one. >Trivia question: under what circumstances will Rick's macro produce the wrong >answer to the presumed question? Perhaps I should try to answer that myself! a. If signed arithmetic does not use 2's complement notation b. For types shorter than int if the compiler's promotion is wrong Farrell Woods <ftw@westford.ccur.com> mailed me: > It doesn't work for types where sizeof (type) < sizeof (int). I > believe that you can only write a macro which will tell you if the > *promoted* type is signed or unsigned, as Karl Heuer already pointed out. The promoted type retains the signedness of the shorter type (that's my understanding, anyway), and the macro works on all sizes in my test. A question: if a compiler's promotion causes my macro to fail on short types, is the compiler broken? If so, is this macro any use as a compiler test? Or is my brain broken? Comments on a postcard please ... (sorry, wrong technology) -- Rick Jones You gotta stand for something Tetra Ltd. Maidenhead, Berks Or you'll fall for anything rick@tetrauk.uucp (...!ukc!tetrauk.uucp!rick) - John Cougar Mellencamp
karl@haddock.ima.isc.com (Karl Heuer) (07/27/90)
In article <619@.tetrauk.UUCP> rick@tetrauk.UUCP (Rick Jones) writes: >In <17147@haddock.ima.isc.com> karl@kelp.ima.isc.com (Karl Heuer) writes: >>>#define IsUnsigned(a) (a >= 0 && ~a >= 0) >> >>Trivia question: under what circumstances will Rick's macro produce the wrong >>answer to the presumed question? > >Perhaps I should try to answer that myself! >a. If signed arithmetic does not use 2's complement notation Actually I had a more specific answer in mind--even on such machines it works for *most* values. I think there are only two exceptions: a1. The signed value 0 on a one's complement machine a2. The signed value INT_MAX on a sign-magnitude machine In both cases ~a is -0, which is >= 0 despite having the sign bit set. >b. For types shorter than int if the compiler's promotion is wrong > >The promoted type retains the signedness of the shorter type (that's my >understanding, anyway) Nope. Classic C compilers are divided on the issue, and ANSI C requires value-preserving rather than unsigned-preserving promotion. So, if short is 16 bits and int is 32, unsigned short promotes to signed int. Also: c. If the argument is an expression whose primary operator with sufficiently low precedence, e.g. `IsUnsigned(1||1)'. (Fix: parenthesize the two instances of `a' in the macro body.) d. If the arg is an expression with side effects, e.g. `IsUnsigned(*p++)' where `int *p' points into `{ 1, ~1 }'. (Fix: use an algorithm that evaluates the arg only once. Not a problem in practice, since the only use for this macro is in a situation where the side effects would wreak havoc anyway.) Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
will@kfw.COM (Will Crowder) (07/27/90)
I promised myself I wouldn't get into this.... It sounds like the question has to do with whether or not a given *type* is signed or unsigned for a given implementation. That could be a useful thing to know, and ideally, the result would be a compile-time constant. The specific case I'm thinking of char, which, according to ANSI, can be signed or unsigned as the implementation desires. What's wrong with: #define IsUnsigned(type) ((type)0 - 1 > 0) Will
steve@groucho.ucar.edu (Steve Emmerson) (07/29/90)
In <1990Jul27.161339.14712@kfw.COM> will@kfw.COM (Will Crowder) writes: >What's wrong with: >#define IsUnsigned(type) ((type)0 - 1 > 0) Unless I'm mistaken, in ANSI C "(char)0" will, on most machines, promote to "signed int" due to the value-preserving rule; consequently, the above expression will always be false on those machines, regardless of the signedness of "char". Steve Emmerson steve@unidata.ucar.edu ...!ncar!unidata!steve
rick@.tetrauk.UUCP (Rick Jones) (07/30/90)
I knew I should have kept out of this! My suggestion [#define IsUnsigned(a) (a >= 0 && ~a > 0)] will spot a compiler with wrong promotion of short types, but I have to admit the macro fails with ANSII promotion, while working with old K&R. Comes of using pretend ANSII compilers, I suppose, and K&R version 2 is _horribly_ ambiguous about "~". Perhaps I finally understand the ANSII promotion rules at last! -- Rick Jones You gotta stand for something Tetra Ltd. Maidenhead, Berks Or you'll fall for anything rick@tetrauk.uucp (...!ukc!tetrauk.uucp!rick) - John Cougar Mellencamp
will@kfw.COM (Will Crowder) (07/30/90)
In article <8118@ncar.ucar.edu> steve@groucho.ucar.edu (Steve Emmerson) writes: >In <1990Jul27.161339.14712@kfw.COM> will@kfw.COM (Will Crowder) writes: > >>What's wrong with: > >>#define IsUnsigned(type) ((type)0 - 1 > 0) > >Unless I'm mistaken, in ANSI C "(char)0" will, on most machines, >promote to "signed int" due to the value-preserving rule; consequently, >the above expression will always be false on those machines, regardless >of the signedness of "char". > >Steve Emmerson steve@unidata.ucar.edu ...!ncar!unidata!steve You're absolutely right, which Karl Heuer also pointed out to me via e-mail. I hate the fact that signedness is not preserved, so I probably blocked it out of my memory due to severe emotional trauma. :) :) :) (In other words, I blew it.) I've tried ((type)(-1) > 0) on Turbo C and Gnu CC v1.36, and it seems to work on both. It does not, however, work on Sun cc. A compile-time switch on Turbo C lets you choose whether you want signed or unsigned chars, which is handy. Side note: can anyone out there give a good explanation as to why chars were *ever* signed in the first place, and why ANSI decided not to require either signed or unsigned chars (leaving it implementation dependent)? Will
karl@haddock.ima.isc.com (Karl Heuer) (07/31/90)
In article <1990Jul30.162449.19240@kfw.COM> will@kfw.com (Will Crowder) writes: >Side note: can anyone out there give a good explanation as to why >chars were *ever* signed in the first place, The pdp11's byte-to-word instruction did sign extension, so it was cheaper to have chars be signed. Since ASCII fits in the intersection of signed and unsigned char, most of the problems were hidden. >and why ANSI decided not to require either signed or unsigned chars (leaving >it implementation dependent)? Because which one is cheaper is an implementation-dependent issue, and, since most programs don't care (because they don't use char objects as arithmetic quantities), there was no reason to impose an undue burden on them. I think the real mistake was in having `char' do triple duty: it's the atomic text object (for which signedness shouldn't even be an askable question; cf. Pascal), the allocation quantum (probably should have been spelled `byte'), and a small integer type (which should be spelled `short short int'). Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
henry@zoo.toronto.edu (Henry Spencer) (08/01/90)
In article <17181@haddock.ima.isc.com> karl@kelp.ima.isc.com (Karl Heuer) writes: >>Side note: can anyone out there give a good explanation as to why >>chars were *ever* signed in the first place, > >The pdp11's byte-to-word instruction did sign extension, so it was cheaper to >have chars be signed... I've heard Dennis express some doubts about this decision in retrospect, but it was a sensible thing to do at the time. The cost penalty for doing unsigned chars on the 11 is fairly high unless you do enough optimization to discover that the expression in question ignores the high bits anyway (e.g. by assigning the value to another char variable). -- The 486 is to a modern CPU as a Jules | Henry Spencer at U of Toronto Zoology Verne reprint is to a modern SF novel. | henry@zoo.toronto.edu utzoo!henry
carroll@m.cs.uiuc.edu (08/01/90)
/* Written 1:22 pm Jul 31, 1990 by henry@zoo.toronto.edu in m.cs.uiuc.edu:comp.lang.c */ In article <17181@haddock.ima.isc.com> karl@kelp.ima.isc.com (Karl Heuer) writes: >>Side note: can anyone out there give a good explanation as to why >>chars were *ever* signed in the first place, >The pdp11's byte-to-word instruction did sign extension, so it was cheaper to >have chars be signed... I've heard Dennis express some doubts about this decision in retrospect, but it was a sensible thing to do at the time. /* End of text from m.cs.uiuc.edu:comp.lang.c */ The problem was that "signed" was a valid type modifier, but "unsigned" wasn't. If chars were (by default) unsigned, they could be made signed, but if they were signed, they couldn't be made unsigned. This means that under K&R(1) C, if the default char type was signed, there was no way to have unsigned chars. IMHO, this is a problem. (Now ANSI-fixed, at least). Alan M. Carroll Barbara/Marilyn in '92 : carroll@cs.uiuc.edu + This time, why not choose the better halves? Epoch Development Team CS Grad / U of Ill @ Urbana ...{ucbvax,pur-ee,convex}!cs.uiuc.edu!carroll
chris@mimsy.umd.edu (Chris Torek) (08/02/90)
In article <621@.tetrauk.UUCP> rick@.tetrauk.UUCP (Rick Jones) writes: >Perhaps I finally understand the ANSII promotion rules at last! Probably not. :-) (Incidentally, `ANSI' has only one `I'; it is `ASCII' that has two.) Actually, the rule is fairly easy to state: `In ANSI C, when an unsigned type is promoted% to some other type, it becomes signed (without changing value) if and only if the new type is actually bigger.' In practise, this means that you have to know whether sizeof(short) < sizeof(int) and whether sizeof(char) < sizeof(int). Alternatively, never let values promote without using a cast to a non-promoting type; this avoids the problem entirely. ----- % `Promotion' is not the same as `conversion' or `assignment'. See the standard (X3.159-1989) for an exact description. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris
carroll@m.cs.uiuc.edu (08/06/90)
/* Written 12:07 pm Aug 2, 1990 by henry@zoo.toronto.edu in m.cs.uiuc.edu:comp.lang.c */ In article <4700058@m.cs.uiuc.edu> carroll@m.cs.uiuc.edu writes: >The problem was that "signed" was a valid type modifier, but "unsigned" wasn't. >If chars were (by default) unsigned, they could be made signed... Um, excuse me? /* End of text from m.cs.uiuc.edu:comp.lang.c */ Woops. Change "signed" <-> "unsigned". Got to get some more sleep.
peter@ficc.ferranti.com (Peter da Silva) (08/07/90)
In article <25836@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes: > Actually, the rule is fairly easy to state: `In ANSI C, when an > unsigned type is promoted% to some other type, it becomes signed > (without changing value) if and only if the new type is actually > bigger.' In practise, this means that you have to know whether > sizeof(short) < sizeof(int) and whether sizeof(char) < sizeof(int). What is the rationale for this? There's probably a good reason, but at first glance it seems counterintuitive. -- Peter da Silva. `-_-' +1 713 274 5180. 'U` <peter@ficc.ferranti.com>
ramsey@NCoast.ORG (Cedric Ramsey) (08/07/90)
In article <4700059@m.cs.uiuc.edu> carroll@m.cs.uiuc.edu writes: > >/* Written 12:07 pm Aug 2, 1990 by henry@zoo.toronto.edu in m.cs.uiuc.edu:comp.lang.c */ >In article <4700058@m.cs.uiuc.edu> carroll@m.cs.uiuc.edu writes: >>The problem was that "signed" was a valid type modifier, but "unsigned" wasn't. >>If chars were (by default) unsigned, they could be made signed... > >Um, excuse me? >/* End of text from m.cs.uiuc.edu:comp.lang.c */ >Woops. Change "signed" <-> "unsigned". Got to get some more sleep. Hello, I would like to throw in my two cents here, for what it's worth. I though that chars were signed or unsigned for when used in expressions they will be promoted to integer or unsigned as declared. Otherwise, who cares. a char will be a char no matter what it's sign is. It will have the same number of bits, which is the real problem; some chars are 8 bit others are 7 some are 9, but thats another story. Anyway, that all that I have to say. As to the question, I don't know, I wasn't there. But if I didn't understand the question I would have asked for clarification. Afterall, how can a programmer try to program a task without an understanding of what is to be done. That is from my perspective but then again I wasn't there and don't know any of the underlying circumstances.
rjc@uk.ac.ed.cstr (Richard Caley) (08/25/90)
How about... #define IsUnsigned(n) ((n-n-1) > 0 ) -- rjc@uk.ac.ed.cstr