I want to get 998 / 999 = 0.998, but I get 0.999.
Can you help me?
#include <stdio.h>
#include <math.h>
int main() {
float a,b,c;
float d,e,f;
scanf("%f", &a);
d= a / 999;
scanf("%f", &b);
e= b / 999;
scanf("%f", &c);
f= c / 999;
printf("%.3f...\n", d);
printf("%.3f...\n", e);
printf("%.3f...\n", f);
}
The result is 0.99899899... so rounding it to 3 decimals should yield 0.999 and your program does that correctly.
If your intention is to round down with 3 decimals, then you must tell the program to do that instead. For that, you can use the floor function included in the math library you're using:
floor(998.0/999.0*1000)/1000;
Notwithstanding the fact that 998 / 999 is 0.998999...9, if you want to truncate on the 3rd significant figure, then one way is to write, from C99 onwards
truncf(998.f / 999 * 1000) / 1000;
or
floorf(998.f / 999 * 1000) / 1000;
You might find that the second way is more likely to be available pre-C99, if not then use say (long) in place of floorf, and replace the final division with 1000.f.
These can introduce joke digits from about the 7th significant figure, but the formatting choice you already use will obviate that.
Related
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
const double TAX = 0.13;
double small = 17.96;
double subTotal = small * 6;
double taxes = subTotal * TAX;
printf("j SubTotal: %9.4lf Tax: %9.4lf \n", (double)subTotal, (double)taxes);
return 0;
}
The required output is
SubTotal: 107.7600 Tax: 14.0100 should come out.
My output is:
SubTotal: 107.7600 Tax: 14.0088
What should I do?
The solution is to not ever use floating point types for currency.
If you have a decimal type available, use it.
If you don't, write one.
Or, at a minimum, use long integers to store cents.
If you want to round to two decimal places, multiply by one hundred add one half, truncate to an int and then divide by one hundred. Like,
double round(double v) {
return ((int)(v * 100 + .5)) / 100.;
}
Then you can call that like
double taxes = round(subTotal * TAX);
And I get (with no other changes)
j SubTotal: 107.7600 Tax: 14.0100
C provides useful rounding functions rint(), round(), nearby(), llround() that well handle rounding corner cases.
To round to the nearest 100th, scale the value by /100.0, round and scale back.
#include <math.h>
double value = ...;
value *= 100.0;
value = round(value); // or rint(), nearby()
value /= 100.0;
At this point, value may not exactly be of the form ddd.dd but will be the closest double to that form. Printing with "%.4f" will then print to the closest 0.0001.
printf("%9.4lf\n", value);
Alternatively, take money and round to the smallest monetary unit - suppose OP wants to the nearest cent (0.01).
long long value_cents = llround(value * 100.0);
printf("%lld.%02d00", amount / 100, abs(amount % 100));
It’s a weird requirement to display four decimal places while rounding to two, but you can satisfy it by displaying two decimal places and hard-coding the characters 00 after it:
printf("j SubTotal: %9.2f00 Tax: %9.2f00 \n", subTotal, taxes);
Do not use floating point numbers for currency because they are tricky and inexact in many cases. Here is a working solution that gives you the exact output you want, but you should know it is strange to print more than two digits after the decimal point if those extra digits are always zero.
The + 99 in the code below is the trick you need to make the calculation always round up, instead of rounding down which is the normal behavior of unsigned integer division.
#include <stdio.h>
#include <stdint.h>
void print_money_with_strange_format(uint64_t amount)
{
printf("%llu.%02llu00", amount / 100, amount % 100);
}
int main(void)
{
uint64_t tax_rate = 13;
uint64_t small = 1796;
uint64_t subtotal = small * 6;
uint64_t tax = (subtotal * tax_rate + 99) / 100;
printf("SubTotal: ");
print_money_with_strange_format(subtotal);
printf(" Tax: ");
print_money_with_strange_format(tax);
printf("\n");
}
If you want to round the output to two decimals, but still producing four on output, just use
printf("%9.2f00", value);
and the value will be rounded to two decimals, and two zeros will be appended to it. But, why the computer should round 88 to 100 in a calculation, when you have not commanded it to round numbers at some place?
To round a number when the first decimal is over .5, you can just add 0.5 and then truncate the result. In case you want to do it at some position, just multiply the number by the required power of ten (in this case 100) and after the truncation, divide it again by that power(100), as proposed by other answers.
I tried searching this up on Stack Overflow but couldn't find an answer.
Here is the code:
#include <stdio.h>
int main(void) {
double y;
printf("Enter a number: ");
scanf("%lf", &y);
printf("Your number when rounded is: %.2lf", y);
//If user inputs 5.05286, how can i round off this number so as to get the output as 5.00
//I want the output to be rounded as well as to be 2 decimal places like 10.6789 becomes 11.00
return 0;
}
I want to round a number, for example, if the number is 5.05286, it should be rounded to 5.00, and if it is 5.678901, it will be rounded to 6.00 with 2decimal places. The number 5.678901 is getting rounded to 5.05 but it should round to 5. I am aware that I can use floor() and ceil(), but I don't think I will be able to round off the answer without conditional statements, which is not the scope of my C knowledge. I also tried to use the round() function but it doesn't round at all.
You need to import <math.h> header :
#include <math.h> //don't forget to import this !
double a;
a = round(5.05286); //will be rounded to 5.00
This function has analog definitions for every type, which means that you can pass the following types and it'll be rounded to the nearest for every one of them :
double round(double a);
float roundf(float a);
long double roundl(long double a);
If you don't want to use any additional header:
float x = 5.65286;
x = (int)(x+0.5);
printf("%.2f",x);
I am a real beginner here and I'm really not sure about this. It is a homework assignment.
We have to find 10 (x,y) coordinates of an arc using the radius, a starting angle and an end angle. The program works, but the results it gives differ very slightly from the 'correct' results as required by the automatic checking system. Here's the code and both mine and the systems results based on r=100, angle1=1, anglef=30!
Thanks in advance!
FILE *pf1;
int n=0;
double angulo1, angulof, angulo, radio, x, y;
printf ("\nIntroduce radio : ");
scanf ("%lf", &radio);
printf ("\nIntroduce angulo inicial : ");
scanf ("%lf", &angulo1);
printf ("\nIntroduce angulo final : ");
scanf ("%lf", &angulof);
angulo = ((angulof-angulo1)/9);
pf1 = fopen("salida.txt", "w");
for (n=0; n<=9; n++)
{
x=radio*cos(angulo1+(angulo*n));
y=radio*sin(angulo1+(angulo*n));
fprintf (pf1, "%lf,%lf\n", x,y);
}
return 0;
.
ERROR
■■■ MY FILE:
54.030231,84.147098
-41.614684,90.929743
-98.999250,14.112001
-65.364362,-75.680250
28.366219,-95.892427
96.017029,-27.941550
75.390225,65.698660
-14.550003,98.935825
-91.113026,41.211849
-83.907153,-54.402111
■■■ CORRECT FILE:
54.030231,84.147095
-41.614685,90.929741
-98.999252,14.112000
-65.364365,-75.680252
28.366219,-95.892426
96.017029,-27.941549
75.390228,65.698662
-14.550003,98.935822
-91.113029,41.211849
-83.907150,-54.402111
The post is very confusing:
Calculating angles from 1 to 30 radians in 10 steps doesn't make much sense. Sensible values for radians are from -2π to +2π, outside that range trigonomic functions quickly lose precision. Also, making steps that are much larger than a few degrees is very unusual. To get from 1 to 30 radians in 10 steps, steps of almost 180° are taken.
Some testing of the output reveals that the steps are smaller: from 1 to 10 radians in 10 steps. This is still 57° per step, and goes almost 2 times around the circle.
Reverse engineering the output with atan2(y,x) reveals that the desired output is less precise than the calculation with doubles. So, probably the calculations used 32 bit floats. To test this, one has to be very careful. Internally, floats can get passed as doubles, and the processor works with 80 bits of precision for arithmetic calculations. (Note that on most machines long double has the same precision as double.)
Now, if you call sin on a float, the compiler often calls the double version of sin. To force the float version, one can try to explicitly call them, they have an f appended to the function name: sinf and cosf.
Testing the following with MicroSoft Visual C, 2017 community edition:
#include <math.h>
void test_sinf()
{
float radio = 100;
float angulo1 = 1;
float angulof = 10;
float angulo = (angulof - angulo1) / 9;
float x, y;
int n;
for (n = 0; n < 10; ++n) {
x = radio * cosf(angulo1 + (angulo*n));
y = radio * sinf(angulo1 + (angulo*n));
printf("%.6lf,%.6lf\n", x, y);
}
}
outputs:
54.030228, 84.147095
-41.614685, 90.929741
-98.999252, 14.112000
-65.364365, -75.680252
28.366220, -95.892426
96.017029, -27.941549
75.390228, 65.698662
-14.550003, 98.935822
-91.113022, 41.211849
-83.907150, -54.402115
This leaves the last digit of only 4 of the numbers with a difference. Which suggests a slightly different library/compiler has been used. As the angles and the radius are all integer numbers which can be represented exact with floats, they are an unprobable cause of the differences.
edit: Testing out the suggestion of #gnasher729 is seems he's right. Running the code with the double precision sin and cos, and convering the result to float before printing, gives exactly the "desired" numbers. This probably gives the same results on most compilers for this test case. (32 bit floats are an IEEE standard, and 64 bit trigonomic functions have enough precision to make implementation details disappear after rounding.)
#include <math.h>
void test_sin_converted_to_float()
{
float radio = 100;
float angulo1 = 1;
float angulof = 10;
float angulo = (angulof - angulo1) / 9;
float x, y;
for (int n = 0; n <= 9; ++n) {
x = radio * cos(angulo1 + (angulo*n));
y = radio * sin(angulo1 + (angulo*n));
printf("%.6lf, %.6lf\n", x, y);
}
}
Checking your data with a spreadsheet, it contains exactly what it ought to contain. The data in the second file however look like sine and cosine where calculated with single precision (float).
Which would mean that whoever created this "automatic checking" should be very, very, ashamed of themselves.
Example (in C):
#include<stdio.h>
int main()
{
int a, b = 999;
float c = 0.0;
scanf("%d", &a);
c = (float)a/b;
printf("%.3lf...", c);
return 0;
}
If I put 998 it will come out 0.999, but I want the result be 0.998; how?
It looks like you want to truncate instead of round.
The mathematical result of 999/998 is 0.9989989989... Rounded to three decimal places, that is 0.999. So if you use %.3f to print it, that's what you're going to get.
When you convert a floating-point number to integer in C, the fractional part is truncated. So if you had the number 998.9989989 and you converted it to an int, you'd get 998. So you can get the result you want by multiplying by 1000, truncating to an int, and dividing by 1000 again:
c = c * 1000;
c = (int)c;
c = c / 1000;
Or you could shorten that to
c = (int)(c * 1000) / 1000.;
This will work fine for problems such as 998/999 ≈ 0.998, but you're close to the edge of where type float's limited precision will start introducing its own rounding issues. Using double would be a better choice. (Type float's limited precision almost always introduces issues.)
In my quest to learn C I've come across a task which is causing me a few problems. I need to make an equation for the approximate value of the formulae n!, which can be described as:
n! = n^n*e^(-n)*sqrt(2(2*n+1/3)*PI), however I simply cannot get my values to corrospond with the actual value. 5! = 120ish
I can get a value of some 148ish
Can't figure out where my code is wrong:
#include <stdio.h>
#include <math.h>
#define PI 3.14156
#define E_CONST 2.7828
int main ()
{
double num;
double calc, first, second, third, fourth;
printf("Give an int: ");
scanf("%lf", &num);
first = pow(num , num);
second = pow(E_CONST, -num);
third = (2 * num + 1/3);
fourth = sqrt(2*third*PI);
//calc = first * second * fourth;
calc = pow(num, num) * pow(E_CONST, -num) * sqrt(2*(2*num+(1/3))*PI);
printf("Input: %f", num);
printf("1: %.2f\n2: %.10f\n3: %.8f\n4: %.2f\n", first, second, third, fourth);
printf("\nInt was: %.2f\n\nApproximate number: %.5f", num, calc);
return 0;
}
Feel like i have tried everything. The code is a bit messy, but it's because I've scrambled so much with it now.
3.14156 is a bad value for PI: it's better to use 3.1416, or 3.14159, or 4 * atan(1), or, for POSIX implementations, M_PI.
2.7828 is a very bad value for e: it's better to use 2.7183, or exp(1), or, for POSIX implementations, M_E.
1/3 is integer division, the result is 0: it's better to use 1.0/3.
Also your approximation is incorrect. The correct approximation is
n^n * e^(-n) * sqrt((2*n+1/3)*PI)
It seems you fell into the integer division trap with 1/3, which has the value 0. You need to write this with floating point constants as 1.0 / 3.0.
You probably need to type 1.0/3.0 to get one third.