How to change datatypes in c - c

I have a function, which adds the given arguments and prints the result.
With integer numbers, there were no problems at all. Used atoi to change string argument -> int.
e.g. : ./main 3 4 5 will print 12.
But if I have ./main 4.5 6 5.5 ?how do I do something like this in C? How can the function "see", that it has to change the argument types now to float?
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char* argv[] )
{
int i , sum = 0;
for(i=1; i < (argc); ++i)
sum += atol(argv[i]);
printf("%d\n", sum);
return 0;
}

In c, there is no function overloading as in c++, thus you should use atof, like this:
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char* argv[] )
{
int i;
double sum = 0;
for(i = 1; i < (argc); ++i)
sum += atof(argv[i]);
printf("%f\n", sum);
return 0;
}
to treat numbers as reals, not integers.
Output:
gsamaras#gsamaras-A15:~$ ./a.out 4.5 6 5.5
16.000000
since now 6 is treated like 6.0.
You might want to read this as well: How to convert string to float?

I have tested the code below. It will print the float number upto 2 decimal places.
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char* argv[] )
{
int i;
double sum = 0;
for(i=1; i<argc; i++)
sum += atof(argv[i]);
printf("%.2f\n", sum);
return 0;
}

You should use double to store floating point numbers, atof to parse strings and the %f printf specifier.

Although I get an implicit declaration warning for strtod (because the linux manual doesn't tell me the correct includes to use), this code below does work:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
int i;
double sum=0;
for(i=1; i < argc; ++i)
sum += strtod(argv[i],NULL);
printf("%f\n", sum);
return 0;
}
The manual also states the following as an issue with using atoi():
The atoi() function converts the initial portion of the string pointed to by nptr to int.
The behavior is the same as
strtol(nptr, (char **) NULL, 10);
except that atoi() does not detect errors.

Related

I am trying to write a code that takes the sum of each value but also prints each value along the way

I want to take the sum of various equations listed below from 1 to 100. I keep getting an error "float point exception: 8". I am not sure what I am doing wrong.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char** argv)
{
double sk1[100]={0};
double sk2[100]={0};
double sk3[100]={0};
double sk4[100]={0};
for(int i=1;i<101;++i)
{
sk1[i-1]+=(1/i)-log(i);
sk2[i-1]+=1/(i^2);
sk3[i-1]+=1/(i^3);
sk4[i-1]+=1/(i^4);
printf("%e %e %e %e\n",sk1[i-1],sk2[i-1],sk3[i-1],sk4[i-1]);
}
return 0;
}
For example, for sk1, the code would print (1/1)-log(1), then (1/2)-log(2) + the previous value, and so on.
In C, ^ is the bitwise XOR operator, and not the power function.
In the 2nd loop, when the cpu is trying to calculate the expression
sk2[i-1]+=1/(i^2);
it actually try to divide by zero!
(2 ^ 2) == (00000010 ^ 00000010) == 0
What you really want to do, is to use pow;
int main(int argc, char** argv)
{
double sk1[100]={0};
double sk2[100]={0};
double sk3[100]={0};
double sk4[100]={0};
for(int i=1;i<101;++i)
{
sk1[i-1]+=(1/i)-log(i);
sk2[i-1]+=1/pow(i, 2);
sk3[i-1]+=1/pow(i, 3);
sk4[i-1]+=1/pow(i, 4);
printf("%e %e %e %e\n",sk1[i-1],sk2[i-1],sk3[i-1],sk4[i-1]);
}
return 0;
}
The error is that you are using ^. In C, that is not the power operator, it's the binary XOR operator. Instead, you could use pow(base, exp), which is already included in math.h

Incorrect single precision floating point representation on ubuntu 64 bit

