Re: [Dev-C++] Some extra bytes written to file?
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
|
From: <qa...@ho...> - 2003-03-06 23:00:10
|
See comments...
*********** REPLY SEPARATOR ***********
On 2003-03-06 at 23:42 Ioannis Vranos wrote:
Important correction:
-------Original Message-------
From: Ioannis Vranos
Date: =D0=DD=EC=F0=F4=E7, 6 =CC=DC=F1=F4=E9=EF=F2 2003 11:37:40 =EC=EC
To: Dev-C++ Mailing List
Subject: Re: [Dev-C++] Some extra bytes written to file?
-------Original Message-------
From: "J=F6rgen"
Date: =D0=DD=EC=F0=F4=E7, 6 =CC=DC=F1=F4=E9=EF=F2 2003 5:00:15 =EC=EC
To: dev...@li...
Subject: [Dev-C++] Some extra bytes written to file?
Hi.
This problem puzzles me. I have the following data.
-4 0 0 4 1 0 4 2 0 3 2 27 1 3 108 1 3 135 1 3 189 1 3 351 1 4 0 8 5 0 4 6 0
4 7 0 4 8 0 4 9
0 3 9 27 1 10 27 2 10 36 1 10 54 1 11 108 1 11 189 1
I'm not to familiar with reg.exp, but I guess that the reg.exp. for the=
data
would be
result [value1 value2 value3]*
where
result is an integer but is always in the range -64 to 64
value1 is an integer but is always in the range 0 to 11
value2 is an integer but is always in the range 0 to 65536
value3 is an integer but is always in the range 0 to 4
let's say that we call [value1 value2 value3] for 'value' and 'nbrOfValues'
the number of sets
of 'value'. In this case nbrOfvalues =3D 20
When I write the data to file, using ofstream foo("foofile") I do it in the
following way
=3D=3D> Since it is C++, why don't you use bitset<> elegantly and=
efficiently?
[commment]
Where should I use it? I can't see the purpose for it.
if(result < 0)
foo << '-';
else
foo << '+';
foo << ((unsigned char) (abs(result) & 0x000000FF));
for(int i=3D0; i<numberOfValues; i++){
foo << ((unsigned char) (value[i][0] & 0x000000FF));
foo << ((unsigned char) ((value[i][1] & 0x0000FF00) >> 8));
foo << ((unsigned char) (value[i][1] & 0x000000FF));
foo << ((unsigned char) (value[i][2] & 0x000000FF));
=3D=3D> CORRECTION: Since value2 is [0,65536] use unsigned long. E.g.
for(int i=3D0; i<numberOfValues; i++){
foo << static_cast<unsigned long> (value[i][0]) & 0x000000FF;
foo << static_cast<unsigned long>(value[i][1]) & 0x0000FF00 >> 8;
foo << static_cast<unsigned long> (value[i][1]) & 0x000000FF;
foo << static_cast<unsigned long> (value[i][2]) & 0x000000FF;
=3D=3D>CORRECTION: The casting should be applied "before" the bitwise=
operation.
[comment]
What I'm trying to do is to reduce the size of the written file. Casting to=
unsigned long gives me no reduction in size.
E.g.
4 * char =3D 4 * 8 =3D 32 bits =3D 4 bytes.
4 * unsigned long =3D 4 * 32 =3D 128 bits =3D 32 bytes
}
The problem comes when I read the data from file. If I just reverse the
procedure and prints
the decoded data to screen I get
-4 0 0 4 1 0 4 2 0 3 2 27 1 3 108 1 3 135 1 3 189 1 3 351 1 4 0 8 5 0 4 6 0
4 7 0 4 8 0 4 9 0
3 9 27 1 10 27 2 10 36 1 10 54 1 11 108 1 11 189 1 0 80 114
It looks just the same as the original data except for the last three
numbers (0 80 114).
When looking at the filesize it shows that it is 85 bytes, but the data
written is only 82 bytes
For debugging purposes, instead of writing directly to file, I first store
everything in a
string s. That is, replacing foo << ... with s +=3D ... Finally I write it=
to
file with foo << s;
When I print the string s to screen in hex-mode
cout.setf( ios_base::hex, ios_base::basefield );
for(int i=3D0; i<s.size(); i++)
cout << " " << s[i];
it gives the following output
2d 4 0 0 0 4 1 0 0 4 2 0 0 3 2 0 1b 1 3 0 6c 1 3 0 87 1 3 0 bd 1 3 1 5f 1 4
0 0 8 5 0 0 4 6 0
0 4 7 0 0 4 8 0 0 4 9 0 0 3 9 0 1b 1 a 0 1b 2 a 0 24 1 a 0 36 1 b 0 6c 1 b
0 bd 1
and it is the way it should be
But when I look at the datafile in a hexeditor I see
2d 4 0 0 0 4 1 0 0 4 2 0 0 3 2 0 1b 1 3 0 6c 1 3 0 87 1 3 0 bd 1 3 1 5f 1 4
0 0 8 5 0 0 4 6 0
0 4 7 0 0 4 8 0 0 4 9 0 0 3 9 0 1b 1 d a 0 1b 2 d a 0 24 1 d a 0 36 1 b 0=
6c
1 b 0 bd 1
An extra byte 'd' emerges before every one of the three "value1"-'a' bytes
(d a 0 1b 2 , d a 0 24 1 , d a 0 36 1).
Where did these 'd' bytes come from?
=3D=3D> Truncation. You "bitwise" a signed value (casted to unsigned type)=
and
its bit, marking its signess floats around. Also keep in mind that the
binary representation of negative values is radically different from the
positive ones.
[comment]
First. There are no negative integers (int) in the data so the problem=
shouldn't be happening.
Second. Lets say that the value of the int to be casted is 130. In bits it=
is written
00000000 00000000 00000000 10000010
Then it is masket with
00000000 00000000 00000000 11111111
and the result is
00000000 00000000 00000000 10000010
Now it is casted to unsigned char and we got the following bits
10000010
The value is still 130. If it were a signed char the bitrepresentation=
would still be
10000010
but the value would be -126
Why are the only occuring in front of the 'a' byte?
How come that when I print the data to screen it does not mess up the=
values
but instead
appends (0 80 114) at the end?
=3D=3D> Hmmm.
[comment]
Couldn't agree more
Ioannis Vranos
* Programming pages: http://www.noicys.freeurl.com
* Alternative URL: http://run.to/noicys
|