home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!mcsun!fuug!demos!kiae!glas!demos!oracle.us!us.oracle.com!wkaufman
- From: wkaufman@us.oracle.com
- Newsgroups: comp.lang.c
- Date: 18 Jul 92 20:36 MDT
- Subject: Re: unsigned long to long without lossa
- Sender: Notesfile to Usenet Gateway <notes@glas.apc.org>
- Message-ID: <1992Jul18.163616.13897@oracle.us>
- References: <brself.711346221@hal>
- Nf-ID: #R:brself.711346221@hal:-680706142:1992Jul18.163616.13897@oracle.us:-1978910101:001:4816
- Nf-From: us.oracle.com!wkaufman Jul 18 20:36:00 1992
- Lines: 115
-
-
- In article <1992Jul17.201215.19749@wyvern.twuug.com> alpha@wyvern.twuug.com (Joe Wright) writes:
- ] brself@hal.gnu.ai.mit.edu (Ben Self) writes:
- ] :
- ] : Can anyone please tell me a portable (one which does not step on either
- ] : the ANSI or POSIX standards) way to preserve the bit order and precision
- ] : of an unsigned long that has to be crammed into a variable of type long.
-
- If (ulong_val > INT_MAX), there's not much you can do. Someone else
- (name lost) suggested the following code:
-
- if (ulong_val > INT_MAX)
- slong_val = ulong_val - INT_MAX;
-
- First, there may be problems if you're not doing this on a two's
- complement machine (OK, I don't know *what* problems--I'm just
- guessing).
-
- Second, it assumes that negative numbers are acceptable to whatever
- takes a Message type (which may well be true--some info from the
- poster on the Message type and the message codes could help).
-
- And third, I'm not sure this will work, because (long) isn't big
- enough for the left side of the minus sign, and (unsigned long) can't
- take the negative value of the whole, so I don't know if the machine
- could find an suitable intermediate value for the calculation. (If I'm
- wrong, someone will be along in a bit to correct me, in a violent
- manner.)
-
- ] : I know that ANSI treats unsigned long as wider type than long and if
- ] : mixed all values are promoted to unsigned long.
-
- In real life (as opposed to ANSI), some machines will have the same
- top value for both--signed-bit machines, for example. But, for the
- majority of machines you'll use, unsigned will be one bit longer. (I
- almost wrote, "...a bit longer", which isn't quite the same thing.
- Amazing how technical terms can mangle the language.)
-
- ] : I know they both have the same size; surely there must be a way to
- ] : assure there is no loss of information in a portable way.
-
- If Message is your own invention (not buried in some vendor's
- header, for example), and you can't change the numbers, you might want
- to just add a bit to the type, like
-
- if (ulong_val > INT_MAX)
- {
- message.long_val = ulong_val - INT_MAX;
- message.big_number = 1;
- }
- else
- {
- message.long_val = ulong_val;
- message.big_number = 0;
- }
-
- and reconstruct the ulong_val the other way.
-
- If, on the other hand, Message *isn't* your own invention, but the
- message codes *are*, lower the numbers--assuming you're on a 32-bit
- machine, you don't really have two billion messages, right? Or, even if
- you do, you could use negative numbers, right?
-
- If you don't own either the message codes *or* the Message type,
- well,...
-
- ] Most of my posts generate flames from 'knowledgable' readers and
- ] alternatives to any suggestions. So here goes..
-
- I *swear*, this is *not* a flame!
-
- ] Historically, 'unsigned long' has been supported by the language
- ] but not by the implementation.
-
- Actually, if the hardware supports unsigned types, it's likely that
- the compiler will, too. But, yeah, the above may be true for PCs, and
- many of the RISC machines out now,...
-
- ] This has to do with the complexity
- ] (in the implementation) of treating the two differently. Really,
- ] why should we treat 'unsigned long'? Nobody needs an integer bigger
- ] that 2 billion, surely.
-
- ...if you're lucky enough to be on a 32-plus-bit machine. In the
- original poster's case, 2 billion is probably good enough for the number
- of possible messages--who'd even want to type in 2 billion messages?!?
- But for calculating the US national debt, for example, it's not enough.
- (Well, OK, 4 billion isn't large enough either,...)
-
- (As a random anecdote, a friend was working for AT&T during the time
- of The Great Breakup, writing software to figure out what money went
- where. Early on, he wasn't sure whether to display values in millions
- or billions,... When you get that far up there, every bit helps.)
-
- ] If the ANSI standard provides different sizes for 'long int' and
- ] 'unsigned long int' it is news to me. I would guess that all
- ] implementations will have them the same size in any case.
-
- On a two's-complement machine, half the space is taken up with
- negative numbers, right? If you drop those (i.e., if you use a real
- unsigned integer type), you'll increase the top value. On this Sun
- machine, for instance, limits.h lists
-
- #define INT_MAX 0x7FFFFFFF
- #define UINT_MAX 0xFFFFFFFF
-
- This isn't a wackiness of the C implementation, it's a fact of the
- two's-complement integer space.
-
- -- Bill K.
-
- Bill Kaufman, | "...all conscious species are plastic and
- Corporate Lackey | all plastic species are conscious."
- wkaufman@us.oracle.com | -- Yew-Kwang Ng
-
-