I feel like I am nearing an end on this assignment, but do not understand why it only works correctly every other time. If I enter "FFFFFFFF" my program prints out:
0xFFFFFFFF
signBit 1, expBits 255, fractBits 0x007FFFFF
QNaN
but if I enter "FFFFFFFF" again my program prints out:
0xFFFFFFFF
my program will not print out the correct output every time but yet every other time.
Is there anyone who can help me identify where the error occurs in my code?
Any help is greatly appreciated!
Thanks!
// do not change this code except in the following ways:
// * write code for the following functions:
// * bigOrSmallEndian()
// * getNextHexInt()
// * printLinesForNumber()
// * change studentName by changing "I. Forgot" to your actual name
#include <stdio.h>
#include <stdlib.h>
static char *studentName = "Tenzin Shakya";
// 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>");
scanf("%x", &i);
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;
}
You are inputting the user's number in getNextHexInt, but printNumberData asks for the input again with another scanf. You don't need the second scanf because the input i is already set to the user's input from getNextHexInt.
here's the code for doing that
float myFloat;
int myInt;
memcpy(&myInt, &myFloat, 4);
int signBit = ((1 << 31) & myInt) >> 31;
printf("%i\n", signBit)
I typed it up in a rush, hopefully it works, ill check it in a sec
Heres a program, but it displays -1 for some reason for sign
#include <string.h>
#include <stdio.h>
int main()
{
float a = 1337;
int* b = (int*)&a;
int signbit = ((1 << 31) & *b) >> 31;
printf("%i\n", signbit);
a *= -1;
signbit = ((1 << 31) & *b) >> 31;
printf("%i\n", signbit);
return 0;
}
Related
How would I change this function to handle negative numbers? It correctly outputs everything but it does not make the leading bit 1 when negative. I can't do a negative check then simply force the first bit to be 1 because the amount of 0s between the leading bit and rest of the numbers will be off.
char* fromInt(int bin){
static char str[33];
str[1] = '\0';
int n;
for (n = 128; n > 0; n >>= 1){
if( (bin & n) == n){
strcat(str, "1");
}else{
strcat(str, "0");
}
}
return str;
}
I guess what you want is:
char* fromInt(int bin)
{
static char str[33];
str[0] = '0' + ((bin & 0x80000000) == 0x80000000);
str[1] = '\0';
for (int n = 0x40000000; n > 0; n >>= 1) {
if ((bin & n) == n)
strcat(str, "1");
else
strcat(str, "0");
}
return str;
}
The function has two steps. First is to determine the setting of sign bit (assuming that int object has 32 bits and it uses two's complement arithmetic):
(bin & 0x80000000) == 0x80000000
yields either 1 or 0. Because it's about the sign, It might have been written simply as:
'0' + (bin < 0)
The second step is to loop over remaining bits from position 30 to 0, like in the original code.
Here is an example program:
int main(void)
{
printf("%s\n", fromInt(0));
printf("%s\n", fromInt(1536));
printf("%s\n", fromInt(-1));
return 0;
}
This will output:
00000000000000000000000000000000
00000000000000000000011000000000
11111111111111111111111111111111
I have a file in this format:
F2,80,FF,CF,0F,00,A2,XXXX,XXXX,XXXX,01FE,00
I need to take bytes 3 and 4 and combine them into a signed integer.
For example I should extract FF and CF and combine them to 0xFFCF. This should give me a signed value of -49.
The code that I have is here:
int main()
{
char buffer[1024] ;
char *record,*line;
uint8_t val;
uint8_t msb, lsb;
int16_t rate;
int i=0,j=0;
int mat[100][100];
FILE *fstream = fopen("log1.txt","r");
if(fstream == NULL)
{
printf("\n file opening failed ");
return -1 ;
}
while((line=fgets(buffer,sizeof(buffer),fstream))!=NULL)
{
record = strtok(line,",");
int count = 0;
while(record != NULL)
{
count++;
if (count == 3)
{
printf("string:%s\n", record);
sscanf(record, "%02X", &msb);
printf("MSB: %01X\n",msb) ;
}
if (count == 4)
{
printf("string:%s\n", record);
sscanf(record, "%02X", &lsb);
printf("lsb: %01X\n",lsb);
}
if (count == 5)
{
int16_t value = (short)(((msb) & 0xFF) << 8 | (lsb) & 0xFF);
printf("rate: %.2f\n", value*0.03125);
getchar();
}
record = strtok(NULL,",");
}
++i ;
}
return 0;
}
The exact output I see from my code is:
string:FF
MSB: FF
string:CD
lsb: CD
HEX: 00CD
rate: 6.41
I would expect rate to come out as: -1.59
I never seem to see negative numbers, and the values I get are too small.
Rather than using different variable types to try and get the behaviour that you want, how about just being explicit about it? Like so:
#include <stdio.h>
int main(int argc, char *argv[])
{
int msb = 0xff;
int lsb = 0xcf;
int value = (((msb & 0xff) << 8) | (lsb & 0xff));
if (value >= 0x8000) value = -(0x10000 - value);
printf("%d\n", value);
return 0;
}
Here is how I got the code to work:
int16_t hexToInt(char* msb, char* lsb)
{
char toparse[50];
strcpy(toparse, msb);
strcat(toparse,lsb);
int16_t number = (int16_t)strtol(toparse, NULL, 16);
return number;
}
int main()
{
char buffer[1024] ;
char *record,*line;
uint8_t val;
char msb[16], lsb[16];
int16_t rate;
FILE *fstream = fopen("log1.txt","r");
if(fstream == NULL)
{
printf("\n file opening failed ");
return -1 ;
}
while((line=fgets(buffer,sizeof(buffer),fstream))!=NULL)
{
record = strtok(line,",");
int count = 0;
while(record != NULL)
{
count++;
if (count == 3)
{
printf("string:%s\n", record);
strcpy(msb, record);
}
if (count == 4)
{
printf("string:%s\n", record);
strcpy(lsb,record);
}
if (count == 5)
{
int16_t value = hexToInt(msb,lsb);
printf("rate: %.2f\n", value*0.03125);
getchar();
}
record = strtok(NULL,",");
}
++i ;
}
return 0;
}
The value is indeed 0xFFCF, but when multiplying with 0.03125 it is promoted to higher datatype because of which value looses its signedness.
Just change
printf("rate: %.2f\n", value*0.03125);
to
printf("rate: %.2f\n", ((short)value*0.03125));
With value being -49 or 0xFFCF the output will be
rate: -1.53
Code has undefined behavior. OP's code attempts to save an int sized result into 1-byte locations. A good compiler or one with warnings enabled would warn of this issue.
uint8_t msb, lsb;
...
sscanf(record, "%02X", &msb);
sscanf(record, "%02X", &lsb);
Code could use the correct scanf() specifier
#include <inttypes.h>
sscanf(record, "%02" SCNx8, &msb);
sscanf(record, "%02" SCNx8, &lsb);
or simply a different type
unsigned msb, lsb;
...
sscanf(record, "%02X", &msb);
sscanf(record, "%02X", &lsb);
OP's conversion is suspect:
uint8_t msb, lsb;
int16_t value = (short)(((msb) & 0xFF) << 8 | (lsb) & 0xFF);
printf("rate: %.2f\n", value*0.03125);
Suggest something like #John Bickers The following works even if int is 16-bit.
long value = msb;
value <<= 8;
value += lsb;
if (value >= 0x8000) value -= 0x10000;
printf("value %ld\n", value);
// -49 * 0.03125 --> "-1.53"
printf("rate: %.2f\n", value * 0.03125);
Since OP expects a scaled out of -15.6 from -49, perhaps scaling by 1/pi is needed rather than * 0.03125?
I am writing a program that simulate a transmission of characters over the network.
I have written the following function:
int getCharBit(char c, int bitNum){
return (c & (1 <<bitNum)) >> bitNum;
}
// returns the ith bit of the character c
int getShortBit(short num, int bitNum)
{
return (num & (1 <<bitNum)) >> bitNum;
}
// sets bit i in num to 1
int setShortBit(int bitNum, short *num){
return num | (1 << bitNum);
}
// count the number of bits in the short and returns the number of bits
/* input:
num - an integer
Output:
the number of bits in num
*/
int countBits(short num)
{
int sum=0;
int i;
for(i = num; i != 0; i = i >> 1){
sum += i & 1;
}
return sum;
}
I also written a function that counts the number of ones in a short integer num and a mask:
int countOnes(short int num, short int pMask){
short tempBit = num & pMask;
sum = 0;
while(tempBit > 0){
if((tempBit & 1) == 1){
sum ++;
}
tempBit >> 1;
}
return sum;
}
and a function that sets the Parity Bit:
int setParityBits(short *num)
// set parity bit p1 using mask P1_MASK by
// get the number of bits in *num and the mask P1_MASK
int numOnes = countOnes(num, P1_MASK);
// if the number of bits is odd then set the corresponding parity bit to 1 (even parity)
if ((numOnes % 2) != 0){
setShortBit(1, num);
}
// do the same for parity bits in positions 2,4,8
int numOnes2 = countOnes(num, P2_MASK);
if ((numOnes2 % 2) != 0){
setShortBit(2, num);
}
int numOnes4 = countOnes(num, P4_MASK);
if ((numOnes4 % 2) != 0){
setShortBit(4, num);
}
int numOnes8 = countOnes(num, P8_MASK);
if ((numOnes8 % 2) != 0){
setShortBit(8, num);
}
I am also given a few function that are supposed to read the input and transmit it. The problem is in one of the functions I have written.
For example, if I run the program and type hello as an input, I should get 3220 3160 3264 3264 7420 as an output, but I get 0 0 0 0 0.
I can't seem to find what I was doing wrong, Could someone please help me?
I'm create CRC-CCITT Encode (Polynomail 0x1021 and Initial Value is 0xFFFF)
It is correct 8bit, 16bit, 24bit, 32bit ... (1 Byte, 2Byte, 3Byte ...)
But not correct answer 12bit, 20bit, 28bit (not Byte)
I find this algorithm
function crc(bit array bitString[1..len], int polynomial) {
shiftRegister := initial value // 00000000 OR 11111111
for i from 1 to len {
if (shiftRegister top bit) xor bitString[i] = 1
shiftRegister := (shiftRegister left shift 1) xor polynomial
else
shiftRegister := shiftRegister left shift 1
}
return shiftRegister
}
and my source code is like that
// crc_ccitt.h
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
static const char CRC_CCITT[] = "0001000000100001";
static char Shift_Register[] = "1111111111111111";
char* getCRC(char *, int);
void leftShift(char *);
void xorCalc();
char* getCRC(char* dataCode, int dataCodeLength) {
int i;
for (i = 0; i < dataCodeLength; i++) {
if ((Shift_Register[0] == '1' && dataCode[i] == '0')
|| (Shift_Register[0] == '0' && dataCode[i] == '1')) {
leftShift(Shift_Register);
xorCalc();
} else {
leftShift(Shift_Register);
}
printf("%c%c%c%c ", Shift_Register[0], Shift_Register[1], Shift_Register[2], Shift_Register[3]);
printf("%c%c%c%c ", Shift_Register[4], Shift_Register[5], Shift_Register[6], Shift_Register[7]);
printf("%c%c%c%c ", Shift_Register[8], Shift_Register[9], Shift_Register[10], Shift_Register[11]);
printf("%c%c%c%c ", Shift_Register[12], Shift_Register[13], Shift_Register[14], Shift_Register[15]);
printf("\n");
}
return Shift_Register;
}
void leftShift(char *Shift_Register) {
memmove(Shift_Register, Shift_Register + 1, strlen(Shift_Register) - 1);
memset(Shift_Register + strlen(Shift_Register) - 1, '0', 1);
}
void xorCalc() {
int i;
for (i = 0; i < 16; ++i) {
if ((Shift_Register[i] == '1' && CRC_CCITT[i] == '0')
|| (Shift_Register[i] == '0' && CRC_CCITT[i] == '1')) {
Shift_Register[i] = '1';
} else {
Shift_Register[i] = '0';
}
}
}
// crc_ccitt.c
#include "crc_ccitt.h"
int main() {
char dataCode[256];
char *CRC = "";
printf("Input Data Code: ");
gets(dataCode);
/*
puts(dataCode);
rightShift(dataCode);
puts(dataCode);
*/
CRC = getCRC(dataCode, strlen(dataCode));
//printf("%s", CRC);
return 0;
}
I confirm CRC Encode value with this page
http://www.lammertbies.nl/comm/info/crc-calculation.html
For example
Input 0001111111110010(1FF2)
page : C11F
my program : 1100 0001 0001 1111 (C11F)
But
Input 000111111111 (1FF)
page : FFAD
my program : 1101 0011 0000 1111 (D30F)
What of lack of my program??
Or, is algorithm is wrong??
Program OK
Algorithm OK
User input is likely the error.
Your CRC "0001000000100001" is for a 16-bit operation.
Your failed input is "000111111111", 12 bits.
Instead try using "0000000111111111" or "0001111111110000" (pad on the left or right)
Note: I would have tried it myself but you did not provide crc_ccitt.h
I am trying to convert a decimal number (329.39062) to binary (exponent, mentissa). I keep getting segmentation fault. on running the gdb test, It shows me feof. I have changed alot but it keeps showing me the segmentation fault at the same point. Where am i going wrong? Thank you for all the help.
#include <stdio.h>
#include <stdlib.h>
char* valueToConvert(int value);
int main(int argc, char *argv[])
{
FILE* input;
FILE* output;
input = fopen(argv[1],"r");
output = fopen(argv[2],"w");
float value;
unsigned char *charValue = (unsigned char *) &value;
int exponentValue;
long mantissaValue;
while(!feof(input))
{
fread(&charValue, sizeof(float),1, input);
exponentValue = ((charValue[0] & 0x7F) << 1)|((charValue[1] & 0x80) >> 7);
mantissaValue = ((charValue[1] & 0x7F) << 8)|((charValue[2] & 0xFF) <<8) | (charValue[3] & 0xFF);
fprintf(output,"%d %s %s\n",(charValue[0] & 0x80 >> 7),valueToConvert(exponentValue - 127),valueToConvert(mantissaValue));
}
}
char* valueToConvert(int value)
{
int counter = 0;
char* conversion = calloc(32,sizeof(int));
while(value>0)
{
if((value%2 == 1) && (value%2 != 0))
{
conversion[31 - counter++] = '1';
}
if((value%2 == 0) && (value%2 != 1))
{
conversion[31 - counter++] = '0';
}
value = value/2;
}
return conversion;
}
The problem is here:
fread(&charValue, sizeof(float),1, input);
That should be
fread(charValue, sizeof(float),1, input);
Because charValue is a pointer.
To address your problems with the output, you're filling the buffer backwards after initializing it completely with 0 via calloc, so fprintf is hitting 0 (a char used to signify the end of a string) and stopping "prematurely".
Here's a fast binary string function:
void fast_d2b(int x, char* c) {
int i;
for (i = 31; i >= 0; --i) {
*(c++) = '0' + ((x >> i) & 0x1);
}
}
It's based on the one shown here.
Only differences are that my variation doesn't write to the buffer backwards and it writes '0' and '1' instead of integral values 0 and 1.