For loops goes on forever [duplicate] - c++

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 5 years ago.
Somehow, when I run this program, it'll go on forever even though I wrote it in a way that makes it stop when i reaches 10. Please help.
double i;
for(i = 0; i != 10; i+= 0.1){
printf("%.1f\n", i);
}

0.1 cannot be represented accurately as double.
A quick fix is to change the loop condition into i < 10.
Otherwise use loop variable of an integer type, a fixed precision float, or whatever else.
Note, however, that with other decimal increments, notably the negative powers of 2 (0.5, 0.25, etc.), it might work, provided the overall iteration count is not too high.

Related

How I can solve C++ output negative numbers when using modulo? [duplicate]

This question already has answers here:
Fastest way to get a positive modulo in C/C++
(9 answers)
How to code a modulo (%) operator in C/C++/Obj-C that handles negative numbers
(16 answers)
Closed 2 years ago.
In a code written by me, I have used both below functions to calculate mod of displayed negative number.
fmod(-10,11)
(-10, 11)
Though the correct answer is 1. It always displays the answer -10 in c++. How I can solve it?
From cppreference.com:
double fmod (double numer, double denom);
The floating-point remainder of the division operation x/y calculated by this function is exactly the value x - n*y, where n is x/y with its fractional part truncated.
The returned value has the same sign as x and is less than y in magnitude.
In your case it is -10 - (-10)/11 * 11 = -10 - 0 * 11 = -10, which is correct for that implementation of fmod. If you need another answer, you should implement your own version, as modulo is defined in different ways for negative numbers.

