Function assigns incorrect float value in C - c

I am trying to return a float value and assign it to a float variable, but the value of the new float is different from the returned one.
float getVoltageReading() {
return 1.2f;
}
void updateUIReadings(uint8_t menuID) {
float integerReading = getVoltageReading(); // digital voltage
}
In debugger I see that getVoltageReading return 1.2, but the integerReading is assigned to be 1.06703091e+009
Why is that?

You are calling the getVoltageReading function without an active prototype in scope, which means it is assuming that it will return an int. It looks like, from the way your question is organised, that it is in scope, but I can assure you it's not.
You can see that with the following two files, testprog1.c:
#include <stdio.h>
//float getVoltageReading(void);
int main(void) {
float integerReading = getVoltageReading ();
printf("%e\n", integerReading);
return 0;
}
and testprog2.c:
float getVoltageReading(void) {
return 1.2f;
}
When these are compiled and linked together, the output is:
1.067031e+09
because the float value being returned from getVoltageReading() is being interpreted as an int. If you uncomment the prototype in testprog1.c, it works fine because it interprets the float value as a float:
1.200000e+00

Related

After returning a float value from a method and trying to print it, the printed value is always wrong (although the method does works as intended)

I wrote a simple method to calculate an arithmetic mean like so:
float arithmetic_mean(int a[], int n)
{
float sum = 0;
int i;
for (i = 0; i < n; i++)
{
sum += a[i];
}
sum = sum / (float)n;
return sum;
}
I wanted to check it in main:
int main()
{
int a[] = { 1,3,5,1,6,7 };
float check = arithmetic_mean(a, 6);
printf("%f", check);
return 0;
}
even though the value the method returns is correct (=3.833333 as checked by printing it before returning it), when I try to print it in main I get 9 as the output.
I'm really new to C language and stuff like this always seems to happen with floats - I'll write a method that works and return a float - and the returned value would be something seemingly random. What am I missing here? What am I doing wrong?
The problem (which I can reproduce with MSVC) is that you are calling the arithmetic_mean function (from main) before you have defined it. Thus, the compiler uses a default definition of the function, which is that it returns an int type ... and the actual (float) value returned just happens to have a bit pattern that represents 9 when interpreted as an int.
You can leave the definition of the function where it is (after main) so long as you provide a forward declaration of the function, so that the compiler knows what the return type is:
float arithmetic_mean(int a[], int n); // Forward declaration of the function!
int main()
{
int a[] = { 1,3,5,1,6,7 };
float check = arithmetic_mean(a, 6);
printf("%f\n", check);
return 0;
}
// The actual DEFINITION (including the body) of the function can follow...
Turning on compiler warnings would have helped you spot this! For example, without the forward declaration, MSVC gives this:
warning C4013: 'arithmetic_mean' undefined; assuming extern returning
int

function of type double with no return

I want to represent the values of the sin function in the intervall 0 to 2Pi:
#include <stdio.h>
#include<math.h>
double sinus(double lower, double upper, double step){
double i;
for(i=lower; i<=upper;i=i+step){
printf("%13.3f%14.3f\n",i,sin(i));
}
}
int main () {
printf(" x-Value y-Value\n\n");
sinus(0, 2 * M_PI,M_PI/8);
return 0;
}
Why does this work? The function sinus does not return a value of type double?
Why does this work? The function sinus does not return a value of type double?
It doesn't really work... my compiler (clang 11.0) gives a warning:
return.c:11:1: warning: control reaches end of non-void function [-Wreturn-type]
It works in the sense that it's not a compilation error (unless you set your compiler to treat warnings as errors). It works in the sense that you're not using the return value from sinus() anyway, so you don't really care what's in the return value.
If you were using the result from sinus(), then your code would be broken in the sense that it's not doing something meaningful. Depending on the compiler and the details of the program, you might always get the same return value, or you might get some random garbage value; either way, the value wouldn't be meaningful.
TL/DR: Don't do that.
Is there a way to get this right without using void instead of double?
There are two obvious ways to fix the problem. You can leave the declaration of sinus() as is, and change the body to return a double to match the declaration:
double sinus(double lower, double upper, double step){
double i;
for(i=lower; i<=upper;i=i+step){
printf("%13.3f%14.3f\n",i,sin(i));
}
return 0.0;
}
Or, you can change the return type of sinus() so that you don't have to return anything:
void sinus(double lower, double upper, double step){
double i;
for(i=lower; i<=upper;i=i+step){
printf("%13.3f%14.3f\n",i,sin(i));
}
}
There's nothing in the implementation of sinus() that you seem to need to return, and no reason in main() to look at the return value, I'd go with the second option.

Is it possible to write a function which returns a pointer to a function different from the function in its argument?

