I'm VERY new to programming, and I'm using a book to help me write some code that will solve ln(1+x) after the user inputs "x". My syntax is exactly the way the book has it in its example but I keep getting an error: expected expression before 'long' on line 28. Line 28 is the line that reads long double y = LOG(1+(x));.
#include <stdio.h>
#include <math.h>
#define LOG(X) _Generic((X),\
long double: log(1+(x))\
)
int main()
{
double x;
printf("Please enter a number from -1 to +1: ");
scanf("%f", &x);
long double y = LOG(1+(x));
printf("From C math library: ln(1+x) = %f\n", y);
}
Firstly, your generic macro is written for long double type. You supplied a double argument x. long double and double are two different types. You did not define a generic branch for double, which means that your macro will not compile for a double argument. Either change the type of x to long double or make your generic macro support double arguments.
Also, this is a very strange way to write a LOG macro. Why are you explicitly using 1 + (x) as log argument inside the macro? What if tomorrow you'll want to calculate LOG(2 + y)? Your macro will still insist on calculating log(1 + (x)) instead, which does not make any sense at all. A more sensible thing to do would be to just pass X to log
#define LOG(X) _Generic((X),\
long double: log(X)\
)
Secondly, in order to scanf a double value you need %lf format specifier. %f is for float. To printf a long double value you need %Lf format.
If you are new to programming, and trying to make an example work, I would not use macros at this stage but focus on the function and the data type. Start with a double which is the typical working type of the library interfaced by math.h. My example shows how to calculate the natural ln with the log() function.
As others have commented, scanf() needs a format specifier of %lf for a double, however printf() only needs the format specifier of %f for a double. Note that I have tested the return value from scanf() function as well as the number you input, to check that the input was well behaved.
Lastly, you invite numbers in the range -1 <= x <= 1 yet ln(0) is undefined, hence I have restricted the input range to exclude -1.
#include <stdio.h>
#include <math.h>
int main(void)
{
double x = 0, y;
printf("Please enter a number from -1 to +1: ");
if (1 != scanf("%lf", &x) || x <= -1 || x > 1) {
printf("I need -1 < number <= +1\n");
return 1;
}
y = log(x + 1);
printf("From C math library: ln(1+x) = %f\n", y);
return 0;
}
Here are some sample outputs:
Please enter a number from -1 to +1: -1
I need -1 < number <= +1
Please enter a number from -1 to +1: 0
From C math library: ln(1+x) = 0.000000
Please enter a number from -1 to +1: 1
From C math library: ln(1+x) = 0.693147
Related
Here is my code, when using print statements it appeared to be an infinite loop:
some potential issues i can troubleshoot are integer division, and perhaps figuring out if the algorithm terminates, and if it always has the correct output, perhaps there is some idiosyncrasy of the C language that I do not understand causing this issue?
From my understanding as the sum tends to negative infinity it will cause the break statement to be triggered ending the algorithm once it reaches an approximation of epsilon precision.
#include <stdio.h>
int main()
{
double pi, sum, epsilon;
long long i=1;
long long max = 2147483647;
printf("Pleas enter the desired accuracy epsilon : ");
scanf("%f", &epsilon);
while (i<max){
if (i%2 == 0){
sum = -4.0/(2.0*i-1);
}else if (i%2 ==1){
sum = (4.0/(2.0*i-1));
}
if (sum < epsilon){
break;
}
pi += sum;
}
printf("The value of pi approximated to epsion : %f is %f\n", epsilon, pi);
return 0;
}
You are not increment the value of i in your while loop. As a result its value always remains 1.
Increment i after your processing is done before the closing } of the while loop.
Initialize the values of pi, sum, epsilon so that you do not run into undefined behavior when you try to read their values for the first time.
Also, with proper options enabled (-Wall with GCC) the compiler will warn you, that you are trying to read a float into a double.
warning: format '%f' expects argument of type 'float *', but argument 2 has type 'double *' [-Wformat=]
scanf("%f", &epsilon);
~^ ~~~~~~~~
So you have to use the correct conversion specifier: %lf instead of %f in your scanf statement.
If you are not very particular about the number 2147483647 and just want a large value, you can also use ULLONG_MAX (from limits.h) to initialize max instead of hard-coding the value.
You need to increment i value in while loop.
Your looping condition while(i < max) is always satisfied (infinite loop). So the value of i or max should be changed inside the loop to ever end the loop.
Your code has undefined behavior:
scanf("%f", &epsilon);
scanf %f takes a float *, not double *. The correct format for double * is %lf.
Your loop condition while (i<max) is equivalent to while (1) as neither i nor max change their value inside the loop.
This also means sum is always 4:
sum = (4.0/(2.0*i-1));
// 4 / (2 * 1 - 1) = 4 / (2 - 1) = 4 / 1 = 4
pi += sum;
also has undefined behavior: pi is uninitialized.
Given this code that my professor gave us in an exam which means we cannot modify the code nor use function from other libraries (except stdio.h):
float x;
(suppose x NOT having an integer part)
while (CONDITION){
x = x*10
}
I have to find the condition that makes sure that x has no valid number to the right of decimal point not giving attention to the problems of precision of a float number (After the decimal point we have to have only zeros). I tried this condition:
while ((fmod((x*10),10))){
X = X*10
}
printf(" %f ",x);
example:
INPUT x=0.456; --------> OUTPUT: 456.000
INPUT X=0.4567;--------> OUTPUT; 4567.000
It is important to be sure that after the decimal point we don't have any
significant number
But I had to include math.h library BUT my professor doesn't allow us to use it in this specific case (I'm not even allowed to use (long) since we never seen it in class).
So what is the condition that solve the problem properly without this library?
As pointed out here previously:Due to the accuracy of floats this is not really possible but I think your Prof wants to get something like
while (x - (int)x != 0 )
or
while (x - (int)x >= 0.00000001 )
You can get rid of the zeroes by using the g modifier instead of f:
printf(" %g \n",x);
There is fuzziness ("not giving attention to the problems of precision of a float number") in the question, yet I think a sought answer is below, assign x to an integer type until x no longer has a fractional part.
Success of this method depends on INT_MIN <= x <= INT_MAX. This is expected when the number of bits in the significant of float does not exceed the value bits of int. Although this is common, it is not specified by C. As an alternative, code could with a wider integer type like long long with a far less chance of the range restriction issue.
Given the rounding introduced with *10, this method is not a good foundation of float to text conversion.
float Dipok(float x) {
int i;
while ((i=x) != x) {
x = x*10;
}
return x;
}
#include <assert.h>
#include <stdio.h>
#include <float.h>
void Dipok_test(float x) {
// suppose x NOT having an integer part
assert(x > -1.0 && x < 1.0);
float y = Dipok(x);
printf("x:%.*f y:%.f\n", FLT_DECIMAL_DIG, x, y);
}
int main(void) {
Dipok_test(0.456);
Dipok_test(0.4567);
return 0;
}
Output
x:0.456000000 y:456
x:0.456699997 y:4567
As already pointed out by 2501, this is just not possible.
Floats are not accurate. Depending on your platform, the float value for 0.001 is represented as something like 0.0010000001 in fact.
What would you expect the code to calculate: 10000001 or 1?
Any solution will work for some values only.
I try to answer to my exam question please if I say something wrong correct me!
It is not possible to find a proper condition that makes sure that there are no valid number after the decimal point. For example : We want to know the result of 0.4*20 which is 8.000 BUT due to imprecision problems the output will be different:
f=0.4;
for(i=1;i<20;i++)
f=f+0.4;
printf("The number f=0.4*20 is ");
if(f!=8.0) {printf(" not ");}
printf(" %f ",8.0);
printf("The real answer is f=0.4*20= %f",f);
Our OUTPUT will be:
The number f=0.4*20 is not 8.000000
The real answer is f=0.4*20= 8.000001
I am in an introductory C programming class. Our latest project has us writing code to tabulate x and sqrt(x) values from 1-10 with a 0.1 step using a while loop. When I try to do the 0.1 increment, however, nothing is added to the starting integer 1 and the program runs in an infinite loop. I'll post the code below. Other than it not doing the step, the program runs fine (and works with other increments like 1, etc.). How do I resolve this?
#include <stdio.h>
#include <math.h>
int main(void)
{
int x=1;
double sq_rt;
printf("Square Root Table: \n");
printf("Value of X Square Root of X\n");
while (x <= 10)
{
sq_rt = sqrt (x);
printf("%6i %20f \n", x, sq_rt);
x += 1e-1;
}
return 0;
}
An int type will only allow you to store whole numbers (i.e. -2, -1, 0, 1, 2 etc). To store numbers with a decimal point, you'll need a double precision (or double) type. Change the first line of main() to:
double x = 1.0;
If you try to add 1e-1 to an int, it will convert it to an int first - the type of x - which when truncated will end up being zero, so you'll never actually add anything to x.
The line in your program which reads
x += 1e-1;
is performing operations equivalent to
x = (int)(((double)x) + 0.1);
In other words, x is first converted to a double, then 0.1 is added to it, resulting in 1.1. This value is then converted to int, resulting in a value of 1, which is assigned to x.
The fix is to change the type of x to a floating point type such as float or double.
Share and enjoy.
the following code is a suggestion on how to perform the desired algorithm.
#include <stdio.h>
#include <math.h>
// define the magic numbers, don't embed them in the code
#define UPPER_LIMIT (10.0)
#define STEP_SIZE (0.1)
int main(void)
{
double x=1.0;
double sq_rt;
printf("Square Root Table: \n");
printf("Value of X Square Root of X\n");
// due to ambiguities in 'real' values,
// this loop will iterate approx. 90 times.
while( x < UPPER_LIMIT )
{
sq_rt = sqrt (x);
// display the two double values
// note: long float conversion values
// because the underlying numbers are double
// note: blanks for alignment with column headers
printf("%9.6lf %16.13lf \n", x, sq_rt);
// increase base value by increment of 0.1
x += STEP_SIZE;
} // end while
return 0;
} // end function: main
First my context is that of a compiler writer who needs to convert floating point literals (strings) into float/double values. I haven't done any floating point programming the last 15 years so i'm pretty sure this is a total stupid newbie question.
double res;
errno=0;
*res = strtod((const char*)literal,NULL);
if (errno==ERANGE) throw_a_literal_out_of_range_exception();
return res;
but there is no "strtof" function in the c runtime library?
EDIT: To clarify. I already know that the string 'literal' is a valid pattern for a C floating point. It already passed a regular expression test. I just want to check if there is a range/precision problem.
The reason is in Eiffel source code a user can write
a := {REAL_32} 3.1415
b := {REAL_32} 3.0E200
To cast a written floating point number explit to a 32bit floating point. I think in the second case the compiler should detect that the value is out of range and raise an error or at least a warning.
In C89 you may use sscanf.
For example:
float myfloat;
if(sscanf(str, "%f", &myfloat) != 1)
/* String could not be converted */
else
/* String was converted, myfloat is usable */
#Nicholas Goy:
I don't think sscanf(str, "%f, &float) == 1 (or != 1) really does what's desired.
If there are additional characters in str (e.g. "1.1foo"), it will parse without error, which is probably undesirable. This can be rectified by doing:
char dummy;
if (sscanf(str, "%f%c", &float, &dummy) != 1) {
/* Parse error. */
} else {
/* Parsed cleanly. */
}
instead. However, sscanf with %f is likely to use strtod internally and cast to float anyway. The language in the C standard says:
a,e,f,g Matches an optionally signed floating-point number, infinity, or NaN, whose
format is the same as expected for the subject sequence of the strtod
function. The corresponding argument shall be a pointer to floating.
which sort of implies this, and it seems to be true for me (gcc 4.2.1 on FreeBSD). Using the above sscanf code, "1.79e308" parses successfully but has the value +inf, as does "5e-300" with the value 0.0, and these are the same results you'd get from (float) 1.79e308 and (float) 5e-300.
Anyway. All that said, I question why the OP wants to use float instead of double anyway.
I was going to say, simply use the code you already have, but assign the result of strod() to a float instead of a double. But your code is wrong in several ways.
Firstly, you cannot test errno unless an error has ocurred. Secondly, strtod() will not set errno except for things like range errors. If you pass it an invalid number, like "XYZ", it will not be set.
More correct use of strtod is:
char *p;
double d = strtod( "123.4xyz", & p );
if ( * p != 0 ) {
// not a number - in this case will point at 'x'
}
Using strtod() to read a float, you may lose some precision, but that's the price you pay for using floats - in general, unless you have a very good reason not to, you should always prefer the use of double to float.
strtof does not exist in C89, but it does in C99.
I suggest converting to double first, then cast to float. If the relative difference, (f-d)/f, is greater than float precision (roughly, 1e-7) then there are more digits than what can be safely stored in float.
Since you have your value in a double, you can just check if it's outside of the range of float:
#include <stdlib.h>
#include <stdio.h>
#include <float.h>
int main(int argc, char *argv[])
{
double d = FLT_MAX;
if (argc > 1) {
d = strtod(argv[1], NULL);
}
if ((d > 0 && (d > FLT_MAX || d < FLT_MIN))
|| (d < 0 && (d < -FLT_MAX || d > -FLT_MIN)))
printf("Invalid float: %g\n", d);
else
printf("Valid: %g\n", d);
return EXIT_SUCCESS;
}
Running the program:
$ ./a.out
Valid: 3.40282e+38
$ ./a.out 3.5e38
Invalid float: 3.5e+38
$ ./a.out -1e40
Invalid float: -1e+40
You may or may not need to add a test for correct strtod() return, depending upon whether there's a possibility of an overflow in double type as well.
On MSVC you can use _atoflt(), defined in stdlib.h
This always results in 0 for me and I don't know why...
Other examples on internet generally cause of division.
in Codeblocks same code results normally but in Atom I have this problem.
please help.
#include <stdio.h>
#include <conio.h>
#define PI 3.14
int main() {
float r,a,c;
printf("enter radius: \n");
scanf("%.2f",&r);
c = r * PI * 2;
a = r * r * PI;
printf("area:%.2f circumference:%.2f \n",c,a );
return 0;
}
C11 7.21.6.2p3 says the following of fscanf et al:
3 [...] Each conversion specification is introduced
by the character %. After the %, the following appear in sequence:
An optional assignment-suppressing character *.
An optional decimal integer greater than zero that specifies the maximum field width (in characters).
An optional length modifier that specifies the size of the receiving object.
A conversion specifier character that specifies the type of conversion to be applied.
The length modifier means the extra letter(s) such as l in %lf meaning double. Notice that while %2f would be valid and would mean that only to 2 characters of input can be consumed, it is nowhere said that you can write %.2f, i.e. %.2f is an invalid conversion specification, and hence the behaviour is undefined (C11 7.2.6.2p13).
If there's no reason you want to use %.2f to scan, just using %f will work
#include <stdio.h>
#include <conio.h>
#define PI 3.14
int main() {
float r,a,c;
printf("enter radius: \n");
scanf("%f",&r);
c = r * PI * 2;
a = r * r * PI;
printf("area:%.2f circumference:%.2f \n",c,a );
return 0;
}
Example:
daniel#daniel-FX503VM:~/Documents/test$ ./zero
enter radius:
1
area:6.28 circumference:3.14
The .2 in the printf is a printing format specifier, and shouldn't have an impact on a scanf
Where you're putting the .2 in the scanf is actually the width field,which specifies the maximum number of characters to be read in the current reading operation (optionally). However, in this context, .2 characters as a width is not a meaningful sentiment, seeing as the width is required to be an integer.
If what you're actually trying to do is only read 2 characters, you could say
scanf("%2f", &r);
But be warned that the '.' would also count as a character.If you specifically just want the output to be two decimal places, then the proposed code above should suffice. If you want to round it internally, I'd suggest you read this post