problem in using 'double' data type in for loops with fractional incrementation [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
I had a program which requires one to search values from -100.00 to +100.00 with incrementation of 0.01 inside a for loop. But the if conditions arent working properly even if code is correct...
As an example I tried printing a small section i.e if(i==1.5){cout<<"yes...";}
it was not working even though the code was attaining the value i=1.5, i verified that by printing each of the values too.
#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
double i;
for(i=-1.00; i<1.00; i=i+0.01)
{
if(i>-0.04 && i<0.04)
{
cout<<i;
if(i==0.01)
cout<<"->yes ";
else
cout<<"->no ";
}
}
return 0;
}
Output:
-0.04->no -0.03->no -0.02->no -0.02->no -0.01->no 7.5287e-016->no 0.01->no 0.02->no 0.03->no
Process returned 0 (0x0) execution time : 1.391
(notice that 0.01 is being attained but still it prints 'no')
(also notice that 0.04 is being printed even if it wasn't instructed to do so)
use this if(abs(i - 0.01) < 0.00000000001) instead.
double - double precision floating point type. Usually IEEE-754 64 bit
floating point type
The crux of the problem is that numbers are represented in this format as a whole number times a power of two; rational numbers (such as 0.01, which is 1/100) whose denominator is not a power of two cannot be exactly represented.
In simple word, if the number can't be represented by a sum of 1/(2^n) you don't have the exact number you want to use. So to compare two double numbers calculate the absolute difference between them and use a tolerance value e.g. 0.00000000001 .
Doubles are stored in binary format. To cut things short fractional part is written as binary. Now let's imagine it's size is 1 bit. So you've two possible values (for fraction only): .0 and .5. With two bits you have: .0 .25 .5 .75. With three bits: .125 .25 .375 .5 .625 .75 .875. And so on. But you'll never get 0.1. So what computer does? It cheats. It lies to you, that 0.1 you see is 0.1. While it more looks like 0.1000000000000000002 or something like this. Why it looks like 0.1? Because formatting of floating point values has long standing tradition of rounding numbers, so 0.10000000000001 becomes 0.1. As a result 0.1 * 10 won't equal 1.0.
Correct solution is to avoid floating point numbers, unless you don't care for precision. If your program breaks, once your floating point value "changes" by miniscule amount, then you need to find another way. In your case using non-fractional values will be enough:
for(auto ii=-100; ii<100; ++ii)
{
if(ii>-4 && ii<4)
{
cout << (ii / 100.0);
if(ii==1)
cout<<"->yes ";
else
cout<<"->no ";
}
}

Why does "double i = 1/12;" yields to i = 0? [duplicate]

This question already has answers here:
Why does dividing two int not yield the right value when assigned to double?
(10 answers)
Closed 5 years ago.
I think the title says everything. I want to define a variable i as the fraction 1/12. However, i is 0.
double i = 1/12;
std::cout << i; // Output: 0
Or, more specific, I want to calculate a power of something:
im_ = std::pow((1 + i), (1/12)) - 1;
However, the compile evaluates (1/12) as 0 and thus the result is wrong.
Simple because 1/12 is evaluated as integer math, not floating point math.
1/12 becomes 0 because integer math does not take into account the decimal fractions.
To get the expected result you will need to write down the numbers as a floating point literal, like this: 1.0/12.0.
More details can be found here: Why can't I return a double from two ints being divided

visual studio 2010 showing weird behavior on float/double increment [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Dealing with accuracy problems in floating-point numbers
I am writing an OpenGl animation and am using a float variable "time" to keep track of the time.
I am incrementing the "time" variable by 0.01 .I have certain conditions to fulfil whenever "time" reaches an integer value.The issue is that after a certain time the float increment shows weird behavior.
I start from time = 0 and I see that after "time" reaches 0.83 the next value is 0.839999.
I though this could be related to float precision so I tried using double/long double and I found that instead of reaching the value 1.00 the code is reaching the value 1.0000007.
I tried incrementing by "0.01f" instead of "0.01" but got no success.
Is this some bug in Visual Studio or am I doing it the wrong way?
I could post the code but I don't think it's of much use as I am assigning to "time" just at one place and it's just being used at other places.
Don't ever compare floating point values for equality unless you know exactly what you are doing. I would strongly suggest you use integers (perhaps integer numbers of milliseconds) for this purpose.
See What Every Computer Scientist Should Know About Floating-Point Arithmetic for more information.
Floating point is a fixed-precision format. This is an inherent limitation of fixed-precision formats.
For example, say you used six decimal digits of precision. One-third would be .333333. But if you add one-third three times, you get .999999, not 1. That's the nature of the beast.
Not exactly recommending this, but the issue is that the 0.1 cannot be represented exactly as double. 1.0 can be. So if you make your time-step a (negative) power of two, you will find a difference. By way of illustration:
double delta = 1.0 / 8;
int stopper = 10;
int nextInt = 1;
for (double t = 0; t <= stopper; t += delta)
{
if (t == nextInt)
{
std::cout << "int ";
++nextInt;
}
else
std::cout << " ";
std::cout << t << std::endl;
}
Just round "time" after each increment to make sure it maintains a sensible value.
Something like that:
double round(double value, double precision)
{
return floor(value / precision + 0.5) * precision;
}
time = round(time + 0.1, 0.1);

Why do simple doubles like 1.82 end up being 1.819999999645634565360? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why does Visual Studio 2008 tell me .9 - .8999999999999995 = 0.00000000000000055511151231257827?
c++
Hey so i'm making a function to return the number of a digits in a number data type given, but i'm having some trouble with doubles.
I figure out how many digits are in it by multiplying it by like 10 billion and then taking away digits 1 by 1 until the double ends up being 0. however when putting in a double of value say .7904 i never exit the function as it keeps taking away digits which never end up being 0 as the resut of .7904 ends up being 7,903,999,988 and not 7,904,000,000.
How can i solve this problem?? Thanks =) ! oh and any other feed back on my code is WELCOME!
here's the code of my function:
/////////////////////// Numb_Digits() ////////////////////////////////////////////////////
enum{DECIMALS = 10, WHOLE_NUMBS = 20, ALL = 30};
template<typename T>
unsigned long int Numb_Digits(T numb, int scope)
{
unsigned long int length= 0;
switch(scope){
case DECIMALS: numb-= (int)numb; numb*=10000000000; // 10 bil (10 zeros)
for(; numb != 0; length++)
numb-=((int)(numb/pow((double)10, (double)(9-length))))* pow((double)10, (double)(9-length)); break;
case WHOLE_NUMBS: numb= (int)numb; numb*=10000000000;
for(; numb != 0; length++)
numb-=((int)(numb/pow((double)10, (double)(9-length))))* pow((double)10, (double)(9-length)); break;
case ALL: numb = numb; numb*=10000000000;
for(; numb != 0; length++)
numb-=((int)(numb/pow((double)10, (double)(9-length))))* pow((double)10, (double)(9-length)); break;
default: break;}
return length;
};
int main()
{
double test = 345.6457;
cout << Numb_Digits(test, ALL) << endl;
cout << Numb_Digits(test, DECIMALS) << endl;
cout << Numb_Digits(test, WHOLE_NUMBS) << endl;
return 0;
}
It's because of their binary representation, which is discussed in depth here:
http://en.wikipedia.org/wiki/IEEE_754-2008
Basically, when a number can't be represented as is, an approximation is used instead.
To compare floats for equality, check if their difference is lesser than an arbitrary precision.
The easy summary about floating point arithmetic :
http://floating-point-gui.de/
Read this and you'll see the light.
If you're more on the math side, Goldberg paper is always nice :
http://cr.yp.to/2005-590/goldberg.pdf
Long story short : real numbers are stored with a fixed, irregular precision, leading to non obvious behaviors. This is unrelated to the language but more a design choice of how to handle real numbers as a whole.
This is because C++ (like most other languages) can not store floating point numbers with infinte precision.
Floating points are stored like this:
sign * coefficient * 10^exponent if you're using base 10.
The problem is that both the coefficient and exponent are stored as finite integers.
This is a common problem with storing floating point in computer programs, you usually get a tiny rounding error.
The most common way of dealing with this is:
Store the number as a fraction (x/y)
Use a delta that allows small deviations (if abs(x-y) < delta)
Use a third party library such as GMP that can store floating point with perfect precision.
Regarding your question about counting decimals.
There is no way of dealing with this if you get a double as input. You cannot be sure that the user actually sent 1.819999999645634565360 and not 1.82.
Either you have to change your input or change the way your function works.
More info on floating point can be found here: http://en.wikipedia.org/wiki/Floating_point
This is because of the way the IEEE floating point standard is implemented, which will vary depending on operations. It is an approximation of precision. Never use logic of if(float == float), ever!
Float numbers are represented in the form Significant digits × baseexponent(IEEE 754). In your case, float 1.82 = 1 + 0.5 + 0.25 + 0.0625 + ...
Since only a limited digits could be stored, therefore there will be a round error if the float number cannot be represented as a terminating expansion in the relevant base (base 2 in the case).
You should always check relative differences with floating point numbers, not absolute values.
You need to read this, too.
Computers don't store floating point numbers exactly. To accomplish what you are doing, you could store the original input as a string, and count the number of characters.