Related
How can i calculate in C power of 2, without pow function?
For example, after keyboard input 4, the result to be 16?
I know that, for example, 2^5 can be typing similar like 2^1*2^5 (I don't know if this idea can help)
To calculate 2N in C, use 1 << N.
If this may exceed the value representable in an int, use (Type) 1 << N, where Type is the integer type you want to use, such as unsigned long or uint64_t.
<< is the left-shift operator. It moves bits “left” in the bits that represent a number. Since numbers are represented in binary, moving bits left increases the powers of 2 they represent. Thus, 12 represents 1, 102 represents 2, 1002 represents 4, and so on, so 1 shifted left N positions represents 2N.
Numbers can be represented in binary form. For example, if integers are stored using 32 bits, 1 is stored like this:
00000000 00000000 00000000 00000001
And the value is the result of 1 x (20)
If you do a left-shift operation your value will be stored as this:
00000000 00000000 00000000 00000010
That means that now the result is result of 1 x (21)
Bit used to store a type is sizeof(type)x8, because a byte is 8 bit.
So best method is to use shift:
The left-shift of 1 by exp is equivalent to 2 raised to exp.
Shift operators must not be used for negative exponents in case of pow. The result is an undefined behaviour.
Another case of undefined behavior is the one of shifting the number equal to or more than N, in case of that number is stored in N bits.
#include <stdio.h>
#include <stdlib.h>
int main() {
int exp;
printf("Please, insert exponent:\n");
if (scanf("%d", &exp) != 1) {
printf("ERROR: scanf\n");
exit(EXIT_FAILURE);
}
if (exp < 0) {
printf("ERROR: exponent must be >= 0\n");
exit(EXIT_FAILURE);
}
printf("2^(%d) = %d\n", exp, 1 << exp);
exit(EXIT_SUCCESS);
}
You can also do it creating a ricorsive function (int) -> int:
int my_pow(int exp) {
If (exp < 0 ) {
return -1;
}
if (exp == 0) {
return 1;
}
if (exp > 0) {
return 2 * my_pow(exp-1);
}
}
Using it as main:
int main() {
int exp;
scanf("%d" &exp);
int res = my_pow(exp);
if (res == -1) {
printf("ERROR: Exponent must be equal or bigger than 0\n");
exit(EXIT_FAILURE);
}
printf("2^(%d) = %d", exp, res);
return 0;
}
I wrote simple code in C language (without libraries), but the result is good only when you read it from right to left, how to reverse it? I want the most simplified code as it is possible. My code below:
#include <stdio.h>
int main() {
int number;
printf("Changes from decimal to binary\n");
printf("Enter the number: ");
scanf("%d",&number);
do{
if(number % 2 == 1){
printf("1");
}else{
printf("0");
}
number = number / 2;
}
while(number>0);
return 0;
}
You could store the binary number in an array and then print it backwards. So you would have for example int binaryDigits[1024]; and then instead of printing you will store the number in the array with a counter. Before the loop: int i = 0; and after that instead of printf("1"); and printf("0");, binaryDigits[i++] = 1 and binaryDigits[i++] = 0 respectively. Finally you could print the number in order with a for loop:
for (i = i - 1; i >= 0; i--)
printf("%d", binaryDigits[i])
You could use recursion and print the digits as you fall off the stack. I changed number from int to unsigned int.
void print_dec_to_bin_hlp(unsigned int number)
{
if(number > 0)
{
print_dec_to_bin_hlp(number/2);
printf("%d", (number%2));
}
}
void print_dec_to_bin(unsigned int number)
{
if (number == 0) printf("%d", number);
else print_dec_to_bin_hlp(number);
}
A recursive solution using bitwise operations, for unsigned integers:
void print_binary(unsigned int num) {
if(num >> 1) print_binary(num >> 1);
putchar(num & 1 ? '1' : '0');
}
The bitwise operators >>, &, etc. access the bits in the value. The bits form a binary representation of the number. >> shifts the bits to the right, where the bits are ordered from MSB (most significant bit) to LSB, like the normal way numbers are written.
num & 1 returns non-zero only if the LSB (rightmost) bit is set. (AND mask with ..0001). So (num >> 1) & 1 does the same on the second-rightmost bit. So this recursive function prints the bits in MSB to LSB order.
The if(num >> 1) check makes sure prefix zeroes are not printed: If after the rightshift, num is all-zeroes, it is not printed any further. The check is made outside the function call, so that print_binary(0) (initial call) will still always print a single 0.
For signed integers:
void print_signed_binary(int num) {
if(num < 0) {
putchar('-');
print_binary(-num);
} else {
print_binary(num);
}
}
Introduction
This program should input a number in decimal (base 10) from the user, convert that number to binary, calculate the "binary sum", then present the binary sum and binary representation of the input.
The program should go something like this:
What type of display do you want?
Enter 1 for character parity, 2 for integer checksum: 2
Enter an integer for checksum calculation: 1024
Integer: 1024, Bit representation: 00000000 00000000 00000100 00000000
Sum of the number is: 4
Checksum of the number is: 4, Bit representation: 00000100
What is binary sum?
The "binary sum" of a number, n, is defined splitting the binary representation of n into 8-bit long numbers, and summing the base-10 value of each. This means 32-bit long numbers, you sum the base-10 values of the numbers represented by bits (1-8), (9-16), (17-24), and (25-32). Here is an example:
Example of binary sum of 1234567:
Step 1:
Convert 1234567 into it's binary representation.
1234567 -> 100101101011010000111
Step 2:
Split the binary number into 8 bit parts, adding zero's to the left if needed to make complete 8-bit numbers.
100101101011010000111 -> 00010010 11010110 10000111
Step 3:
Convert each 8-bit long number to decimal then add their values.
00010010 -> 18 (2^1 + 2^4 => 2 + 16 = 18)
11010110 -> 214 (2^1 + 2^2 + 2^4 + 2^6 + 2^7 => 2 + 4 + 16 + 64 + 128) = 214
10000111 -> 135 (2^0 + 2^1 + 2^2 + 2^7 => 1 + 2 + 4 + 128) = 135
18 + 214 + 135 = 367
The binary sum of 1234567 is 367.
I have no problem showing the binary representation of the input, but I'm not sure on how calculate the binary sum. This is challenging because I'm not allowed to use strings or arrays, only basic primitive data types.
This the code I have made so far, with comments where I am having issues:
int main(void) {
char endLoop;
int userChoice;
char choice1;
char byte;
int choice2;
while(endLoop != 'q') {
printf("\nWhat type of display do you want?");
printf("\nEnter 1 for character parity, 2 for integer checksum: ");
scanf("%d", &userChoice);
if(userChoice == 1) {
printf("Enter a character for parity calculation: ");
scanf(" %c", &choice1);
printf("Character: %c" , choice1);
printf(", Bit Representation: ");
int number1s = fromBinary(toBinary(choice1, 8));
printf("\nNumber of ones: %d", number1s);
printf("\nEven 1 parity for the character is: ");
if(number1s % 2 != 0) {
printf("1");
toBinary(choice1, 7);
} else {
toBinary(choice1, 8);
}
}
if(userChoice == 2) {
printf("Enter an integer for checksum calculation: ");
scanf("%d", &choice2);
printf("Integer: %d", choice2);
printf(", Bit Representation: " );
toBinary(choice2, 32);
printf("\nSum of number is: ");
printf("\nChecksum of number is: ");
printf(", Bit Representation: ");
}
printf("\n\nEnter r to repeat, q to quit: ");
scanf(" %c", &endLoop);
}
}
int toBinary(int userInput, int bits) {
int i;
int mask = 1 << bits - 1;
int count = 0;
for (i = 1; i <= bits; i++) {
if (userInput & mask){
count++;
putchar('1');
} else {
putchar('0');
}
userInput <<= 1;
if (! (i % 8)) {
putchar(' ');
}
}
return count;
}
int fromBinary(char binaryValue) {
// I wanted to take the binary value I get from toBinary() and
// convert it to decimal here. But am not sure how to go about it
// since I need the bit representation, and I don't store the bit
// representation, I only print it out.
// I need to convert it to decimal so that I can add the decimal
// values up to calculate the binary sum.
}
EDIT for negative inputs
You have said that you would also like to handle negative numbers. The simplest way to do this, is to define your method to accept an unsigned int rather than an int. This will allow you to do all your normal bit operations without worrying about handling different cases for negative numbers.
Change this line
int getSum(int n) {
to this
int getSum(unsigned int n) {
No further changes are necessary, in fact now we can remove the if statement in getSum.
The new complete getSum method has been updated below. The commented code can be found at the bottom.
Remember, if you want to print out an unsigned int, the format specifier is %u not %d.
Solution
If you have a number, and you want to add up the values of what each 8 bits of that number would be in base 10, you can do it like this:
int getSum(unsigned int n) {
int total = 0;
while(n) {
int tempCount = 0, i = 0;
for(i = 0; n && i < 8; i++) {
tempCount += (n & 1) * pow(2, i);
n >>= 1;
}
total += tempCount
}
return total;
}
Explanation
This code will (while n > 0) grab 8 bits at a time, and add their base-10 values:
2^0 * 1 or 2^0 * 0 +
2^1 * 1 or 2^1 * 0 +
2^2 * 1 or 2^2 * 0 +
... +
2^7 * 1 or 2^7 * 0
tempCount holds the sum for each set of 8 bits, and after each 8 bits, tempCount is added to the total and is reset to 0.
The condition in the for loop, n && i < 8 is of course to stop after grabbing 8 bits, but to also terminate early if n is 0.
Testing
This output:
getSum(1025) = 5
getSum(2048) = 8
getSum(1234567) = 367
getSum(2147483647) = 892
was used to verify the correctness of this code:
#include <stdio.h>
#include <math.h>
int getSum(unsigned int n) {
int total = 0;
//printf("passed in %u\n", n);
while(n) {
int tempCount = 0, i;
//printf("n starts while as %u\n", n);
// Take up to 8 bits from the right side of the number
// and add together their original values (1, 2, 4, ..., 64, 128)
for(i = 0; n && i < 8; i++) {
//printf("\t\tn in for as %u\n", n);
tempCount += (n & 1) * pow(2, i);
//printf("\t\t\tbit is %u\n", (n & 1));
n >>= 1;
}
//printf("\tAdded %u from that set of 8 bits\n", tempCount);
total += tempCount;
}
return total;
}
int main(void) {
printf("getSum(1025) = %d\n", getSum(1025));
printf("getSum(2048) = %d\n", getSum(2048));
printf("getSum(1234567) = %d\n", getSum(1234567));
printf("getSum(2147483647) = %d\n", getSum(2147483647));
return 0;
}
Of course I checked these examples by hand:
2147483647
2147483647 == 01111111 11111111 11111111 11111111
The bit sum =
01111111 + 11111111 + 11111111 + 11111111 =
127 + 255 + 255 + 255 = 892
getSum(2147483647) = 892
1025
1025 == 00000100 00000001
The bit sum =
00000100 + 00000001 =
4 + 1 = 5
getSum(1025) = 5
2048
2048 == 00001000 00000000
The bit sum =
00001000 + 00000000 =
8 + 0 = 8
getSum(2048) = 8
1234567
1234567 == 00010010 11010110 10000111
The bit sum =
00010010 + 11010110 + 10000111 =
18 + 214 + 135 = 367
getSum(1234567) = 367
-1
-1 = 11111111 11111111 11111111 11111111
The bit sum =
11111111 + 11111111 + 11111111 + 11111111 =
255 + 255 + 255 + 255 = 1020
getSum(-1) = 1020
I'm working on an assignment but I'm stuck. For some reason I can't get this outcome:
byte order: little-endian
> FFFFFFFF
0xFFFFFFFF
signBit 1, expBits 255, fractBits 0x007FFFFF
QNaN
> 3
0x00000003
signBit 0, expBits 0, fractBits 0x00000003
denormalized: exp = -126
> DEADBEEF
0xDEADBEEF
signBit 1, expBits 189, fractBits 0x002DBEEF
normalized: exp = 62
> deadbeef
0xDEADBEEF
signBit 1, expBits 189, fractBits 0x002DBEEF
normalized: exp = 62
> 0
0x00000000
signBit 0, expBits 0, fractBits 0x00000000
+zero
I have tried to solve this problem but I can't figure out where I went wrong. The following code is my attempt for this project. I feel that I'm nearing the end but I can't finish..
Here is my code:
#include <stdio.h>
#include <stdlib.h>
static char *studentName = "name";
// report whether machine is big or small endian
void bigOrSmallEndian()
{
int num = 1;
if(*(char *)&num == 1)
{
printf("\nbyte order: little-endian\n\n");
}
else
{
printf("\nbyte order: big-endian\n\n");
}
}
// get next int (entered in hex) using scanf()
// returns 1 (success) or 0 (failure)
// if call succeeded, return int value via i pointer
int getNextHexInt(int *i)
{
// replace this code with the call to scanf()
//*i = 0;
//return 1;
scanf ("%x", i);
return 1;
}
// print requested data for the given number
void printNumberData(int i)
{
//printf("%x %0#10x\n",i,*(int *)&i);
int tru_exp =0;
//int stored_exp;
int negative;
int exponent;
int mantissa;
printf("\n>");
printf("\n0x%08X",i);
negative = !!(i & 0x80000000);
exponent = (i & 0x7f800000) >> 23;
mantissa = (i & 0x007FFFFF);
printf("\nsignBit %d, ", negative);
printf("expbits %d, ", exponent);
printf("fractbits 0x%08X", mantissa);
// "%#010x, ", mantissa);
if(exponent == 0)
{
if(mantissa != 0)
{
printf("\ndenormalized ");
}
}
else{
printf("\nnormalized: ");
tru_exp = exponent - 127;
printf("exp = %d", tru_exp);
}
if(exponent == 0 && mantissa == 0 && negative == 1)
{
printf("\n-zero");
}
if(exponent ==0 && mantissa == 0 && negative == 0)
{
printf("\n+zero");
}
if(exponent == 255 && mantissa != 0 && negative == 1)
{
printf("\nQNaN");
}
if(exponent == 255 && mantissa != 0 && negative == 0)
{
printf("\nSNaN");
}
if(exponent == 0xff && mantissa == 0 && negative == 1)
{
printf("\n-infinity");
}
if(exponent == 0xff && mantissa == 0 && negative == 0)
{
printf("\n+infinity");
}
printf("\n");
while(i != 0)
break;
}
// do not change this function in any way
int main(int argc, char **argv)
{
int i; // number currently being analyzed
int nValues; // number of values successfully parsed by scanf
printf("CS201 - A01p - %s\n\n", studentName);
bigOrSmallEndian();
for (;;) {
if (argc == 1) // allow grading script to control ...
printf("> "); // ... whether prompt character is printed
nValues = getNextHexInt(&i);
printf("0x%08X\n", i);
if (! nValues) { // encountered bad input
printf("bad input\n");
while (getchar() != '\n') ; // flush bad line from input buffer
continue;
}
printNumberData(i);
if (i == 0)
break;
}
printf("\n");
return 0;
}
My outcome for this code is:
byte order: little-endian
> FFFFFFFF
0xFFFFFFFF
>
0xFFFFFFFF
signBit 1, expbits 255, fractbits 0x007FFFFF
normalized: exp = 128
QNaN
> 3
0x00000003
>
0x00000003
signBit 0, expbits 0, fractbits 0x00000003
denormalized
> DEADBEEF
0xDEADBEEF
>
0xDEADBEEF
signBit 1, expbits 189, fractbits 0x002DBEEF
normalized: exp = 62
> deadbeef
0xDEADBEEF
>
0xDEADBEEF
signBit 1, expbits 189, fractbits 0x002DBEEF
normalized: exp = 62
> 0
0x00000000
>
0x00000000
signBit 0, expbits 0, fractbits 0x00000000
+zero
I believe the problem lies in printNumberData() but I can't point where.
I hope someone can pitch in because any help is greatly appreciated.
So, the only problem, as far as I see, is that your exponent isn't signed. You can fix that by changing tru_exp into a int8_t (or signed char). Or by simply sign-extending the number manually, e.g. if (tru_exp > 128) tru_exp -= 256;
You have a series of if statements which identify special cases (zeroes, infinities, NaNs), but you identify those after you've done some processing of 'normal' values. You should use an if / else if / else if chain instead, and deal with the special cases first, with the final else handling all the regular (normalized) numbers.
Here's some code based on what you provided, but the formatting and coding is considerably condensed. The main program here avoids input, and covers the gamut of values, I believe. When this is producing the correct data, you can futz with the formatting to suit the teacher's testing harness.
#include <stdio.h>
extern void printNumberData(int i);
void printNumberData(int i)
{
int negative = (i & 0x80000000U) >> 31;
int exponent = (i & 0x7F800000U) >> 23;
int mantissa = (i & 0x007FFFFFU) >> 0;;
printf("0x%08X sign %d, exponent %3d, fraction 0x%08X: ",
i, negative, exponent, mantissa);
if (exponent == 0x00 && mantissa == 0 && negative == 1)
printf("-zero\n");
else if (exponent == 0x00 && mantissa == 0 && negative == 0)
printf("+zero\n");
else if (exponent == 0xFF && mantissa != 0 && negative == 1)
printf("QNaN\n");
else if (exponent == 0xFF && mantissa != 0 && negative == 0)
printf("SNaN\n");
else if (exponent == 0xFF && mantissa == 0 && negative == 1)
printf("-infinity\n");
else if (exponent == 0xFF && mantissa == 0 && negative == 0)
printf("+infinity\n");
else if (exponent == 0)
printf("denormalized: exp = -126\n");
else
printf("normalized: exp = %4d\n", exponent - 127);
}
int main(void)
{
printNumberData(0xFFFFFFFF); /* QNan */
printNumberData(0x00000003); /* Denorm */
printNumberData(0x00800003); /* Normal */
printNumberData(0xDEADBEEF); /* Normal */
printNumberData(0x00000000); /* +0 */
printNumberData(0x80000000); /* -0 */
printNumberData(0xFF800000); /* +Inf */
printNumberData(0x7F800000); /* -Inf */
printNumberData(0xFF800001); /* QNan */
printNumberData(0x7F800001); /* SNan */
return(0);
}
It produces one line of output per number:
0xFFFFFFFF sign 1, exponent 255, fraction 0x007FFFFF: QNaN
0x00000003 sign 0, exponent 0, fraction 0x00000003: denormalized: exp = -126
0x00800003 sign 0, exponent 1, fraction 0x00000003: normalized: exp = -126
0xDEADBEEF sign 1, exponent 189, fraction 0x002DBEEF: normalized: exp = 62
0x00000000 sign 0, exponent 0, fraction 0x00000000: +zero
0x80000000 sign 1, exponent 0, fraction 0x00000000: -zero
0xFF800000 sign 1, exponent 255, fraction 0x00000000: -infinity
0x7F800000 sign 0, exponent 255, fraction 0x00000000: +infinity
0xFF800001 sign 1, exponent 255, fraction 0x00000001: QNaN
0x7F800001 sign 0, exponent 255, fraction 0x00000001: SNaN
If you read the Wikipedia page on Single-precision floating point format, you get an explanation of sorts about denormalized numbers having an adjusted exponent of -126 even though the value of the exponent bits is 0 and 0-127 is normally -127. Basically, it is simply stated by fiat that the exponent is -126 and underflow is occurring.
Other related pages do mention it, but somewhat more 'in passing':
IEEE 754:1985
IEEE 754 revision
Double-precision floating pointformat
Half-precision floating point format
Can someone look over my program and tell me if i am doing it correctly?
I am accepting user input in the form of 8 hexadecimal digits. I want to interpret those 8 digits as an IEEE 754 32-bit floating point number and will print out information about that number.
here is my output:
IEEE 754 32-bit floating point
byte order: little-endian
>7fffffff
0x7FFFFFFF
signBit 0, expbits 255, fractbits 0x007FFFFF
normalized: exp = 128
SNaN
>40000000
0x40000000
signBit 0, expbits 128, fractbits 0x00000000
normalized: exp = 1
>0
0x00000000
signBit 0, expbits 0, fractbits 0x00000000
+zero
here is the code..
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int HexNumber;
int tru_exp =0;
int stored_exp;
int negative;
int exponent;
int mantissa;
printf("IEEE 754 32-bit floating point");
int a = 0x12345678;
unsigned char *c = (unsigned char*)(&a);
if (*c == 0x78)
{
printf("\nbyte order: little-endian\n");
}
else
{
printf("\nbyte order: big-endian\n");
}
do{
printf("\n>");
scanf("%x", &HexNumber);
printf("\n0x%08X",HexNumber);
negative = !!(HexNumber & 0x80000000);
exponent = (HexNumber & 0x7f800000) >> 23;
mantissa = (HexNumber & 0x007FFFFF);
printf("\nsignBit %d, ", negative);
printf("expbits %d, ", exponent);
printf("fractbits 0x%08X", mantissa);
// "%#010x, ", mantissa);
if(exponent == 0)
{
if(mantissa != 0)
{
printf("\ndenormalized ");
}
}
else{
printf("\nnormalized: ");
tru_exp = exponent - 127;
printf("exp = %d", tru_exp);
}
if(exponent == 0 && mantissa == 0 && negative == 1)
{
printf("\n-zero");
}
if(exponent ==0 && mantissa == 0 && negative == 0)
{
printf("\n+zero");
}
if(exponent == 255 && mantissa != 0 && negative == 1)
{
printf("\nQNaN");
}
if(exponent == 255 && mantissa != 0 && negative == 0)
{
printf("\nSNaN");
}
if(exponent == 0xff && mantissa == 0 && negative == 1)
{
printf("\n-infinity");
}
if(exponent == 0xff && mantissa == 0 && negative == 0)
{
printf("\n+infinity");
}
printf("\n");
}while(HexNumber != 0);
return 0;
}
I dont think the de normalized is right?
Generally, you're pretty close. Some comments:
0x7fffffff is a quiet NaN, not a signaling NaN. The signbit does not determine whether or not a NaN is quiet; rather it is the leading bit of the significand (the preferred term for what you call "mantissa") field. 0xffbfffff is a signaling NaN, for example.
Edit: interjay correctly points out that this encoding isn't actually required by IEEE-754; a platform is free to use a different encoding for differentiating quiet and signaling NaNs. However, it is recommended by the standard:
A quiet NaN bit string should be
encoded with the first bit of the
trailing significand field T being 1.
A signaling NaN bit string should be
encoded with the first bit of the
trailing significand field being 0.
Infinities and NaNs usually aren't called "normal numbers" in the IEEE-754 terminology.
Your condition for calling a number "denormal" is correct.
For normal numbers, it would be nice to add the implicit leading bit when you report the significand. I personally would probably print them out in the C99 hex notation: 0x40000000 has a significand (once you add the implicit bit) of 0x800000 and an exponent of 1, so becomes 0x1.000000p1.
I'm sure some aging PDP-11 hacker will give you a hard time about "big endian" and "little endian" not being the only two possibilities.
Edit Ok, example of checking for qNaN on platforms that use IEEE-754's recommended encoding:
if (exponent == 0xff && mantissa & 0x00400000) printf("\nqNaN");