Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++
Dear all,
 
I think it is simple program. But I really face problem and tired out of finding solution. So, I really need your help.
 
Here is the problem.
I saved 7E FF FF FF FF FF FF 7E (8 bytes) data in binary file.
I would like to retrieve it as reverse order with binary file.
 
The following is output function.
void outputint64(int i) {
	__int64 app1 = (__int64)mem[i+3] << 48; //mem is short type array data read from binary file
	__int64 app2 = (__int64)mem[i+2] << 32;
	__int64 app3 = (__int64)mem[i+1] << 16;
	__int64 app4 = (__int64)mem[i];
	__int64 app = (__int64)app1 | (__int64)app2 | (__int64)app3 | (__int64)app4;
	printf("int64 value is : %I64x", app);
}
 
app1 output is 0x 7E FF 00 00 00 00 00 00 //the output is as I expect
app2 output is 0x FF FF FF FF 00 00 00 00 //actually I only expect 0x 00 00 FF FF 00 00 00 00
app3 output is 0x FF FF FF FF FF FF 00 00 //actually I only expect 0x 00 00 00 00 FF FF 00 00
app4 output is 0x FF FF FF FF FF FF FF 7E //actually I only expect 0x 00 00 00 00 00 00 FF 7E
 
So, app output becomes 0x FF FF FF FF FF FF FF 7E, even though I expect as 0x 7E FF FF FF FF FF FF 7E.
 
How should I modify to get the expected result?
If you have any idea, please help me.
 
Thanks in advance.
Posted 10-Oct-12 5:49am
Edited 10-Oct-12 6:07am
DaveAuld171.7K
v4
Comments
enhzflep at 10-Oct-12 12:07pm
   
What's stored in 'mem[]'?
Could you provide a small, but complete sample program?
 
EDIT: Never-mind - just read the comment. :oops:
April2004 at 10-Oct-12 12:11pm
   
Hi,
Here is my simple source code. I just cut out the points of my current problem.Thanks for your help.
 
#include <stdio.h>
#include <conio.h>
#include <string.h>
 
void outputshort(int i);
void outputint64(int i);
 
short mem[100];
 
void main(){
FILE* fp = 0;
 
short x[100];
 
char *filename = "C:\\chk\\test.dat";
fp = fopen(filename, "wb");
if (fp) {
for (int j = 0; j < 10; j++){
x[j] = (short)j;
fwrite(&x[j], 1, sizeof(x[j]), fp);
}
__int64 val = 9151314442816847742; //7E FF FF FF FF FF FF 7E
fwrite(&val, 1, sizeof(val), fp);
for (int j = 10; j < 20; j++){
x[j] = (short)j;
fwrite(&x[j], 1, sizeof(x[j]), fp);
}
__int64 val1 = 9114441220867751806; //7E 7C FF FF FF FF FF 7E
fwrite(&val1, 1, sizeof(val1), fp);
}

fclose(fp);
 
FILE* fr = fopen(filename, "r");
if (fr) {
fread(&mem, sizeof(mem), 1, fr);
}
 
outputshort(9);
outputint64(10);
 
_getch();
}
 
void outputshort(int i) {
printf("short value is : %d\n", mem[i]);
}
 
void outputint64(int i) {
__int64 app1 = (__int64)mem[i+3] << 48;
__int64 app2 = (__int64)mem[i+2] << 32;
__int64 app3 = (__int64)mem[i+1] << 16;
__int64 app4 = (__int64)mem[i];
__int64 app = (__int64)app1 | (__int64)app2 | (__int64)app3 | (__int64)app4;
printf("int64 value is : %I64x", app);
}
 
Best Regards
Jochen Arndt at 10-Oct-12 12:21pm
   
If you use Visual C++, you can use the _byteswap_uint64() function.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

I think you'll find that the problem is one of sign-extension, that is to say - if you've only declared mem to be an array of 4 shorts, they are SIGNEDshorts. App1 works ok because the first short is 0x7E - or 0111 1110
 
The others fail, because they all begin with a 1 bit in the MSB (most significant bit) This means they are interpreted as signed (-ve, in fact), so to maintain that negativity when they are multiplied 0 which is what a left shift is, they have 1 bits inserted (in the more significat bits), rather than 0 bits - which are still added in the least significant bits.
 
To fix, declare mem as an array of UNsigned shorts. (This behaviour doesn't happen in ASM - it's the C compiler does it for (to?) you)
 
The following code produces the output:
 
int64 value is : 7effffffffffff7e
 

#include <stdio.h>
#include <stdlib.h>

unsigned short mem[4];
 
void outputint64(__int64 i)
{
    __int64 app1 = (__int64)mem[i+3] << 48; //mem is short type array data read from binary file
    __int64 app2 = (__int64)mem[i+2] << 32;
    __int64 app3 = (__int64)mem[i+1] << 16;
    __int64 app4 = (__int64)mem[i];
    __int64 app = (__int64)app1 | (__int64)app2 | (__int64)app3 | (__int64)app4;
    printf("int64 value is : %I64x", app);
}
 
int main()
{
    FILE *fp;
    fp = fopen("inputData.bin", "rb");
    fread(mem, 2, 4, fp);
    fclose(fp);
    int offset = 0;
 
    outputint64(offset);
}
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

short is a signed type. So, when you cast from short to __int64, it fills the additional bytes according to the sign bit. In your case it's 1 (when the value of the high byte is FF). So the additional bytes are filled with FF's.

You can fix that issue, by adding an additional & operation for each << operation. Something like:

__int64 app3 = ((__int64)mem[i+1] & (__int64)0xffff) << 16;

Or, by adding an additional cast to unsigned short. Something like:

__int64 app3 = (__int64)(unsigned short)mem[i+1] << 16;

By the way, you can set the value for the app variable (in the outputint64 function), in one line only:

__int64 app = *((__int64*)&mem[i]);
Smile | :)
  Permalink  
v6
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

Dear enhzflep, Jochen Arndt and Shmuel Zang,
 
Thank you very much for your advice.
Because of your help, I can finish my job.
I used unsigned short as you said. The work is done well.
 
I will also practice _byteswap_uint64(), *((__int64*)&mem[i] for improving my programming knowledge.
 
Thanks a lot for your helps
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 6,649
1 Sergey Alexandrovich Kryukov 6,270
2 CPallini 5,190
3 George Jonsson 3,574
4 Gihan Liyanage 2,522


Advertise | Privacy | Mobile
Web01 | 2.8.140916.1 | Last Updated 11 Oct 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100