C Language scientific notation problems [duplicate] - c

This question already has answers here:
strange output in comparison of float with float literal
(8 answers)
Closed 7 years ago.
I have the following program:
float x = 3.e17;
printf("x = %f", x);
which gives the result:
x = 299999995292024832.000000
why is the result not 300000000000000000.000000?

#include <stdio.h>
#include <stdlib.h>
union
{
double d;
float f;
unsigned int ui[2];
} myun;
int main ( void )
{
float fx = 3.e17;
double dx = 3.e17;
printf("fx %f\n",fx);
printf("dx %lf\n",dx);
myun.f=fx;
printf("fx 0x%08X\n",myun.ui[0]);
myun.ui[0]++;
printf("fx %lf\n",myun.f);
myun.d=dx;
printf("dx 0x%08X 0x%08X\n",myun.ui[1],myun.ui[0]);
return(0);
}
(yes this is an incorrect/invalid way to use a union but it just happened to work)
fx 299999995292024832.000000
dx 300000000000000000.000000
fx 0x5C853A0D
fx 300000029651763200.000000
dx 0x4390A741 0xA4627800
wikipedia points out that single can handle up to 9 digits without a loss of precision and double 15-17. So right there is your answer, didnt necessarily need to do an experiment.

Because of limited float precision. Use double for more precision, but floating point is not always exact

Related

Problem with float and int multiplication in C [duplicate]

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;
}

Not sure how to deal with repeating decimals in C [duplicate]

This question already has answers here:
C program to convert Fahrenheit to Celsius always prints zero
(6 answers)
Closed 2 years ago.
int number = round(2/3);
printf("%i", number);
the output is
0
I expected to get 1 as 0.6 recurring should round up - i know for sure that the problem is with recurring decimals as they are always rounded down - I'm not sure how to round up in this kind of scenario.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main(void) {
double number = round(2.0/3.0);
printf("%0.f", number);
}
Output = 1
You can use double or float for rounding numbers
Without floating point calculations, the following will round to nearest using just integer division:
int a = 2;
int number = (a + 1) / 3; // = 1
In general, rounding a / b to the nearest integer is equivalent to truncating (a + b / 2) / b.
use double or float number. in definition and in printf
#include <stdio.h>
int main(void)
{
double number = (double)2/3;
printf("%.f", number);
}

Division of double and float in c [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 years ago.
i believe that double have x2 precision of float .
in my calculator 10/3 is 3.3333333333333333333333333333333
when i do the following code :
#include <stdlib.h>
#include <stdio.h>
void main() {
double var = (double )10 / (double )3;
float var2 = (float )10 / (float )3;
printf("%f %f \n" , var , var2 );
}
i get the same number of digits after 3, :
3.3333333333333335 3.3333332538604736
why do i get the same number of digits? and why the value is different ? and how to do a division for double and float and get all the numbers and digits in c (like in my calculator) ?
By default printf will only print a limited number of digits. On my system it's 6 digits. On your system it seems to be 16 digits.
To print more digits do:
printf("%.60f \n%.60f \n" , var , var2 );
Output:
3.333333333333333481363069950020872056484222412109375000000000
3.333333253860473632812500000000000000000000000000000000000000
As you can see neither float nor double can print
3.333333333333333333333333333333333333333333333333333333333333
but - obviously - double is closer than float.
BTW: It's not void main() {. It shall be int main(void) {

comparing a #define constant with a variable of same value does not equal (C language) [duplicate]

This question already has answers here:
strange output in comparison of float with float literal
(8 answers)
Closed 4 years ago.
I am new to C language. Here is my question and code:
I have a constant and a variable with the same value and I try to compare them to check if they are equal. It seems to me that since they are assigned the same value, they should be equal but that is not the case.
#include <stdio.h>
#define mypi1 3.14
int main()
{
int ans;
float mypi2 = 3.14;
if(mypi1==mypi2)
{
ans=1;
}
else
{
ans=0;
}
printf("%i",ans);
return 0;
}
My output is 0. Which indicates they are not equal. What is the reasoning behind this? This is a really simple question but I could not find it anywhere. Please help and thanks in advance.
#define mypi1 3.14
float mypi2 = 3.14;
The first of those is a double type, the second is a double coerced into a float.
The expression mypi1==mypi2 will first convert the float back to a double before comparing (the idea is that, if one type is of lesser range/precision than the other, it's converted so that both types are identical).
Hence, if the if statement is failing, it's likely that you lose information in the double -> float -> double round-trip(a).
To be honest, unless you're using a great many floating point values (and storage space is a concern), you should probably just use double everywhere. If you do need float types, use that for both values:
#define mypi1 3.14f
float mypi2 = 3.14f;
Comparing two float variables will not involve any conversions.
(a) See, for example, the following complete program:
#include <stdio.h>
#define x 3.14
int main(void) {
float y = 3.14; // double -> float
double z = y; // -> double
printf("%.50f\n", x);
printf("%.50f\n", z);
}
In this, x is a double and z is a double that's gone through the round-trip conversion discussed above. The output shows the difference that can happen:
3.14000000000000012434497875801753252744674682617188
3.14000010490417480468750000000000000000000000000000

Floating Point Representation in C [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 4 years ago.
I'm not sure how floating point are represented in C, and how much of a precision someone could get.
In a c source file, I have the macro:
#define NUMBER 123.367
In the main function there are these 2 instructions:
float x = NUMBER;
printf("x is %f\n", x);
When I run it, I get:
x is 123.366997
Which is quite close to 123.367, but it kinda messes the purpose of the program.
Is there any way to round up x to the desired value? Or is this a flaw of floating point arithmetic-representation that can't be fixed?
You should use a double, not a float.
#include <stdio.h>
#define NUMBER 123.367
int main (void) {
float f = NUMBER;
double d = NUMBER;
printf("f is %f\n", f);
printf("d is %f\n", d);
return 0;
}
This will give you:
f is 123.366997
d is 123.367000
'double' uses 53 bits for precision, while a 'float' only uses 24.

Resources