I have recently stumbled on this curious thought while handling a C code.
I have written a function which returns a double and takes in as argument the pointer to a function and a certain number of parameters, namely
double template_1(double (*)(double),...);
this function correctly identifies a certain property of a real function
double f(double );
represented as a pointer in template_1, in order to maketemplate_1 valid for every real function I might plug-in.
Now I had to write another function, let it be:
double derivative(double (*)(double),double);
double derivative(double (*f)(double),double x){
double epsilon = ...;
return ( f(x+epsilon)-f(x-epsilon) )/(2.0*epsilon);
}
again with f in the argument to make it work for every f.
My question is: since I would like to use derivative in template_1 without modifying it, is it possible to write a function which takes derivative and spits out something that has the form of double (*)(double ) ?
My idea was to define typedef double (*real_function)(double);
and then to define
real_function g(double (*derivative)(double (*)(double),double ) )
which I'd like it to spit out something like: double derivative_2(double x); so that I could define something like g(derivative) = double (*h)( double); directly in template_1 argument
unfortunately I don't have the faintest idea of how to make this work, or even if it can work.
There are a couple ways to do anonymous functions in C. As the comments said, they aren't portable. But depending on the use case you may find this useful: Anonymous functions using GCC statement expressions
A couple of people have seemed to have similar issues, not sure how portable they are but they may be resourceful:
https://github.com/graphitemaster/lambdapp
https://github.com/Leushenko/C99-Lambda
Basically, if there's a way to architect your program in a way that doesn't require anonymous functions, then do it that way. If you have no other option, then I would give one of these a shot.
Warning: I am a C++ developer with little C knowledge so everything that follows is likely unidiomatic C.
As KerrekSB said, you would need to carry some state with your function. This is not possible with raw functions but you can define a struct that carries the state and add a function that works with this struct. This obviously has the drawback of losing the nice function call syntax. I whipped up an example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
typedef double (*raw_fptr)(double);
struct real_function;
typedef double (*evaluate_function)(struct real_function*, double);
struct real_function {
evaluate_function evaluate;
};
typedef struct real_function real_function;
double evaluate(real_function *f, double x) {
if(f) {
return f->evaluate(f, x);
}
return NAN;
}
struct raw_real_function {
real_function real_function_base;
raw_fptr raw_function;
};
typedef struct raw_real_function raw_real_function;
double evaluate_raw_real_function(real_function *f_base, double x) {
if(f_base) {
raw_real_function *f = (raw_real_function*)f_base;
return f->raw_function(x);
}
return NAN;
}
raw_real_function make_raw_real_function(raw_fptr function) {
raw_real_function result;
result.raw_function = function;
result.real_function_base.evaluate = evaluate_raw_real_function;
return result;
}
struct derive_real_function {
real_function real_function_base;
real_function *function_to_derive;
};
typedef struct derive_real_function derive_real_function;
double derive(real_function *f_base, double x) {
derive_real_function *f = (derive_real_function*)f_base;
double epsilon = 1e-3;
double upper = evaluate(f->function_to_derive, x+epsilon);
double lower = evaluate(f->function_to_derive, x-epsilon);
double result = (upper - lower)/(2.0*epsilon);
return result;
}
derive_real_function make_derivative(real_function * function_to_derive) {
derive_real_function result;
result.real_function_base.evaluate = derive;
result.function_to_derive = function_to_derive;
return result;
}
double x_cubed(double x) {
return x * x * x;
}
int main(int argc, char **argv) {
raw_real_function x_cubed_wrapped = make_raw_real_function(x_cubed);
derive_real_function derived = make_derivative(&x_cubed_wrapped.real_function_base);
derive_real_function derived_twice = make_derivative(&derived.real_function_base);
double x = atof(argv[1]);
double derivative = evaluate(&derived.real_function_base, x);
double second_derivative = evaluate(&derived_twice.real_function_base, x);
printf("derivative of x^3 at %f = %f\n", x, derivative);
printf("second derivative of x^3 at %f = %f\n", x, second_derivative);
return 0;
}
See (a slight variaton, due to input limitations) running here.
How does it work? I faked some inheritance with the structs real_function, raw_real_function and derive_real_function to generate virtual function calls. The struct real_function serves as the container of a virtual function table consisting of only the entry evaluate. This function pointer points to the "derived" structs' relevant evaluate function:
raw_real_function instances point to evaluate_raw_real_function (as initialized in make_raw_real_function. derive_real_function instances point evaluate to derive (as initialized in make_derivative).
When calling evaluate on the real_function_base member, it will call the associated evaluation function, which casts the real_function* to it's associated struct pointer and does what is needed with that information.
Since everything is just a real_function*, we can chain them at will but need to convert "normal" functions into the real_function format, that's what make_raw_real_function does.
If you have a function my_fancy_function:
double my_fancy_function (double x) { return sin(x) + cos(x); }
Then, you can use a helper macro that creates the derived function for you.
#define DEFINE_DERIVATIVE_OF(FUNC) \
double derivative_of_ ## FUNC (double x) { \
return derivative(FUNC, x); \
}
DEFINE_DERIVATIVE_OF(my_fancy_function)
You then pass this newly defined function to your template.
template_1(derivative_of_my_fancy_function, x, y, z);