I have the following data.
float u[4] = {0x3f951d32, 0x3f207887, 0x3d99c3a0, 0x3eb405d2};
ScaleFunction(u);
void ScaleFunction(float *u_ptr)
{
for(int i = 0; i < 4; i++)
{
printf("u[%d] = %f\n", u_ptr[i]);
}
// And a lot more
}
The application containing the snippet above is executed on a 64 bit machine running ubuntu 16.10.
Much to my chagrin, the floating point numbers are incorrectly interpreted as: 1066736960.000000, 1059092608.000000, 1033487232.000000 and 1051985344.000000.
The numbers when printed in hexadecimal confirm that the caller passes the correct values to callee.
What am I doing wrong here?
I even tried the following with no joy.
uint32_t u[4] = {0x3f951d32, 0x3f207887, 0x3d99c3a0, 0x3eb405d2};
ScaleFunction(u);
void ScaleFunction(uint32_t *u_ptr)
{
float ut[4];
for(int i = 0; i < 4; i++)
{
ut[i] = (float) u_ptr[i];
printf("ut[%d] = %f\n", ut[i]);
}
// And a lot more
}
I expect to interpret the hexadecimals in the callee as:
1.1649, 0.6268, 0.075, 0.5516
The problem is, that you initialize your array with large integer values, not the hex representation of the floats. With your hex constants starting with values around 0x3f it's pretty clear that these are floating point data with values around 1.0.
As far as I know there is no direct way to initialize a float array with hex constants (if there is one, community, please tell me!).
So you have to define your data-array as int and convert it to float as you use it. IMPORTANT: Directly casting the pointer from int to float will break the aliasing rule of C and may result in code that looks correct but misbehaves.
Converting between the two data-types via memcpy is safe though and the compiler is usually smart enough to spot this and optimize it out.
So this solution here does what you want:
#include <stdint.h>
#include <stdio.h>
#include <string.h>
uint32_t u[4] = {0x3f951d32, 0x3f207887, 0x3d99c3a0, 0x3eb405d2};
void ScaleFunction(uint32_t *u_ptr)
{
for(int i = 0; i < 4; i++)
{
float temp;
memcpy (&temp, &u[i], sizeof (float));
printf("u[%d] = %f\n", i, temp);
}
// And a lot more
}
void main (int argc, char **args)
{
ScaleFunction (u);
}
You code cannot work as you think: you are assigning integers to your float. You are not assigning the HEX values as float.
Best thing you can do is to have a init array and copy it to your float array
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>
uint32_t init[] = {0x3f951d32u, 0x3f207887u, 0x3d99c3a0u, 0x3eb405d2u};
void ScaleFunction(float *u_ptr, size_t size)
{
for(size_t i = 0; i < size; i++)
{
printf("u[%zu] = %f\n", i, u_ptr[i]);
}
// And a lot more
}
int main (void)
{
assert ( sizeof(float) == sizeof(uint32_t) );
float u[sizeof(init)/sizeof(init[0])];
memcpy(u, init, sizeof(init));
ScaleFunction(u, sizeof(init)/sizeof(init[0]));
}

Get the return value from a function

I want to modify a char by using a function and print it on the screen but my code cannot achieve this function. Here is my source code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
long M = 2147483647;
void IntroduceError(char k[],double p)
{
int i;
for ( i = 0; i < 8; i++) {
if ((double)random()/M <= p)
k[i] = 1;
}
}
int main(int argc, char *argv[])
{
char test[] = "11110000";
double rate = atof(argv[1]);
IntroduceError(test, rate);
printf("\nErrored codeword is : %s\n",test);
return 0;
}
k is a string i.e. array of characters, but you're assigning an integer value to it.
Instead of:
k[i] = 1;
You probably want:
k[i] = '1';
Also, you should call srandom at the start of your program to seed the random number generator, passing in at least the PID, i.e. srandom(getpid()); so that you don't get the same results every time.
get in the printf statement is not defined. If you change get with test it should compile.

Command line number adding program produces wrong results

My Code:
#include <stdio.h>
int main(int argc, char*argv[]){
int n = argc;
int i, a, b, sum;
for(i = 0; i < n; i++){
sscanf(argv[i], "%u", &a);
b = a + sum;
sum = b;
}
printf("%d\n", sum);
return 0;
}
This piece of code should do ./a 0 1 2 3 must write terminal 6 But writes 42423.
The aim of the program was to issue the command-line arguments amount. But he does not make it correct angulation.
argv[0] holds the name of the executable which most likely you don't want to include in the loop. so, you need to start the loop from i=1.
As per your input, the argv[0] does not contain a numeric value hence causing a failure to sscanf(), leaving a uninitialized.
So, in your code, the primary issue is with,
b = a + sum;
where, for the first iteration, a and sum are both uninitialized local variables having indeterminate value. So, for the very first loop, you're invoking undefined behavior.
Also, a being an int, you need to use %d format specifier for it.
Two things to mention:
Always check for the return value of scanf() family for success.
Always initialize your local variables.
You are getting garbage value because you are not initialized varuiable sum on declaration.
Just initialize is as sum = 0 and u will get expected result.
Or u can use below code also.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char*argv[]){
int n = argc;
int i, a, b, sum=0;
for(i = 0; i < n; i++){
a = atoi(argv[i]);
sum += a;
}
printf("%d\n", sum);
return 0;
}

Beginner Here Rand in c

im a 1st grader when it comes to c and need help with storing 5 random values in an array and outputting them. Heres where am at.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
struct score_card {int A_ones; int B_twos; int C_threes; int D_fours; int E_fives; int F_sixes; int G_chance;};
int dice_rolls[5];
int randomize(void);
int value;
int main(void) {
struct score_card test;
randomize;
int i;
for(i = 0; i <= 4; i++){
printf("%d\n", dice_rolls[i]);
}
printf("\n");
return 0;
}
int randomize(void){
int i;
srand(time(0));
for(i = 0; i <= 4; i++){
value = rand() % 6 + 1;
dice_rolls[i] = value;
}
}
The output is :
6294304
6294308
6294312
6294316
6294320
the goal was to use modular division to get values from 1 -->6 and store them in the dicerolls array.
I see two immediate problems.
First. you're not terminating your random numbers with a newline. That's why they're all strung together in a big sequence. Change your output line to:
printf("%d\n", &dice_rolls[i]);
Secondly, you're not actually calling randomize. The correct way to call it is with:
randomize();
The statement randomize; is simply an expression giving you the address of the function. It's as useless in this case as the expression 42; which also does nothing. However it's valid C so the compiler doesn't necessarily complain.

Resources