473,406 Members | 2,745 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,406 software developers and data experts.

bytes: shifting doubles?


hi

i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?

i.e. individually copying bytes into a long array:
--------------------------------
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;

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

Nov 15 '05 #1
25 7791
Allan Rydberg wrote:
hi

i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?

i.e. individually copying bytes into a long array:
--------------------------------
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;


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++.

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

Nov 15 '05 #2
Allan Rydberg wrote:
hi

i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?

i.e. individually copying bytes into a long array:
--------------------------------
int pointer;
char databuffer[100];

double uint64;


double is floating point type, not integral type
shifting with these operators is allowed on integral types only
(you may want to look for a 64 bit integral type on your platform)

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

Nov 15 '05 #3
Allan Rydberg <al****@southtech.net> writes:
int pointer;
char databuffer[100];

double uint64;
unsigned long uint32;


double is a floating point type.

--
Philippe Amarenco, aka Phix
epita 2007 - LSE - EpX
"if new true friend not protected for explicit private union, break
case and try using this." -- Nathan Myers, longest c++ sentence.

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

Nov 15 '05 #4

Allan Rydberg wrote:
hi

i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?

Longs (and chars and shorts) are all integers. Doubles are floats, and
you cannot apply the shift operators to them. Just multiply or divide
by the appropriate power of two instead - instead of "a<<6" do "a*64".
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Nov 15 '05 #5

Allan Rydberg wrote:
hi

i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?

i.e. individually copying bytes into a long array:
--------------------------------
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;


A double is a double float. It is not an integer type, so it cannot be
bit shifted. (It can be divided by a power of 2, of course, but
presumably the bit patterns and not the values stored in dataBuffer are
of interest here).

A long long is an integer type and can be bit shifted.

So I recommend declaring uint64 like this:

typedef unsigned long long uint64;

for the code to compile as written. I would also recommend renaming
"pointer" since it is not a pointer, but an index.

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

Nov 15 '05 #6
Allan Rydberg wrote:
i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?
actually the phrase is "...shift operators ... operands shall be
of integral or enumeration type". unsigned long is integral,
double is. You can't do this.
i.e. individually copying bytes into a long array:
--------------------------------
int pointer;
char databuffer[100]; unsigned char databuffer[100];
double uint64;
unsigned long uint32;

pointer =0;
well you could try this:

unsigned char *p;
p = (unsigned char*)&uint64; /* that's an odd name for a double...
*/
for (i = 0; i < sizeof(double); i++)
databuffer [i] = *p++;

this trick of copying one type to another via a cast pointer only
works for unsigned char. Anything else yields undefined behaviour.
Also note that different implementations may represent doubles
differently and hence the above code won't put the same thing in
databuffer.
// this works:
uint32 = 1111111; // anything
databuffer[pointer++] = uint32 >> 24;
databuffer[pointer++] = uint32 >> 16;
databuffer[pointer++] = uint32 >> 8;
databuffer[pointer++] = uint32 >> 0; // jup, i know..!
Undefined Behaviour
// 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;

--
Nick Keighley

"There are 10 types of people in this world.
Those that understand Binary, and those that don't".
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Nov 15 '05 #7
A simple way to do that is to use a union and put both your double and
a char pointer variable or a char array of size double. Thats it. write
data in double and read the value from double but when to stream data
in and out of the char buffer get the data from char poiinter.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Nov 15 '05 #8
Rob
Allan Rydberg wrote:

hi

i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?
You've answered your own question. The basic >> and << operators are
only defined to work with integral types.


i.e. individually copying bytes into a long array:
--------------------------------
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;


If you want access to the bits in the double you might try doing a bit
of wizardry with casting of pointers;

unsigned long long *address; // double is (typically) longer than a
long

address = (unsigned long long)(&uint64);

databuffer[pointer++] = (*address) >> 56;

That will give you access to the bits that (internally) make up the
double variable.

The value of doing this is .... questionable. You might try
specifying what you're *really* trying to achieve by doing this: there
is almost certainly a better way to do it.

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

Nov 15 '05 #9
Allan Rydberg wrote:
i'm trying to shift a double, but i'm getting the error
message '>>' illegal, left operand double. althought that the manpages say, '>>' and '<<' can be applied
for int's only, i was able to use the shift operator on
unsigned longs without any problems.
The operators are defined for all integral types, not just int.
But becareful with >> on a signed integral type; I tend to only
use it with unsigned types, just to be on the safe side.
does anyone know how to do this properly? i.e. individually copying bytes into a long array:
--------------------------------
int pointer;
char databuffer[100]; double uint64;
Now that's a confusing name.
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;


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.

