How to stop rounding decimals with double in c - c

I know this problem has been on the internet for a while but i cant seem to find how to stop my program from rounding the 3rd decimal.
the answer output is 4524.370 and should be 4524.369
also, i know my equations are stupid and could be simplified but im lazy
//Tanner Oelke CSE155E
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main(void){
double v, t; //base variables
double sq1, sq2; //calculation variable for square root
printf("Please enter the given air temperature in Fahrenheit:");
scanf("%lf", &t);
//unessecary equations but it works
sq1=(57*t+297);
sq2=(sq1/247);
v=1086*sqrt(sq2);
printf("%.3lf\n", v);
return 0;
}

With an input of "70.0" the result is 4524.369754... which displays as "4524.370" - What OP gets.
With an input of "69.999975" the result is 4524.369002... which displays as "4524.369" - what OP wants.
If OP expects "70.0" to result in "4524.369", then some minor adjustment to the formula is needed. The precision of double is at least 10 significant digits and often is 15+. Even doing this in float then f(70.0)--> 4524.370.
Else OP has the wrong expectation.
Response to OP's comment:
"to shorten the decimal place to 3 spots without rounding". Hmmm seems strange to want this:
// properly rounded result
printf("%.3lf\n", v);
// shorten to 3 places without rounding
double v3 = floor(v*1000.0)/1000.0;
printf("%.3lf\n", v3);

Related

How to detect if a number is a whole number or a float in C? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
So I am new to C, and I mainly use it to make calculators for probability and stuff like that. My current project finds the increase and decrease of 2 values.
The code is:
#include <stdio.h>
//Variables
//Main Area
int
main ()
{
float num1;
float num2;
float num3;
float num4;
float answer;
//Scanning for the first number
printf ("\n Please Enter the first Value : ");
scanf ("%f", &num1);
//scanning for the second number
printf ("\n Please Enter the second Value : ");
scanf ("%f", &num2);
//calculating
num3 = num1 - num2;
num4 = num3 / num1;
answer = num4 * 100;
//Checking if the answer is an increase or decrease
if (answer > 0) {
printf("The answer has been decreasedby: %f\n", answer);
printf("percent");
}
else {
printf("The answer has been increased by: %f\n", answer * -1);
printf("percent");
}
//Printing the answer
}
The output:
Please Enter the first Value: 9
Please Enter the second Value : 90
The answer has been increased and the final value is: 900.000000
percent
So I set all the values as Floats rather than Ints because Ints only support whole numbers. But when I do get a whole number rather then displaying only the single number with no decimal points, it produces a number with the number and a bunch of zeros after the decimal point. Is there a way to detect if the number Is a whole number and just display that number?
Thanks
Is there a way I can detect if the answer is a whole number and only display that number?
To detect if float is a whole number, use modff() to break a float into its whole number and fractional parts.
float f;
float ipart;
float fpart = modff(f, &ipart);
printf("%g is %s whole number.\n", f, fpart == 0.0 ? "a" : "not a");
An alternative to detecting "whole-ness", use "%g" to print floating point numbers with reduced output.
printf("%g\n", 2.0/3.0); // 0.666667
printf("%g\n", 1234.0); // 1234
Perhaps a step further with "%g". Use a precision wide enough to show any non-zero digits to the right of the . and let the specifier lop off the trailing zeros when the answer is a whole number.
printf("%.*g\n", FLT_DECIMAL_DIG, some_float);
printf("%.*g\n", DBL_DECIMAL_DIG, some_double);
Compare answer to the return value of f.e. the floorf() function (header math.h) - floorf() since you dealing with a variable of type float - with answer passed as argument.
By doing so, you proof if answer contains an even decimal value.
For the output itself, Use a precision specifier (f.e. .0) which specifies the amount of digits in the fraction part and place it between the % and the f conversion specifier, For example %.0f.
The precision of .0 specifies that you want to display no fraction part.
// Checking if the answer is an increase or decrease
if ( answer > 0 ) {
if ( answer == floorf(answer) ) // If answer contains a decimal value.
printf("The answer has been decreased and the final value is: %.0f\n", answer);
else
printf("The answer has been decreased and the final value is: %.3f\n", answer);
}
else {
if ( answer == floorf(answer) ) // If answer contains a decimal value.
printf("The answer has been increased and the final value is: %.0f\n", answer * -1);
else
printf("The answer has been increased and the final value is: %.3f\n", answer * -1);
}
Side Notes:
Note that floating-point often does not provide expected results:
Is floating point math broken?
So, it is possible that even this technique will not work at each and every use case.
Always check the return value of input functions such as scanf() if an input error occurred.
I used floorf(), but ceilf(), truncf() or roundf() could also be used to achieve the same effect.
int main() is deprecated. Use int main(void) instead which declares a full prototype for main().
Since answer will be negative when reaching the else body, printing answer * -1 will output a positive value, since - * - = +. Maybe this is not intended, so this just as a hint.
My way of checking involves :
if(num1 == (int)num1) // This checks whether num1 is integer
{
//Do something
}
else
{
//num1 is float
}