Too many arguments to function call, What do I do?

I am working on a problem in my textbook and I need to make a triangle angle calculator Im used to java but Im not 100% on C yet, I don't understand the logic in it.
#include <stdio.h>
static float angleB;
static float angleA;
float remainingAngle(float answer)
{
float answer= angleA+angleB;
//redefinition of answer
return 0;
}
//CANT TOUCH FROM HERE TO END
int main(int argc, const char * argv[]) {
float angleA = 30.0;
float angleB = 60.0;
float angleC = remainingAngle(angleA,angleB);
// to many arguments to function call (referring to angleC)
printf("the third angle is %.2f\n",angleC);
return 0;
} //END CANT TOUCH
I don't know what to do here.
In your function definition
float remainingAngle(float answer)
the function remainingAngle() accepts one parameter.
OTOH, in your function call
remainingAngle(angleA,angleB);
you're passing two arguments.
The supplied argument number and type should match with the parameter list in function definition.
That said, your code is wrong.
Point 1. Your local variables will shadow the global ones. Maybe that's not what you want. Change
float angleA = 30.0;
float angleB = 60.0;
to
angleA = 30.0;
angleB = 60.0;
Point 2. The function
float remainingAngle(float answer)
{
float answer= angleA+angleB;
//redefinition of answer
return 0;
}
is logically wrong. It should rather be
float remainingAngle(void)
{
float answer= angleA+angleB;
return answer;
}
and should be called like
float angleC = remainingAngle();
AFTER EDIT:
as per your requirement, you can do
float remainingAngle(float angleA, float angleB)
{
float answer= angleA+angleB;
return answer;
}
However, this makes the global variables useless.
In addition to Souravs answer you could also do the following:
float remainingAngle(float angA, float angB)
{
float answer = angA + angB;
return answer;
}
So your call will stay the same.
And for the logical side, what you do is:
You pass two arguments (value of angleA and value of angleB) to the function remainingAngle. There you do the calculation and return the result (answer).
The design of your function isn't good:
static float angleB;
static float angleA;
float remainingAngle(float answer)
{
float answer= angleA+angleB;
//redefinition of answer
return 0;
}
What do I do?
There's no point is passing in the answer; the answer is what you want to receive. (There's also no point in passing "space" for the answer. The anser is a float, a scalar variable. Just pass that around.) Remove the answer argument.
You redefine answer as local variable. After removing the argument of the same name, that redefinition goes away. But in that case you should return answer instead of 0. You could even do without the intermediary variable answer and return the result expression. So: Return the desired expression
The answer depends on two global variables. The function should work on two angles that you pass as arguments. Provide two angle arguments to your function and remove the global variables.
And finally, the sum of the three angles in a triangle is 180°, so your remaining angle calculation is wrong.
Putting all that together:
float remainingAngle(float a, float b)
{
return 180.0f - a - b;
}
and call it like this:
float angleC = remainingAngle(angleA, angleB);
Im used to java
I'm not too familiar with Java, but I don't think functios on scalars like this one are fundamentally different in C and Java.

Error in calling function

While compiling this code in the terminal, I am getting an error saying :
newfile1.c:17: error: conflicting types for ‘average’
newfile1.c:2: note: previous declaration of ‘average’ was here
I don't see what is wrong with the code. Could someone help me out?
enter code here
#include<stdio.h>
float average(float);
int main()
{
float marks[4],avg;
int i;
printf("Please enter your marks\n");
for(i=0;i<=3;i++)
{
scanf("%d",&marks[i]);
}
avg = average(marks[4]);
printf("The average marks value is %f",avg);
return 0;
}
float average(float a[4])
{
int i,sum;
float avg_m;
for(i=0;i<=3;i++)
{
sum=sum+a[i];
}
avg_m=sum/3;
return avg_m;
}
Replace
float average(float);
with
float average(float[]);
The function declaration and definition are not matching.
Then call the function like this:
avg = average(marks);
Change line in your file
float average(float);
to
float average(float []);
You have declared the function to take one float instead you want array of floats.
Also, while calling it in main, change to
avg = average(marks);
float average(float);
expects a float variable . You need to pass an array , so add
float average(float[]);. Error happened since your function declaration and definition not matching.
in your main, you should call avg = average(marks); to pass the array to function avg = average(marks[4]); will pass a single variable.
In the prototype of average, you have given float as argument type so compiler is expecting a single float value as argument. If you want to pass an array of values, you have to declare your prototype like this:
float average(float input_marks[]);
You can't give length of an array argument in a prototype or definition. You have to pass array length as a separate argument. So your prototype should look something like
float average(float a[], int a_length);
Your function average takes one float as argument, hence the declaration should be floa avaerage(float). If you do float average(float a[4]) you are telling compiler that your function takes an array of 4 floats as argument.

Resources