--
James Kanze mailto: ja*********@free.fr
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! ]

Nov 15 '05 #10
Allan Rydberg <al****@southtech.net> writes:
i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.
What would you expect as a result of shifting a double?

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?
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.

i.e. individually copying bytes into a long array:
--------------------------------
int pointer;
char databuffer[100];

double uint64;
A very misleading variable name ...

unsigned long uint32;
.... and a platform-dependant variable name.

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;


Again: what should the result of evaluating the expression

uint64 >> 56

be?

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

Nov 15 '05 #11
On 17 Sep 2005 10:00:36 -0400, Allan Rydberg <al****@southtech.net>
wrote in comp.lang.c:

hi

i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.
Why do you think you want to shift a double?
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.
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?
How to shift a double properly? No, because it makes no sense either
mathematically or in terms of C or C++. What are you really trying to
do?
i.e. individually copying bytes into a long array:
Actually, the code in your snippet below attempts to copy bytes into
an array of char. Unsigned char would be a better choice.
--------------------------------
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));

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html

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

Nov 15 '05 #12
"Allan Rydberg" <al****@southtech.net> wrote in message
news:dg**********@news.hispeed.ch...

hi

i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?

i.e. individually copying bytes into a long array:
--------------------------------
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;

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;"
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Nov 15 '05 #13
Allan Rydberg schrieb:
hi

i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?

i.e. individually copying bytes into a long array:
--------------------------------
int pointer;
char databuffer[100];

double uint64;
unsigned long uint32;
<snip> // this won't:
uint64 = 1111111; // anything
databuffer[pointer++] = uint64 >> 56;


it does not work since bit-shifts are defined for integer-constants
only, not for floating-point numbers.

these have a defined structure, defined as an ieee-standard (don't know
which one though), shifting it might destroy this structure. only way is
to cast to integer-type of the same size (float->integer, both size
4-byte on x86 ), and shift this one.

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

Nov 15 '05 #14
Allan Rydberg <al****@southtech.net> writes:
i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?
The "<<" and ">>" operators can be applied to any integer type (the
left operand should usually be unsigned).

They cannot be applied to any floating-point type, including double.
i.e. individually copying bytes into a long array:
--------------------------------
int pointer;
char databuffer[100];

double uint64;
unsigned long uint32;

pointer =0;
Your variable names are misleading. The name "pointer" implies that
it's a pointer; "index" would be clearer. "uint64" and "uint32" look
like type names rather than variable names. And finally, "uint64" is
misleading for a variable of type double, which is not an integer
type.
// this works:
uint32 = 1111111; // anything
databuffer[pointer++] = uint32 >> 24;
databuffer[pointer++] = uint32 >> 16;
databuffer[pointer++] = uint32 >> 8;
databuffer[pointer++] = uint32 >> 0; // jup, i know..!
Ok.
// 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;


What are you trying to accomplish?

--
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.

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

Nov 15 '05 #15
"Allan Rydberg" <al****@southtech.net> wrote in message
news:dg**********@news.hispeed.ch...
i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.


Either you misread the manpages or they're misleading.
The shift operators work with integer values, not just ints (chars, shorts
and longs (including long longs) are OK too).

But floats, doubles and long doubles can't be shifted with << and >>...
Well, they can be "shifted" out to the stdout in C++, but C++ isn't C ;)
With the floating point types you have to use * and / to multiply and divide
by 2.

HTH,
Alex

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

Nov 15 '05 #16
Allan Rydberg wrote:
althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
They mean "integral types" of which u.long is one.
You can't shift floating point types.
does anyone know how to do this properly?


Does your compiler provide a real 64-bit int type?
Many do. If so use that. Using double just because
it has the right size (and it may not) is wrong.
Otherwise create your own uint64.

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

Nov 15 '05 #17
On 17 Sep 2005 10:00:36 -0400, Allan Rydberg <al****@southtech.net>
wrote:

hi

i'm trying to shift a double, but i'm getting the
error message '>>' illegal, left operand double.
What do you expect the result to represent? The odds on it being a
valid double are pretty remote.

althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?
Your man page should have said the shift operators can be used on
integers, not int's. unsigned long is an integer type.

i.e. individually copying bytes into a long array:
--------------------------------
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..!
Since databuffer is not unsigned, you have invoked undefined (or maybe
its only implementation defined) behavior several times.

// 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;


Why not make life easy on yourself.

