programming C using xcode, here's the f
#include <stdio.h>
int multiply (int x, int y) {
return x * y;
}
int main()
{
float result = (float) multiply (0.2, 0.5);
printf("the result is %f", result);
}
I don't get the right value, I get 0.0000 !! I did the casting but I don't know whats wrong.
Your program multiplies 0 by 0.
multiply takes two int parameters, so your 0.2 and 0.5 are implicitly converted to int before making the call. That truncates both to 0.
Your typecast doesn't do anything in this program, since the return value of multiply (which is an int) will get implicitly converted during the assignment to result anyway.
You need to change the definition of multiply (or add a floating-point version and call that) if you want this program to work correctly.
The multiply () input arguments are int:
int multiply (int x, int y) {
and you have passed float as input arguments:
multiply (0.2, 0.5);
Hi there is a basic problem. As the numbers you are multiplying are floats but you are passing these into the function multiply as int's hence being rounded to 1 and 0.
This should work
#include <stdio.h>
int multiply (float x, float y) {
return x * y;
}
int main()
{
float result = (float) multiply (0.2, 0.5);
printf("the result is %f", result);
}
Related
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 months ago.
I'm using the online compiler https://www.onlinegdb.com/ and in the following code when I multiply 2.1 with 100 the output becomes 209 instead of 210.
#include<stdio.h>
#include <stdint.h>
int main()
{
float x = 1.8;
x = x + 0.3;
int coefficient = 100;
printf("x: %2f\n", x);
uint16_t y = (uint16_t)(x * coefficient);
printf("y: %d\n", y);
return 0;
}
Where am I doing wrong? And what should I do to obtain 210?
I tried to all different type casts still doesn't work.
The following assumes the compiler uses IEEE-754 binary32 and binary64 for float and double, which is overwhelmingly common.
float x = 1.8;
Since 1.8 is a double constant, the compiler converts 1.8 to the nearest double value, 1.8000000000000000444089209850062616169452667236328125. Then, to assign it to the float x, it converts that to the nearest float value, 1.7999999523162841796875.
x = x + 0.3;
The compiler converts 0.3 to the nearest double value, 0.299999999999999988897769753748434595763683319091796875. Then it adds x and that value using double arithmetic, which produces 2.09999995231628400205181605997495353221893310546875.
Then, to assign that to x, it converts it to the nearest float value, 2.099999904632568359375.
uint16_t y = (uint16_t)(x * coefficient);
Since x is float and coefficient is int, the compiler converts the coefficient to float and performs the multiplication using float arithmetic. This produces 209.9999847412109375.
Then the conversion to uint16_t truncates the number, producing 209.
One way to get 210 instead is to use uint16_t y = lroundf(x * coefficient);. (lroundf is declared in <math.h>.) However, to determine what the right way is, you should explain what these numbers are and why you are doing this arithmetic with them.
Floating point numbers are not exact, when you add 1.8 + 0.3,
the FPU might generate a slightly different result from the expected 2.1 (by margin smaller then float Epsilon)
read more about floating-point numbers representation in wiki https://en.wikipedia.org/wiki/Machine_epsilon
what happens to you is:
1.8 + 0.3 = 209.09999999...
then you truncate it to int resulting in 209
you might find this question also relevant to you Why float.Epsilon and not zero? might be
#include<stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main()
{
float x = 1.8;
x = x + 0.3;
uint16_t coefficient = 100;
printf("x: %2f\n", x);
uint16_t y = round(x * coefficient);
printf("y: %" PRIu16 "\n", y);
return 0;
}
Here is my code:
#include <stdio.h>
#include <math.h>
double Mul(double X,double Y,double Z)
{
Y=Y*pow(10,6);
Y=Y+Z;
X=(X*pow(10,12))+Y;
//X=114360000000000000+117239051145;
//X=Y;
return X;
}
int main()
{
double Hello=Mul(114360,117239,511432);
printf("%f",Hello);
return 0;
}
The output should be "114360117239511432" but I got "114360117239511424" I need to know why 511432 converts to 511424? and How can I solve this problem?
I suggest to get familiar with floating point inaccuracy. However you use decimal numbers as parameters, they are not integers. If you want to know more of the integer limits, please check the numeric limits.
Let me be more specific. Double type become inaccurate if the exponent other than 1. I modified a bit your code, to show what are the exact values.
double Mul(double X, double Y, double Z)
{
double YbutMore = Y * pow(10, 6);
// YbutMore = 117239000000.00000
double YandZ = YbutMore + Z;
// YandZ = 117239511432.00000
double Xpow12 = X * pow(10, 12);
// Xpow12 = 1.1436000000000000e+17
return Xpow12 + Y;
// returns 1.1436000000011723e+17
}
So it all begins when we do a X * pow(10, 12). The mantissa cannot hold this big number, so the exponent will be other than 1 that will cause the inaccuracy. Don't forget to check the double value memory model.
If you are intrested how to store accurate and large numbers, please see How to store extremely large numbers?
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
When I execute this code it returns me 1610612736
void main(){
float a=3.3f;
int b=2;
printf("%d",a*b);
}
Why and how to fix this ?
edit : It's not even a matter of integer and float, if i replace int b=2: by float b=2.0f it return the same silly result
The result of the multiplication of a float and an int is a float. Besides that, it will get promoted to double when passing to printf. You need a %a, %e, %f or %g format. The %d format is used to print int types.
Editorial note: The return value of main should be int. Here's a fixed program:
#include <stdio.h>
int main(void)
{
float a = 3.3f;
int b = 2;
printf("%a\n", a * b);
printf("%e\n", a * b);
printf("%f\n", a * b);
printf("%g\n", a * b);
return 0;
}
and its output:
$ ./example
0x1.a66666p+2
6.600000e+00
6.600000
6.6
Alternately, you could also do
printf("%d\n", (int)(a*b));
and this would print the result you're (kind of) expecting.
You should always explicitly typecast the variables to match the format string, otherwise you could see some weird values printed.
Is there a function to round a float in C or do I need to write my own?
float conver = 45.592346543;
I would like to round the actual value to one decimal place, conver = 45.6.
As Rob mentioned, you probably just want to print the float to 1 decimal place. In this case, you can do something like the following:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float conver = 45.592346543;
printf("conver is %0.1f\n",conver);
return 0;
}
If you want to actually round the stored value, that's a little more complicated. For one, your one-decimal-place representation will rarely have an exact analog in floating-point. If you just want to get as close as possible, something like this might do the trick:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float conver = 45.592346543;
printf("conver is %0.1f\n",conver);
conver = conver*10.0f;
conver = (conver > (floor(conver)+0.5f)) ? ceil(conver) : floor(conver);
conver = conver/10.0f;
//If you're using C99 or better, rather than ANSI C/C89/C90, the following will also work.
//conver = roundf(conver*10.0f)/10.0f;
printf("conver is now %f\n",conver);
return 0;
}
I doubt this second example is what you're looking for, but I included it for completeness. If you do require representing your numbers in this way internally, and not just on output, consider using a fixed-point representation instead.
Sure, you can use roundf(). If you want to round to one decimal, then you could do something like: roundf(10 * x) / 10
#include <math.h>
double round(double x);
float roundf(float x);
Don't forget to link with -lm. See also ceil(), floor() and trunc().
Just to generalize Rob's answer a little, if you're not doing it on output, you can still use the same interface with sprintf().
I think there is another way to do it, though. You can try ceil() and floor() to round up and down. A nice trick is to add 0.5, so anything over 0.5 rounds up but anything under it rounds down. ceil() and floor() only work on doubles though.
EDIT: Also, for floats, you can use truncf() to truncate floats. The same +0.5 trick should work to do accurate rounding.
To print a rounded value, #Matt J well answers the question.
float x = 45.592346543;
printf("%0.1f\n", x); // 45.6
As most floating point (FP) is binary based, exact rounding to one decimal place is not possible when the mathematically correct answer is x.1, x.2, ....
To convert the FP number to the nearest 0.1 is another matter.
Overflow: Approaches that first scale by 10 (or 100, 1000, etc) may overflow for large x.
float round_tenth1(float x) {
x = x * 10.0f;
...
}
Double rounding: Adding 0.5f and then using floorf(x*10.0f + 0.5f)/10.0 returns the wrong result when the intermediate sum x*10.0f + 0.5f rounds up to a new integer.
// Fails to round 838860.4375 correctly, comes up with 838860.5
// 0.4499999880790710449 fails as it rounds to 0.5
float round_tenth2(float x) {
if (x < 0.0) {
return ceilf(x*10.0f + 0.5f)/10.0f;
}
return floorf(x*10.0f + 0.5f)/10.0f;
}
Casting to int has the obvious problem when float x is much greater than INT_MAX.
Using roundf() and family, available in <math.h> is the best approach.
float round_tenthA(float x) {
double x10 = 10.0 * x;
return (float) (round(x10)/10.0);
}
To avoid using double, simply test if the number needs rounding.
float round_tenthB(float x) {
const float limit = 1.0/FLT_EPSILON;
if (fabsf(x) < limit) {
return roundf(x*10.0f)/10.0f;
}
return x;
}
There is a round() function, also fround(), which will round to the nearest integer expressed as a double. But that is not what you want.
I had the same problem and wrote this:
#include <math.h>
double db_round(double value, int nsig)
/* ===============
**
** Rounds double <value> to <nsig> significant figures. Always rounds
** away from zero, so -2.6 to 1 sig fig will become -3.0.
**
** <nsig> should be in the range 1 - 15
*/
{
double a, b;
long long i;
int neg = 0;
if(!value) return value;
if(value < 0.0)
{
value = -value;
neg = 1;
}
i = nsig - log10(value);
if(i) a = pow(10.0, (double)i);
else a = 1.0;
b = value * a;
i = b + 0.5;
value = i / a;
return neg ? -value : value;
}
you can use #define round(a) (int) (a+0.5) as macro
so whenever you write round(1.6) it returns 2 and whenever you write round(1.3) it return 1.