C - long double and printf issue - c

I am new C programmer and I am working on a school project where I have to approximate the value or pi. My professor stated that we have to declare all integer terms using long double. The console shows me asking the user for the number of terms to approximate pi given a function. I enter 1 for the number of terms however the code returns -0.00000000 instead of 4.00000000.
#include <stdio.h>
#include <math.h>
long double approx1(int terms)
{
long double pi = 0;
long double num = 4;
long double denom = 1;
int i;
for(i=1; i <= terms; i++)
{
if(i%2 != 0)
{
pi=pi+(num/denom);
}
else
{
pi=pi-(num/denom);
}
denom = denom + 2;
}
printf("%.8Lf\n", pi);
}
int main()
{
int terms;
long double pie;
printf("input number of terms, input 0 to cancel\n");
scanf("%d", &terms);
while(terms != 0)
{
if(terms > 0)
{
pie = approx1(terms);
printf("%.8Lf\n", pie);
printf("GG mate\n");
break;
}
else
{
printf("Incorrect input, please enter a correct input\n");
scanf("%d", &terms);
}
}
}
I haven't had any success in getting it to work( it works with float though). What am I doing wrong? (I am using Code Blocks with the included compiler btw.)

You forgot to add a return statement in your approx1() function. Withoout that return statement, if you make use of the returned value, it invokes undefined behavior.
Quoting C11 standard, chapter §6.9.1
If the } that terminates a function is reached, and the value of the function call is used by
the caller, the behavior is undefined.

Related

Exiting a loop when a non-double input is typed

Basically the title, I am in a beginners C++ class and am trying to do an assignment but have been having trouble learning without the hands on teaching due to covid. I am trying to sum and average numbers using a while loop, but have it stop when a character or string is entered instead of a double. I think all of my code except the conditionals work, any help would be greatly appreciated.
#include <stdio.h>
int main(int argc, const char* argv[])
{
double userNum, numSum, numAvg;
int i; //iterations for calculating average
userNum = 0.0;
numSum = 0.0;
numAvg = 0.0;
i = 0;
while (1)
{
if (1) {
printf("Enter a score (or stop to quit):\n");
scanf("%lf", &userNum);
}
else // I thought this would break the loop if any nun double value was entered but I was wrong?
{
break;
}
numSum = numSum + userNum;
i++;
}
if (i == 0) // if no ittereations done, gives no sum message
{
printf("No sum and average calculated!");
}
else
{
// otherwise calculates and prints sum and avg
}
{
numAvg = numSum / i;
printf("The sum is: %0.2lf, average is: %0.2lf", numSum, numAvg);
}
return 0;
}
if(1) is redundant and by adding it, you are never going to reach else.
It is equivalent to if (1 != 0) which is always true.
You can achieve what you are asking by checking the return value of scanf(). You can modify your code like so:
while (1)
{
printf("Enter a score (or stop to quit):\n");
if (scanf("%lf", &userNum) != 1) // should return 1 if 1 double is read
{
break;
}
numSum = numSum + userNum;
i++;
}
For large inputs, I would suggests that you switch to fgets() and later parse the string with sscanf(). scanf() doesn't provide any protection from arithmetic overflow, which is undefined behavior.

Pointers and functions for calculating the squareroot of a number in C

