bytes: shifting doubles?

K

Keith Thompson

Keyser Soze said:
double uint64;
[...]
Just because you name it "uint64" does not make it an integer data type.

The declaration of: "double uint64;" still define a floating point data
type.

If you're using gcc try: "unsigned long long uint64;"

If it's a VC compiler try: "unsigned _int64 uint64;"

unsigned long long is not specific to gcc. It's standard in C99, and
many non-C99 compilers (both C and C++) provide it as an extension.
But the C99 standard says only that long long is *at least* 64 bits;
it can be larger. If you really need a 64-bit unsigned type, use
uint64_t (defined in <stdint.h> in C99), or create your own
system-specific typedef.

But for the OP's problem, this isn't really necessary. Since he's
trying to decompose a double value into bytes, there's not much point
in using an intermediate 64-bit integer. Just transform it to an
array of unsigned char.

That's assume he wants to decompose the *representation* of the double
value; it's not at all clear that that's what he needs to do.

To the original poster: If you want a useful answer, you'll need to
post a followup and clarify the question.

--
Keith Thompson (The_Other_Keith) (e-mail address removed) <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.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
K

Keith Thompson

Johncarp said:
unsigned long is usually the same as unsigned int, so it works. if you
want to shift 64bit value, you can use long long under gcc and __int64
(?) under msvc++.

Types unsigned int and unsigned long are *sometimes* the same size.

Type long long is guaranteed to be at least 64 bits; it can be longer
(though I don't know of any platforms where it is).

Consult your C textbook's section on integer types for more
information.

--
Keith Thompson (The_Other_Keith) (e-mail address removed) <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.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
J

James Kanze

Jack said:
On 17 Sep 2005 10:00:36 -0400, Allan Rydberg
<[email protected]> wrote in comp.lang.c:

[...]
Actually, the code in your snippet below attempts to copy
bytes into an array of char. Unsigned char would be a better
choice.

Actually, it doesn't. It attempts to *format* a double using a
binary format. The problem is much more complicated than it
seems, and something perfectly portable is a lot of work,
involving frexp() etc. (and risking some rounding errors).
--------------------------------
int pointer;
char databuffer[100];
double uint64;
unsigned long uint32;
pointer =0;
// this works:
uint32 = 1111111; // anything
databuffer[pointer++] = uint32 >> 24;
databuffer[pointer++] = uint32 >> 16;
databuffer[pointer++] = uint32 >> 8;
databuffer[pointer++] = uint32 >> 0; // jup, i know..!
// this won't:
uint64 = 1111111; // anything
databuffer[pointer++] = uint64 >> 56;
databuffer[pointer++] = uint64 >> 48;
databuffer[pointer++] = uint64 >> 40;
databuffer[pointer++] = uint64 >> 32;
databuffer[pointer++] = uint64 >> 24;
databuffer[pointer++] = uint64 >> 16;
databuffer[pointer++] = uint64 >> 8;
databuffer[pointer++] = uint64 >> 0;
You could include <string.h> and use memcpy().
memcpy(databuffer, &uint64, sizeof(double));

This only works if the machine has 8 bit bytes (very likely --
but there are exceptions), uses the targetted format internally
(he doesn't say what the targetted format is, but I'd guess
IEEE), and if is big-endian. While the first two conditions are
frequently true (although many mainframe computers don't use
IEEE), endian-ness tends to vary, with PC's being little endian,
but Sparcs and Power PC's big endian.

Until he tells us exactly what he is trying to do, and his
portability requirements, it's difficult to propose a solution
-- anything strictly portable would require an enormous amount
of work, and if it isn't necessary...

--
James Kanze mailto: (e-mail address removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
J

James Kanze

James said:
Allan Rydberg wrote:
I suppose that you are formatting binary data for output. And
that the specification requires IEEE double, high byte first,
and that you accept the fact that your code will not be
portable to a machine which doesn't use IEEE floating point
(IBM or Unisys mainframe, for example). Given that you don't
really have absolute portability anyway, the obvious answer
here is to use a reinterpret_cast, e.g.:
double d = 111111 ;
unsigned int const& ui
= reinterpret_cast< unsigned int const& >( d ) ;
databuffer[ pointer ++ ] = ui >> 56 ;
// ...
If you require absolute portability, so that the code will run
as is even on a Unisys mainframe, you've got your work cut out
for you -- you have to functions like frexp to extract the
necessary information from the floating point format and
create your own IEEE format. But portability to this degree
typically isn't necessary.

And that's what I get for posting too quickly. The above only
works if int has 64 bits, which makes it a bit less portable
than I meant. Obviously, you need some sort of 64 bit unsigned
integral type -- unsigned long long if your compiler supports
it, or __uint64. Otherwise, you'll have to introduce some
additional compiler dependancies, to handle different byte
ordres (at which point, I would output it a byte at a time, and
forgo the shifting).

--
James Kanze mailto: (e-mail address removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
K

kanze

Keith said:
Jack Klein said:
On 17 Sep 2005 10:00:36 -0400, Allan Rydberg <[email protected]>
wrote in comp.lang.c: [...]
althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
Either your man pages are incorrect, or more likely you are
quoting them incorrectly. The bitwise right and left shift
operators may be applied to all of the integer types, of
which int is one. The others are char, short, long, and
long long.
Also signed char, unsigned char, unsigned short, unsigned
long, and unsigned long long.

That's not strictly true. They should apply to the long long
elements, if the compiler supports them, but binary operators on
arithmetic types never apply to types smaller than int --
integral promotion takes place.

Note that integral promotion may convert an unsgined type
(unsigned short, unsigned char) into a signed type, which can
then affect later comparisons, etc.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
I

Ian Malone

Thomas said:
If the man page says that >> and << apply to int only, it's wrong. You
can apply them to objects of integral and enumeration types; that
includes unsigned long, but not double.

Is there a use for the shift operators on an enum, or is
it a result of their relation to integer types?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,460
Latest member
eibafima

Latest Threads

Top