Why do my lines rotate in a peculiar fashion?

I am trying to design a fan and make the lines rotate using C language.
This is my code:
#include<stdio.h>
#include<graphics.h>
#include<math.h>
void main(){
int gd=DETECT,gm=0,xr,yr,xr1,yr1,xr2,yr2,x,y,x1,y1,x2,y2;
int x3,y3,i;
float rad;
initgraph(&gd,&gm,"C:\\TURBOC3\\BGI");
x=getmaxx()/2;
y=getmaxy()/2;
printf("x1 and y1:");
scanf("%d %d",&x1,&y1);
printf("x2 and y2:");
scanf("%d %d",&x2,&y2);
printf("x3 and y3:");
scanf("%d %d",&x3,&y3);
printf("\n\n");
setcolor(RED);
line(x,y,x1,y1);
line(x,y,x2,y1);
line(x,y,x3,y3);
rad=toRadians(1);
for(i=0;i<60;i++){
xr=x+((x1-x)*cos(0.017)-(y1-y)*sin(0.017));
yr=y+((x1-x)*sin(0.017)+(y1-y)*cos(0.017));
xr1=x+((x2-x)*cos(0.017)-(y2-y)*sin(0.017));
yr1=y+((x2-x)*sin(0.017)+(y2-y)*cos(0.017));
xr2=x+((x3-x)*cos(0.017)-(y3-y)*sin(0.017));
yr2=y+((x3-x)*sin(0.017)+(y3-y)*cos(0.017));
setcolor(RED);
line(x,y,xr,yr);
line(x,y,xr1,yr1);
line(x,y,xr2,yr2);
x1=xr;
y1=yr;
x2=xr1;
y2=yr1;
x3=xr2;
y3=yr2;
delay(500);
cleardevice();
}
getch();
closegraph();
}
The problem is that the lines don't rotate in a synchronized way. It's like one line is rotating, then after some time the second line starts rotating and so on. Can anyone please help me?
Depending on your compiler, you might see a warning like this:
'=': conversion from 'double' to 'int', possible loss of data
This is pretty much telling you what's going on. You declared your coordinates as int but the trigonometric functions produce double. Very small ones to be precise. int is just not able to capture these small changes and will throw away any digit after the decimal point as soon as you do the assignment to xr etc.
To solve this, simply declare your variables as double. You can then convert these to int before passing them to line(). But you keep your calculations in double precision:
line((int)round(x), (int)round(y), (int)round(xr), (int)round(yr));
...
Another way that circumvents this problem is to increase the angle and calculate the rotated directions from the original values as 3Dave suggested in the comments.
The main take-away message here is: Do not ignore warnings that your compiler gives you.

How to fix C function giving wrong summation values

I have made a simple addition function, but getting wrong summation values, sorry if it is a naive thing to look for. But really want to know why is this happening. I want an alternative solution for this. Thanks in advance!
I am using notepad++ to write the code, and gcc compiler in the windows command prompt to execute the code.
#include <stdlib.h>
#include <stdio.h>
float addit(float num1, float num2)
{
float sumit;
sumit = num1 + num2;
return sumit;
}
int main()
{
float num1, num2;
float answer = 0.000000;
printf("Enter first number: ");
scanf("%f", &num1);
printf("Enter second number: ");
scanf("%f", &num2);
answer = addit(num1, num2);
printf("The summation is: %f", answer);
return 0;
}
The expected output of the addition of 2345.34 and 432.666 is 2778.006.
But, after execution it shows 2778.006104.
Windows cmd window showing execution result as 2778.006104
Welcome to the wonderful world of floating point values! Consider this: between 0 and 1, there are infinitely many numbers. There's 0.1, and there's 0.01, and there's 0.001, and so on. But computers do not have infinite space, so how are we supposed to store numbers? Our solution was to limit the precision of the numbers we stored. As others have mentioned, java's float data type only has 6 or 7 digits of accuracy (in base 10). Because of this, you cannot necessarily guarantee that the result of a mathematical operation on floats will be 100% accurate. You can only be sure that the first 6-7 digits of the result will be.

