I'm trying to create a hash function which stores hexadecimals but I'm not to sure what the hash function to be. I get the addresses which are hexadecimals from a text file and then convert them into unsigned long long int. I'm trying to create a hash table of size 1000, so what exactly do I get when I divide these long long ints? I don't exactly understand this.
The input file contains lines like this:
0x7f1a91026b00
0x7f1a91026b03
0x7f1a91027130
0x7f1a91027131
0x7f1a91027134
0x7f1a91027136
Here's my code so far (I have not created the hash table at the moment since I don't have the hash function)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char **argv){
if(argc!=2){
printf("error\n");
return 0;
// if there is no input then print an error
}
FILE *file = fopen(argv[1], "r"); // open file
if (!file){
printf("error\n");
return 0;
}
char linestring[BUFSIZ];
while (fgets(linestring, sizeof(linestring), file)) // reads the entire file until it hits Null
{
char *endptr;
unsigned long long key = strtoull(linestring, &endptr, 16);
printf("%s\n", linestring);
}
fclose(file);
}
Hexadecimal, Decimal and Octal are simply 3 different ways of printing to the screen the same number.
Let's look at the number 100. We could print it in decimal as 100. Similarly, we could print it in octal as 0144. And we could print it in hexadecimal as 0x64.
But all three of those represent the same number. So the result of 100 / 3, 0144 / 3, and 0x64 / 3 are all identical.
Onto your real question...
You have a number x. You'd like to restrict x to be a number between [0, 0x1000). The easiest way to do that is to do:
unsigned long long x;
unsigned long long y = x % 0x1000;
Now y will be within the range of [0, 0x1000). This is basically accomplished by subtracting 0x1000 from x until it is less than 0x1000.
So if you want hash table size of 1000 then you need to get the modulo of 0x3E8 so for example 0x7f1a91026b00 % 0x3e8 = 0x20. This represent the 32 in dec.
Hex 0x3e8 = Dec 1000.
Related
My program is meant to convert decimal to binary by reading values from an input file and then outputting the binary values into an output file. Lets say the input file has these numbers:
190 31 5 891717742
Everything converts to binary just fine except for the 891717742. This outputs a value which is completely off of the binary output. Ive tried a LONG but they just output a negative value. For example this would output:
11000100 11110010 11 "1434923237" <- not right (not the actual binary values)
Decimal to Binary (from online):
char* convertDecimalToBinary(int n)
{
int binaryNumber = 0;
int remainder, i = 1;
static char buff[100];
while (n!=0)
{
remainder = n%2;
n /= 2;
binaryNumber += remainder*i;
i *= 10;
}
sprintf(buff, "%d", binaryNumber );
return buff;
}
The fundamental problem is that you're trying to use an int to store your binary representation. An int is just that, an integer. In memory it's represented in binary, but the C syntax allows you to use base 10 and base 16 literals when assigning or doing other operations on ints. This might make it seem like it's not being treated as a binary number, but it really is. In your program you are confusing the base 2 representation and the base 10 representation. 891717742 (base 10) converted to binary is 110101001001101000100001101110. What your algorithm is essentially trying to do is store the base 10 number 110101001001101000100001101110 in an int. That base 10 number is larger than even a 64 bit number, it would actually would take 97 bits to store.
Check it this answer to see how you can print out the binary representation of an int in C: Is there a printf converter to print in binary format?
It is pretty much easy, can be done in two easy steps.
Int to hex string
int main()
{
int n=891717742;
char buff[100];
sprintf(buff, "%x", n);
printf("\n buff=%s", buff);
return 0;
}
Hex to binary
Please look at this
How to convert a hexadecimal string to a binary string in C
I have given a number, for example n = 10, and I want to calculate its length in hex with big endian and save it in a 8 byte char pointer. In this example I would like to get the following string:
"\x00\x00\x00\x00\x00\x00\x00\x50".
How do I do that automatically in C with for example sprintf?
I am not even able to get "\x50" in a char pointer:
char tmp[1];
sprintf(tmp, "\x%x", 50); // version 1
sprintf(tmp, "\\x%x", 50); // version 2
Version 1 and 2 don't work.
I have given a number, for example n = 10, and I want to calculate its length in hex
Repeatedly divide by 16 to find the number of hexadecimal digits. A do ... while insures the result is 1 when n==0.
int hex_length = 0;
do {
hex_length++;
} while (number /= 16);
save it in a 8 byte char pointer.
C cannot force your system to use 8-byte pointer. So if you system uses 4 byte char pointer, we are out of luck. Let us assume OP's system uses 8-byte pointer. Yet integers may be assigned to pointers. This may or may not result in valid pointer.
assert(sizeof (char*) == 8);
char *char_pointer = n;
printf("%p\n", (void *) char_pointer);
In this example I would like to get the following string: "\x00\x00\x00\x00\x00\x00\x00\x50".
In C, a string includes the various characters up to an including a null character. "\x00\x00\x00\x00\x00\x00\x00\x50" is not a valid C string, yet is a valid string literal. Code cannot construct string literals at run time, that is a part of source code. Further the relationship between n==10 and "\x00...\x00\x50" is unclear. Instead perhaps the goal is to store n into a 8-byte array (big endian).
char buf[8];
for (int i=8; i>=0; i--) {
buf[i] = (char) n;
n /= 256;
}
OP's code certainly will fail as it attempts to store a string which is too small. Further "\x%x" is not valid code as \x begins an invalid escape sequence.
char tmp[1];
sprintf(tmp, "\x%x", 50); // version 1
Just do:
int i;
...
int length = round(ceil(log(i) / log(16)));
This will give you (in length) the number of hexadecimal digits needed to represent i (without 0x of course).
log(i) / log(base) is the log-base of i. The log16 of i gives you the exponent.
To make clear what we're doing here: When rising 16 to the power of the found exponent, we get back i: 16^log16(i) = i.
By rounding up this exponent using ceil(), you get the number of digits.
Say I have a 32 bit long array of 32 binary digits and I want to output that in Hex form. How would I do that? this is what I have right now but it is too long and I don't know how to compare the 4 binary digits to the corresponding hex number
This is what I have right now where I break up the 32 bit number into 4 bit binary and try to find the matching number in binaryDigits
char hexChars[16] ={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
char * binaryDigits[16] = {"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
int binaryNum[32]= {'0','0','1','0','0','0','0','1','0','0','0','0','1','0','0','1','0','0','0','0','0','0','0','0','0','0','0','0','1','0','1','0'};
int currentBlock, hexDigit;
int a=0, b=1, i=0;
while (a<32)
{
for(a=i+3;a>=i;a--)
{
current=binaryNum[a];
temp=current*b;
currentBlock=currentBlock+temp;
b*=10;
}
i=a;
while(match==0)
{
if(currentBlock != binaryDigits[y])
y++;
else
{
match=1;
hexDigit=binaryDigits[y];
y=0;
printf("%d",hexDigit);
}
}
}
printf("\n%d",currentBlock);
I apologize if this isn't the crux of your issue, but you say
I have a 32 bit long array of 32 binary digits
However, int binaryNum[32] is a 32-integer long array (4 bytes per int, 8 bits per byte = 4 * 8 * 32 which is (1024 bits)). That is what is making things unclear.
Further, you are assigning the ASCII character values '0' (which is 0x30 hex or 48 decimal) and '1' (0x31, 49) to each location in binaryNum. You can do it, and do the gymnastics to compare each value to actually form a
32 bit long array of 32 binary digits
but if that is what you have, why not just write it that way? (as a binary constant). That will give you your 32-bit binary value. For example:
#include <stdio.h>
int main (void) {
unsigned binaryNum = 0b00100001000010010000000000001010;
printf ("\n binaryNum : 0x%8x (%u decimal)\n\n", binaryNum, binaryNum);
return 0;
}
Output
$ ./bin/binum32
binaryNum : 0x2109000a (554237962 decimal)
If this is not where your difficulty lies, please explain further, or again, just what you are trying to accomplish.
So I'm a bit of a newbie to C and I am curious to figure out why I am getting this unusual behavior.
I am reading a file 16 bits at a time and just printing them out as follows.
#include <stdio.h>
#define endian(hex) (((hex & 0x00ff) << 8) + ((hex & 0xff00) >> 8))
int main(int argc, char *argv[])
{
const int SIZE = 2;
const int NMEMB = 1;
FILE *ifp; //input file pointe
FILE *ofp; // output file pointer
int i;
short hex;
for (i = 2; i < argc; i++)
{
// Reads the header and stores the bits
ifp = fopen(argv[i], "r");
if (!ifp) return 1;
while (fread(&hex, SIZE, NMEMB, ifp))
{
printf("\n%x", hex);
printf("\n%x", endian(hex)); // this prints what I expect
printf("\n%x", hex);
hex = endian(hex);
printf("\n%x", hex);
}
}
}
The results look something like this:
ffffdeca
cade // expected
ffffdeca
ffffcade
0
0 // expected
0
0
600
6 // expected
600
6
Can anyone explain to me why the last line in each block doesn't print the same value as the second?
The placeholder %x in the format string interprets the corresponding parameter as unsigned int.
To print the parameter as short, add a length modifier h to the placeholder:
printf("%hx", hex);
http://en.wikipedia.org/wiki/Printf_format_string#Format_placeholders
This is due to integer type-promotion.
Your shorts are being implicitly promoted to int. (which is 32-bits here) So these are sign-extension promotions in this case.
Therefore, your printf() is printing out the hexadecimal digits of the full 32-bit int.
When your short value is negative, the sign-extension will fill the top 16 bits with ones, thus you get ffffcade rather than cade.
The reason why this line:
printf("\n%x", endian(hex));
seems to work is because your macro is implicitly getting rid of the upper 16-bits.
You have implicitly declared hex as a signed value (to make it unsigned write unsigned short hex) so that any value over 0x8FFF is considered to be negative. When printf displays it as a 32-bit int value it is sign-extended with ones, causing the leading Fs. When you print the return value of endian before truncating it by assigning it to hex the full 32 bits are available and printed correctly.
I need to convert a 20digits decimal to binary using C programming. What buffer will I create, because it will be very large, even the calculator can't compute converting 20 digits to Binary.
here is sample of what i intend to accomplish:
Let is assume this code:
I am type this value via my keyboard into the buffer. Meanwhile, I am using an AT85C55WD Mcu.
unsigned char idata token[20]=(2,3,5,6,3,3,4,4,3,2,4,4,6,7,4,3,4,5,3,3);
I want a result
type-define variable convrt_token= 23562244324467434533;
Is this possible using C? If it is, then please how do i go about it?
each digit in decimal has 10 values, 0..9. so you'll need between 3 and 4 digits in binary. so let's say 4 to keep it simple.
so for a 20 digit decimal you'll need an 80 digit number in binary.
you can do it all with chars to keep it simple as well. i assume this is for fun.
char decnum[20];
char binnum[80];
good luck.
Here is elegent solution....:)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<unistd.h>
#include<assert.h>
#include<stdbool.h>
#define max 10000
#define RLC(num,pos) ((num << pos)|(num >> (32 - pos)))
#define RRC(num,pos) ((num >> pos)|(num << (32 - pos)))
void tobinstr(int value, int bitsCount, char* output)
{
int i;
output[bitsCount] = '\0';
for (i = bitsCount - 1; i >= 0; --i, value >>= 1)
{
output[i] = (value & 1) + '0';
}
}
int main()
{
char s[50];
tobinstr(65536,32, s);
printf("%s\n", s);
return 0;
}
Start off as Gidon mentions. Then you only need to define a function 'decToBin' or something like that, which you can use like this:
char decnum[20];
char binnum[80];
// ... get the values, do zero initialization etc...
decToBin( decnum, binnum );
And you're ready to go.
The decToBin function could easily be implemented as a common long division algorithm. That shouldn't be too hard.
Have fun ;)
EDIT: Detailed description:
Look at your last digit. Is it divisible by 2?
--> yes: your binary digit will be 0
--> no: your binary digit will be 1
Divide the entire decimal number by 2 (Long division preferrably) and truncate if necessary.
start over. You will get the binary digits in reverse order. (Repeat until your decimal number is 0)