I can read unsigned ints from a binary file but one of the values is printing out negative.
Expected values:
45788331,
281302247,
461354227,
13127,
299215653,
2356985123,
Values printed out:
45788331,
281302247,
461354227,
13127,
299215653,
-1932982173,
The 6th value is printing out as negative but I am reading a list of unsigned ints?
My code below
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE * fp;
ssize_t read;
int r = 0;
fp = fopen("numbers.bin", "rb");
if (fp == NULL)
exit(-1);
while(fread(&r, sizeof(unsigned int), 1, fp) == 1)
{
printf("%d\n", r);
}
fclose(fp);
if (line) free(line);
exit(0);
}
printf("%d\n", r); prints out a signed decimal integer.
You want: printf("%u\n", r);
Additionally, r is declared as int not unsigned int.
Type of r is int. The range for the 32 bit int is -2147483648 = -(2^32)/2 through 2147483647 = (2^32)/2 -1 decimal.
2356985123 is outside the range for the signed int. When printing r by printf("%d\n", r); r will be presented as -1937982173.
-1937982173 = 2356985123 - 2^32
Related
I have a simple program in which program receive input from the file and converts decimal to binary and counts number of ones in its binary form?
Now For small values it is okay
and for huge values like 15755645551 , it's obviously not working
anyone has any idea how to resolve this problem?
anyone can try with my code?
thank you!!
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define BUFFER 25
long number_read = 0;
long number_of_ones = 0;
long remainder_value = 0;
long binary = 0;
long base = 0;
long buff[BUFFER];
int main()
{
FILE *fp; //file pointer fp
fp = fopen("File.txt", "r+");
while (fgets(buff, sizeof(buff), fp) != NULL)
{
number_read = atoi(buff); //ASCII to integer
printf("\nnumber is=%d", number_read);
while (number_read > 0)
{
remainder_value = number_read % 2;
/* To count no.of 1s */
if (remainder_value == 1)
{
number_of_ones++;
}
binary = binary + remainder_value * base;
number_read = number_read / 2;
base = base * 10;
}
printf("\nNo.of 1's in It's binary representation is = %d\n", number_of_ones);
number_of_ones = 0;
}
fclose(fp);
return 0;
}
Because "long" type occupies 4 bytes as "int" type. You should change it to "long long" type.
I'm looking the best way to transform a float number to its decimal representation in C. I'll try to give you an example: the user introduces a number in IEEE754 (1 1111111 10101...) and the program has to return the decimal representation (ex. 25.6)
I've tried with masks, and bitwise operations, but I haven't got any logical result.
I believe the following is performing the operation you describe:
I use the int as an intermediate representation because it has the same number of bits as the float (on my machine), and it allowed easy conversion from the binary string.
#include <stdio.h>
union {
int i;
float f;
} myunion;
int binstr2int(char *s)
{
int rc;
for (rc = 0; '\0' != *s; s++) {
if ('1' == *s) {
rc = (rc * 2) + 1;
} else if ('0' == *s) {
rc *= 2;
}
}
return rc;
}
int main(void) {
// the input binary string (4 bytes)
char * input = "11000000110110011001100110011010";
float *output;
// convert to int, sizeof(int) == sizeof(float) == 4
int converted = binstr2int(input);
// strat 1: point memory of float at the int
output = (float*)&converted; // cast to suppress warning
printf("%f\n", *output); // -6.8
// strat 2: use a union to share memory
myunion.i = converted;
printf("%f\n", myunion.f); // -6.8
return 0;
}
As #DanielKamilKozar points out, the correct type for that int is uint32_t. However, that would require including <stdint.h>.
This is from google's code jam, practice problem "All your base".
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
long long pow_longlong(int digit, int raiseto)
{
if (raiseto == 0) return 1;
else return digit * pow_longlong(digit, raiseto - 1);
}
long long base10_with_map(int base, char* instr, char* digits)
{
if (base < 2) base = 2;
long long result = 0;
int len = strlen(instr);
int i = 0;
while (len--)
result += digits[instr[len]] * pow_longlong(base, i++);
return result;
}
long long test(char* in)
{
char appear[256];
int i;
int len = strlen(in);
int hold = 0;
for (i = 0; i < 256; i++) appear[i] = '\xFF';
for (i = 0; i < len; i++)
if (appear[in[i]] == '\xFF')
{
if (hold == 0) { appear[in[i]] = 1; hold++; }
else if (hold == 1) { appear[in[i]] = 0; hold++; }
else appear[in[i]] = hold++;
}
return base10_with_map(hold, in, appear);
}
int main(int argc, char* argv[])
{
if (argc < 2)
{
printf("Usage: %s <input-file> \n", argv[0]); return 1;
}
char buf[100];
int a, i;
FILE* f = fopen(argv[1], "r");
fscanf(f, "%d", &a);
long long result;
for (i = 1; i <= a; i++)
{
fscanf(f, "%s", buf);
result = test(buf);
printf("Case #%d: %lld\n", i, result);
}
return 0;
}
This works as intended and produces correct result to the problem. But if I replace my own pow_longlong() with pow() from math.h some calculations differ.
What is the reason to this? Just curious.
Edits:
- No overflow, plain long is enough to store the values, long long is just overkill
- Of course I include math.h
- In example: test("wontyouplaywithme") with pow_longlong returns 674293938766347782 (right) and with math.h 674293938766347904 (wrong)
Sorry that I won't go through your example and your intermediary function; the issue you're having occurs due to double being insufficient, not the long long. It is just that the number grows too large, causing it to require more and more precision towards the end, more than double can safely represent.
Here, try this really simple programme out, or just trust in the output I append to it to see what I mean:
#include <stdio.h>
int main( ){
double a;
long long b;
a = 674293938766347782.0;
b = a;
printf( "%f\n", a );
printf( "%lld", b );
getchar( );
return 0;
}
/*
Output:
674293938766347780.000000
674293938766347776
*/
You see, the double may have 8 bytes, just as much as the long long has, but it is designed so that it would also be able to hold non-integral values, which makes it less precise than long long can get in some cases like this one.
I don't know the exact specifics, but here, in MSDN it is said that its representation range is from -1.7e308 to +1.7e308 with (probably just on average) 15 digit precision.
So, if you are going to work with positive integers only, stick with your function. If you want to have an optimized version, check this one out: https://stackoverflow.com/a/101613/2736228
It makes use of the fact that, for example, while calculating x to the power 8, you can get away with 3 operations:
...
result = x * x; // x^2
result = result * result; // (x^2)^2 = x^4
result = result * result; // (x^4)^2 = x^8
...
Instead of dealing with 7 operations, multiplying them one by one.
pow (see reference) is not defined for integers, but only for floating point numbers. If you call pow with int as an argument the result will be a double.
You can in general not assume that the result of pow will be exactly the same as if you would use pure integer math as in the function pow_longlong.
Citation from wikipedia about double precision floating point numbers:
Between 2^52=4,503,599,627,370,496 and 2^53=9,007,199,254,740,992 the
representable numbers are exactly the integers. For the next range,
from 2^53 to 2^54, everything is multiplied by 2, so the representable
numbers are the even ones, etc.
So you get inaccurate results with pow if the result would be bigger than 2^53.
I have an issue where I am inputting an decimal argument to my code:
./a.out 650
and would like to simply convert the decimal value into hex and output it in a little-endian format:
0A28
My current solution has been to convert the char* to decimal using atoi (we can assume the input is decimal, no worry about error cases).
I have read that I could create an int* and cast it to the char*, something like this:
char* bar = argv[1];
int* foo = (char*)&bar;
and that iterating through it would produce the solution I needed, but I do not quite understand how that would work.
Like this:
#include <stdio.h>
#include <stdlib.h>
unsigned long int n = strtoul(argv[1], NULL, 0);
unsigned char const * p = (unsigned char const *)&n;
for (size_t i = 0; i != sizeof n; ++i)
printf("%02X", p[i]);
To print the reverse endianness, use sizeof n - i - 1 in place of i.
This should take the program's first parameter and print it out as a big endian hexadecimal number and little endian hexadecimal.
int main(int argc, char *argv[]) {
if (argc != 2) return -1;
char *endptr;
unsigned long d = strtoul(argv[1], &endptr, 10);
if (*endptr) {
printf("Not a decimal number '%s'\n", argv[1]);
return 1;
}
printf("%lX\n", d); // normal
do {
printf("%02hhX", (unsigned char) d); // little endian first
d >>= 8;
} while (d);
printf("\n");
return 0;
}
I have a simple code to convert binary to decimal numbers. In my compiler, the decomposition works just fine for number less than 1000, beyond the output is always the same 1023. Anybody has an idea ?
#include <stdio.h>
#include <stdlib.h>
// how many power of ten is there in a number
// (I don't use the pow() function to avoid trouble with floating numbers)
int residu(int N)
{
int i=0;
while(N>=1){
N=N/10;
i++;
}
return i;
}
//exponentiating a number a by a number b
int power(int a, int b){
int i;
int res=1;
for (i=0;i<b;i++){res=a*res;}
return res;
}
//converting a number N
int main()
{
int i;
//the number to convert
int N;
scanf("%d",&N);
//the final decimal result
int res=0;
//we decompose N by descending powers of 10, and M is the rest
int M=0;
for(i=0;i<residu(N);i++){
// simple loop to look if there is a power of (residu(N)-1-i) in N,
// if yes we increment the binary decomposition by
// power(2,residu(N)-1-i)
if(M+ power(10,residu(N)-1-i) <= N)
{
M = M+power(10,residu(N)-1-i);
res=power(2,residu(N)-1-i)+res;
}
}
printf("%d\n",res);
}
Yes try this :
#include <stdio.h>
int main(void)
{
char bin; int dec = 0;
while (bin != '\n') {
scanf("%c",&bin);
if (bin == '1') dec = dec * 2 + 1;
else if (bin == '0') dec *= 2; }
printf("%d\n", dec);
return 0;
}
Most likely this is because you are using an int to store your binary number. An int will not store numbers above 2^31, which is 10 digits long, and 1023 is the largest number you can get with 10 binary digits.
It would be much easier for you to read your input number as a string, and then process each character of the string.
After a little experimentation, I think that your program is intended to accept a number consisting of 1's and 0's only as a base-10 number (the %d reads a decimal number). For example, given input 10, it outputs 2; given 1010, it outputs 10; given 10111001, it outputs 185.
So far, so good. Unfortunately, given 1234, it outputs 15, which is a little unexpected.
If you are running on a machine where int is a 32-bit signed value, then you can't enter a number with more than 10 digits, because you overflow the limit of a 32-bit int (which can handle ±2 billion, in round terms). The scanf() function doesn't handle overflows well.
You could help yourself by echoing your inputs; this is a standard debugging technique. Make sure the computer got the value you are expecting.
I'm not going to attempt to fix the code because I think you're going about the problem in completely the wrong way. (I'm not even sure whether it's best described as binary to decimal, or decimal to binary, or decimal to binary to decimal!) You would do better to read the input as a string of (up to 31) characters, then validate that each one is either a 0 or a 1. Assuming that's correct, then you can process the string very straight-forwardly to generate a value which can be formatted by printf() as a decimal.
Shift left is the same than multiply by 2 and is more efficient, so I think it is a more c-like answer:
#include <stdio.h>
#include <stdlib.h>
int bin2int(const char *bin)
{
int i, j;
j = sizeof(int)*8;
while ( (j--) && ((*bin=='0') || (*bin=='1')) ) {
i <<= 1;
if ( *bin=='1' ) i++;
bin++;
}
return i;
}
int main(void)
{
char* input = NULL;
size_t size = 0;
while ( getline(&input, &size, stdin) > 0 ) {
printf("%i\n", bin2int(input));
}
free(input);
}
#include <stdio.h> //printf
#include <string.h> //strlen
#include <stdint.h> //uintX_t or use int instead - depend on platform.
/* reverse string */
char *strrev(char *str){
int end = strlen(str)-1;
int start = 0;
while( start<end ){
str[start] ^= str[end];
str[end] ^= str[start];
str[start] ^= str[end];
++start;
--end;
}
return str;
}
/* transform binary string to integer */
uint32_t binstr2int(char *bs){
uint32_t ret = 0;
uint32_t val = 1;
while(*bs){
if (*bs++ == '1') ret = ret + val;
val = val*2;
}
return ret;
}
int main(void){
char binstr[] = "1010101001010101110100010011111"; //1428875423
printf("Binary: %s, Int: %d\n", binstr, binstr2int(strrev(binstr)));
return 0;
}