C: with power function converting binary to decimal

I am trying to convert decimal number to binary number using recursion.
But I am getting wrong output...I tried to debug the program and got stuck with "pow()".
I inserted many printf statements to see the status of the variables...
Here is my program...
#include<stdio.h>
#include<conio.h>
#include<math.h>
void main(){
int n,k;
int z;
long b,j;
long binary(int,int);
printf("Enter a Number : ");
scanf("%d",&n);
printf("Binary Equivalent is : ");
k=log2(n);
b=binary(n,k);
z=pow(10,k);
printf("\n\nb=%d ,z=%d",b,z);
}
long binary(int n,int c)
{
int a,np;
static long b=0;
if(n<=1){
b=(n%2)*(int)pow(10,c)+b;
printf("\n nmod2=%d\nb=%ld\nc=%d\nn=%d ",(n%2),b,c,n);
return b;
}
else{
a=n%2;
np=pow(10,c);
b=a*np+b;
printf("\n a=%d,np=%d \n nmod2=%d \n b=%ld \n c=%d \n n=%d ",a,np,(n%2),b,c,n);
binary(n/2,--c);
}
}
Output is:
Enter a Number : 5
Binary Equivalent is :
a=1,np=99
nmod2=1
b=99
c=2
n=5
a=0,np=10
nmod2=0
b=99
c=1
n=2
nmod2=1
b=100
c=0
n=1
b=100 ,z=100
why the "pow(10,c)" in binary() when c=2 equals 99 why not 100 as in main()?
The problem is here:
(int)pow(10,c)
The result is around 100, but rounding it down with (int) can get you either 99 or 100 depending on the roundoff error of pow.
This is a handy function lround in math.h that should help you. It rounds a number towards the closest integer, rounding 0.5 towards zero.
Alternatively, you could define:
int my_round(double f) {
return (int)(f+0.5);
}
Adding 0.5 and rounding down looks like rounding to the closest integer.
The pow() function is a floating-point function, which tends to screw up such stuff. You shouldn't use it for integers without proper rounding to compensate.
Multiple problems.
As others have point out that the result of pow(10,c) is the problem. A good pow() would return exactly 100.0 for pow(10,2). It is reasonable to expect that behavior from pow(), but a cautious programmer would do as others suggest and round-to-nearest a floating point number to an int.
Round to nearest is best handle with a library function. Should one want to roll your own:
int IRound(double f) { return (f > 0.0) ? (int)(f + 0.5) : (int)(f - 0.5); }
long binary(int n,int c) does not return a value when n > 1. Suspect return binary(n/2,--c) is wanted.
The static long b=0; is a bad way to deal with recursion. long binary(int n,int c) would nominally correctly run only once. A second call, b would not necessarily start at 0.
Given pow() is flaky, log2() may need special care too.

Incorrect formula?

So here is a program that is supposed to calculate an approximation to the value of pi if you take enough terms into the sum which is mathematically described in the following program and calculates the expression of the root, you get a value that gets closer and closer to the value of pi the more terms you have.
#include <stdio.h>
#include <math.h>
main()
{
int j, terms;
double sum, precision, pi;
printf("How many terms: "); scanf("%d", &terms);
for(j=1;j<=terms;j++)
sum+=1/(j*j);
pi = sqrt(6*sum);
printf("Pi: %lf.\n", pi);
}
But there is something making it go wrong here and I can't quite figure out what.
sum+=1/(j*j);
I thought the mistake might be in that line because all others look fine,thinking at first maybe the computer isn't counting decimals.I'm unsure.But my question is: What is it in this code that makes it malfunction?And how do I fix it?
This performs integer division:
1/(j*j);
try this:
sum+=1.0/(j*j);
If j*j might overflow, do this
sum+=1.0/((double)j*j);

Resources