unsigned char uchar[sizeof(double)];
double dbl = 1111111;
memcpy(uchar,&dbl,sizeof dbl);
<<Remove the del for email>>

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

Nov 15 '05 #18
Allan Rydberg wrote:
althought that the manpages say, '>>' and '<<' can
be applied for int's only, i was able to use the
shift operator on unsigned longs without any problems.
does anyone know how to do this properly?

That is because an 'unsigned long' is an integer: an 'unsigned' and
'long' integer. You are using 'unsigned long' which is just short-hand
for 'unsigned long int' (C and C++ allow you to leave the 'int' part
out). The 'long' applied to an 'int' or 'unsigned' just says that its
size is at least as big as an the corresponding 'int' or 'unsigned
int'. So, 'sizoef(int) <= sizeof(long int) and sizeof(unsigned int) <=
sizeof(unsigned long int).' If 'long' actually makes the integer type
bigger is implementation defined.

"double", however, along with "float" and "long double" are floating
point types. C and C++ disallow shift operations (and all other bit
manipulation operations, for that matter) with floating point types.

If you actually need a 64-bit integer many compilers offer a language
extension for representing them. For instance, MSVC++ offers '__int64'
for x86 and g++ offers 'long long int' for x86.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Nov 15 '05 #19
Jack Klein <ja*******@spamcop.net> writes:
On 17 Sep 2005 10:00:36 -0400, Allan Rydberg <al****@southtech.net>
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. Since this is cross-posted to
comp.lang.c++.moderated (not a good idea), I'll mention that long long
and unsigned long long are new in C99. Many pre-C99 compilers, and
probably many C++ compilers, provide it as an extension.

--
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.

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

Nov 15 '05 #20
Johncarp <jo******@wp.pl> writes:
[...]
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) 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.

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

Nov 15 '05 #21
"Keyser Soze" <no******@nothere.com> writes:
"Allan Rydberg" <al****@southtech.net> wrote in message
news:dg**********@news.hispeed.ch... [...]
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) 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.

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

Nov 15 '05 #22
James Kanze wrote:
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: ja*********@free.fr
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! ]

Nov 15 '05 #23
Jack Klein wrote:
On 17 Sep 2005 10:00:36 -0400, Allan Rydberg
<al****@southtech.net> 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: ja*********@free.fr
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! ]

Nov 15 '05 #24
Keith Thompson wrote:
Jack Klein <ja*******@spamcop.net> writes:
On 17 Sep 2005 10:00:36 -0400, Allan Rydberg <al****@southtech.net>
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! ]

Nov 15 '05 #25
Thomas Maeder wrote:


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?

--
imalone
Nov 15 '05 #26

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

Similar topics

10
by: Kristian Nybo | last post by:
Hi, I'm writing a simple image file exporter as part of a school project. To implement my image format of choice I need to work with big-endian bytes, where 'byte' of course means '8 bits', not...
25
by: TK | last post by:
I'm used to programming in c or c++ in which my problem is simple. I want to be able to enter a value on a page (like 3.2), and then read it as a 32-bit float and break it into it's individual...
19
by: James Harris | last post by:
My K&R 2nd ed has in the Reference Manual appendix, A7.4.8 sizeof yields the number of BYTES required to store an object of the type of its operand. What happens if C is running on a machine that...
3
by: Dan | last post by:
Is there a way to place x number of bytes directly into a structure? Specifically with this structure: Private Structure HeaderVersion1 Dim intVersion As Int16 Dim intCount As Int16 Dim...
6
by: lovecreatesbeauty | last post by:
/* It seems that when an int with width of four bytes is assigned to a one byte width char, the first three bytes from left to right are discarded and the rightest byte is assigned to that char....
4
by: Lee Crabtree | last post by:
I need to shift all of the values in a byte array by more than 8 bits, meaning that values should flow from one byte to another. Since I don't know in advance how many bits will be shifting, I...
34
by: john | last post by:
If I have a 32 bit unsigned int that is in the wrong byte order, how can I convert it? For example, if have a number 0x090a0b0c how can I reverse this to 0x0c0b0a09 ? Thanks, -John
9
by: Noel Milton | last post by:
Hi: Ok, I've just read in up to 65,535 bytes into a char array (using the recvfrom socket API call). So I have an array of 8 bit char's (char recvString;). Now, four (4) consecutive bytes...
49
by: seema | last post by:
Hi all, How to calculate upper 4 bytes and lower 4 bytes of a value? Can somebody please explain?? say for example, unsigned int scnlen_lo; int scnlen_hi; unsigned long long scnlen; ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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...
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.