Currently working on an school assignment that requires us to write a program that takes user input. As long as the input is positive the squareroot should be calculated, but if the input is negative the squareroot should not be calculated and the program shall print out a message telling the user that its not possible to calculate the squareroot if a negative number.
Quote from the assignment:
"If ​number​ is non-negative, the function should calculate the square root and place theresult in the pointer argument and return the value 1.If ​number​ is negative the function should ​not​ calculate the square root at all, but insteadonly return the value 0."
Here is what i have so far, but when ever I've entered a number the program just shuts down as if it's finished the task but it does not print out anything, help is appriciated. (First programming course i take)
#include <stdio.h>
#include <math.h>
void squareRoot(float number1, float *squareroot)
{
if (number1 > 0)
{
*squareroot = sqrt(number1);
return 1;
}
else if (number1 < 0)
{
return 0;
}
}
int main(void)
{
float n1;
printf("Enter a number to calculate the squareroot of the number: ");
scanf_s("%f", &n1);
float squareRootResult;
squareRoot(n1, &squareRootResult);
if (squareRoot == 1)
{
printf("The squareroot of the entered number is: %f", squareRootResult);
}
else if (squareRoot == 0)
{
printf("It is not possible to calculate thesquare root of a negative number​");
}
return 0;
}
There are many problems in here, starting with:
You declared the function squareRoot to return void (ie: nothing).
Then you try to return integers:
{ ...return 1;.... return 0; }
Ask yourself how a function that returns nothing should return an int of 1 or 0.
Fixup:
// Change return value to int
int squareRoot(float number1, float *squareroot)
{ [....] }
int main(void)
{
[...]
// Declare a variable to hold the return value.
int retValue;
float squareRootResult;
// Put the return value in variable retValue
retValue = squareRoot(n1, &squareRootResult);
// Check the value that was returned!
if (retValue == 1)
{
printf("The squareroot of the entered number is: %f", squareRootResult);
}
else if (retValue == 0)
{
printf("It is not possible to calculate thesquare root of a negative number​");
}
squareRoot is the address of the function, not any particular return value of the function. Didn't your compiler warn of you of this in any way? The fact that it apparently compiles a void function with integral return values is a concern too. Perhaps now might be a good time to (i) see if you can get the compiler to warn you of such things, or (ii) convince your school to upgrade to a newer one. Like love and nature, excellent C compilers are available for free.
The address of the function is not allowed to be 0 by the C standard (ignore this technicality for now), and it's very likely not 1 either, hence neither if statement conditional evaluates to 1, and this accounts for the lack of output.
Your best bet is to perform the validation check on the input n1 before attempting to evaluate the square root. Don't forget to check the return value of scanf_s too - it should be 1 if a float value was read successfully from standard input.
You're not checking the right thing:
squareRoot(n1, &squareRootResult);
if (squareRoot == 1)
{
printf("The squareroot of the entered number is: %f", squareRootResult);
}
else if (squareRoot == 0)
{
printf("It is not possible to calculate thesquare root of a negative number​");
}
squareRoot is the actual function, not the return value. What you're actually doing is checking if the function's pointer is 1 or 0.
You need to assign the return value of the function a another variable and check that.
int rval = squareRoot(n1, &squareRootResult);
if (rval == 1)
{
printf("The squareroot of the entered number is: %f", squareRootResult);
}
else if (rval == 0)
{
printf("It is not possible to calculate thesquare root of a negative number​");
}
Also, you need to change the definition of squareRoot:
void squareRoot(float number1, float *squareroot)
In the function you attempt to return a value but the function is declared to not return anything. You need to set the return type to int:
int squareRoot(float number1, float *squareroot)
Finally, your squareRoot function doesn't handle the case where number1 is 0 and will fail to return a value. This can be fixed by changing this:
if (number1 > 0)
To:
if (number1 >= 0)

Why do I get an endless loop from my code?

#include <stdio.h>
int main() {
int num;
int square;
int sum;
while (num) {
if (num > 0) {
scanf("%d", &num);
square = num * num;
sum = square + sum;
printf("%d \n", sum);
}
}
return 0;
I'm trying to produce the sum of squares for positive numbers, and when the first negative number is inputted, the loop ends. Result needs to be left justified by 10 spaces.
The code has undefined behavior: the first time you test the value of num, it is uninitialized. If by chance it happens to not be negative, you scan a new value and add its square to uninitialized variable sum, producing more undefined behavior, it the value input was negative, the next test fails and the loop repeats forever.
Left justifying in a 10 space width is obtained with the %-10d conversion format.
Here is a corrected version:
#include <stdio.h>
int main(void) {
int num, square, sum = 0;
while (scanf("%d", &num) == 1 && num != 0) {
square = num * num;
sum = square + sum;
printf("%-10d\n", sum);
}
return 0;
}
If you want the number to be right justified in a 10 space width so all output values align properly, use the %10d format instead.
If you input large numbers or too many items, you will eventually exceed the range of type int. You can try and increase the range of variables square and sum by making them long long int or even as commented by PeterJ unsigned long long int, and allow for larger values to be computed:
int main(void) {
int num;
unsigned long long square, sum = 0;
while (scanf("%d", &num) == 1 && num != 0) {
square = (long long)num * num;
sum = square + sum;
printf("%21llu\n", sum);
}
return 0;
}
Note that (long long)num * num will be converted to unsigned long long that has a range at least as large in the positive values.
Using uninitialized variable leads to undefined behavior.You are using uninitialized local variable num in your while loop. num can have any value in it. If the value is smaller than 0 the loop will run forever. It will also loop for ever if the value smaller than 0 is entered using scanf.
For undefined behavior please check lines from standard
6.3.2.1 Lvalues, arrays, and function designators
If the lvalue designates an object of automatic storage duration that
could have been declared with the register storage class (never had
its address taken), and that object is uninitialized (not declared
with an initializer and no assignment to it has been performed prior
to use), the behavior is undefined.
I hope, this might help ending the loop
#include <stdio.h>
int main() {
int num = 0;
int sum = 0;
while (num >= 0) {
scanf("%d", &num);
if (num>=0) {
sum = ( num * num ) + sum;
printf(" %d\n", sum);
}
}
return 0;
}

Why is float in c not working the way it should?

I was trying to do the codechef question - https://www.codechef.com/problems/FLOW009
Here, my code (submitted successfully )is this -
int main(void) {
int testCases;
scanf ("%d\n", &testCases);
while (testCases--) {
float q,p;
scanf ("%f%f", &q,&p);
if (q >= 1000){
printf("%.6f\n",q*p - (q*p*0.1));
}
else{
printf("%.6f\n", q*p);
}
}
return 0;
}
This was submitted successfully... But however when i tried this code -
int main(void) {
int testCases;
scanf ("%d\n", &testCases);
while (testCases--) {
float q,p;
scanf ("%f%f", &q,&p);
if (q >= 1000){
float a = q*p - (q*p*0.1);
printf("%.6f\n",a);
}
else{
printf("%.6f\n", q*p);
}
}
return 0;
}
It said wrong answer. In my compiler the results are same for all the test cases. What is happening. The first code- i am just printing the value.
In the second - i am using a variable to store the value.
PS - i tried typecasting the value also but with no result.
Converting a value from double to float and back does not guarantee the same result.
In
printf("%.6f\n", q*p - (q*p*0.1));
the values are all converted to type double and the calculation is done in double. The result, of type double, is sent directly to printf.
In the other case with the float variable, the values are converted to double, the calculation is done in double then converted to float for the assignment. That value is converted to double before being passed on to printf.
Always use double for floating point variables.

How do I go through a certain number and extract digits smaller than 5 using a recursive function?

it's me again. I deleted my previous question because it was very poorly asked and I didn't even include any code (i'm new at this site, and new at C). So I need to write a program that prints out the digits smaller than 5 out of a given number, and the number of the digits.
For example: 5427891 should be 421 - 3
The assignment also states that i need to print the numbers smaller than 5 in a recursive function, using void.
This is what I've written so far
#include<stdio.h>
void countNum(int n){
//no idea how to start here
}
int main()
{
int num, count = 0;
scanf("%d", &num);
while(num != 0){
num /= 10;
++count;
}
printf(" - %d\n", count);
}
I've written the main function that counts the number of digits, the idea is that i'll assign (not sure i'm using the right word here) the num integer to CountNum to count the number of digits in the result. However, this is where I got stuck. I don't know how to extract and print the digits <5 in my void function. Any tips?
Edit:
I've tried a different method (without using void and starting all over again), but now i get the digits I need, except in reverse. For example, instead of printing out 1324 i get 4231.
Here is the code
#include <stdio.h>
int rec(int num){
if (num==0) {
return 0;
}
int dg=0;
if(num%10<5){
printf("%d", num%10);
dg++;
}
return rec(num/10);
}
int main(){
int n;
scanf("%d", &n);
int i,a;
for(i=0;i<n;i++)
{
scanf("%d", &a);
rec(a);
printf(" \n");
}
return 0;
}
Why is this happening and how should I fix it?
There is nothing in your question that specifies the digits being input are part of an actual int. Rather, its just a sequence of chars that happen to (hopefully) be somewhere in { 0..9 } and in so being, represent some non-bounded number.
That said, you can send as many digit-chars as you like to the following, be it one or a million, makes no difference. As soon as a non-digit or EOF from stdin is encountered, the algorithm will unwind and accumulate the total you seek.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int countDigitsLessThanFive()
{
int c = fgetc(stdin);
if (c == EOF || !isdigit((unsigned char)c))
return 0;
if (c < '5')
{
fputc(c, stdout);
return 1 + countDigitsLessThanFive();
}
return countDigitsLessThanFive();
}
int main()
{
printf(" - %d\n", countDigitsLessThanFive());
return EXIT_SUCCESS;
}
Sample Input/Output
1239872462934800192830823978492387428012983
1232423400123023423420123 - 25
12398724629348001928308239784923874280129831239872462934800192830823978492387428012983
12324234001230234234201231232423400123023423420123 - 50
I somewhat suspect this is not what you're looking for, but I'll leave it here long enough to have you take a peek before dropping it. This algorithm is fairly pointless for a useful demonstration of recursion, to be honest, but at least demonstrates recursion none-the-less.
Modified to print values from most significant to least.
Use the remainder operator %.
"The result of the / operator is the quotient from the division of the first operand by the second; the result of the % operator is the remainder. In both operations, if the value of the second operand is zero, the behavior is undefined" C11dr §6.5.5
On each recursion, find the least significant digit and test it. then divide the number by 10 and recurse if needed. Print this value, if any, after the recursive call.
static int PrintSmallDigit_r(int num) {
int count = 0;
int digit = abs(num % 10);
num /= 10;
if (num) {
count = PrintSmallDigit_r(num);
}
if (digit < 5) {
count++;
putc(digit + '0', stdout);
}
return count;
}
void PrintSmallDigits(int num) {
printf(" - %d\n", PrintSmallDigit_r(num));
}
int main(void) {
PrintSmallDigits(5427891);
PrintSmallDigits(-5427891);
PrintSmallDigits(0);
return 0;
}
Output
421 - 3
421 - 3
0 - 1
Notes:
This approach works for 0 and negative numbers.
First of all, what you wrote is not a recursion. The idea is that the function will call itself with the less number of digits every time until it'll check them all.
Here is a snippet which might help you to understand the idea:
int countNum(int val)
{
if(!val) return 0;
return countNum(val/10) + ((val % 10) < 5);
}
void countNum(int n, int *c){
if(n != 0){
int num = n % 10;
countNum(n / 10, c);
if(num < 5){
printf("%d", num);
++*c;
}
}
}
int main(){
int num, count = 0;
scanf("%d", &num);
countNum(num, &count);
printf(" - %d\n", count);
return 0;
}
for UPDATE
int rec(int num){
if (num==0) {
return 0;
}
int dg;
dg = rec(num/10);//The order in which you call.
if(num%10<5){
printf("%d", num%10);
dg++;
}
return dg;
}
int main(){
int n;
scanf("%d", &n);
int i,a;
for(i=0;i<n;i++){
scanf("%d", &a);
printf(" - %d\n", rec(a));
}
return 0;
}

Resources