Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Consider a simple function to divide two floats,
float floatDiv(float x, float y)
{
float z;
z = x/y;
return z;
}
All I can think of is when y==0 it has undefined behavior. Any others?
Overflow and underflow are two pitfalls, where the true result of a division cannot be held in the data type. This example shows both. In the second case of underflow, the value is too small to be represented and becomes 0.0
#include <stdio.h>
#include <float.h>
int main(){
float large, small;
large = FLT_MAX / FLT_MIN;
printf ("%f\n", (double)large);
small = FLT_MIN / FLT_MAX;
if (small == 0.0f) printf("Zero\n");
return 0;
}
Program output:
1.#INF00
Zero
One of these could happen as an intermediate step in a calculation, so might not be obvious from the range of the expected result. One practical example of that is when computing the sum of an exponential series with alternate + and - terms, such as the series for sin(x).
A pitfall with using floating point is the accuracy, since the set of values that can be represented exactly is very small compared to the values that are not represented exactly.
Given:
z = x / y;
The expression:
z * y
may not be equal to x and depends on the precision capabilities of the floating point representation.
Related
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
I'm trying to do some math in Arduino and the result is NaN:
int Count1=1;
int Count1=1;
int Count2=2;
float Total= 0;
float n1= Count1;
float n2= Count2;
void setup() {
Serial.begin(9600);
}
void loop(){
Total = ((n1 / n2)*-100);
Serial.print(Total);
}
Result: Total = Nan.
Can you help me with some hints ?
hard to say what compiler you got (I do not code in Arduino framework) But I see the problem with this line:
Total = ((n1 / n2)*-100);
where n1=1, n2=2 are floats but -100 is integer so your compiler most likely converted computation into integer (1/2 = 0) and then convert back to float which is SLOW and round off your wanted result... There are ways how to solve this
use floats to avoid integer math
Total = ((n1 / n2)*-100.0);
Total = ((n1 / n2)*-100.0f);
multiply first to preserve accuracy
Total = (-100*n1)/n2;
however this will most likely still use integers so you would have no digits after decimal point.
I would prefer to use #1 as your output is also float...
However all this would lead to result 0 instead of NAN so there might be also different problem like what datatype your Serial.print(Total); expects is it really float or its double?
Try this:
double x;
x=Total;
Serial.print(x);
If it makes any difference. Anyway your code is not MCVE as I see no main so there might be also problem in part of code you did not share.
Also common problem on Arduino is low RAM memory depending on what MCU you have I expect you got 1 or 2 KByte of RAM so if your code uses more you can easily overwrite parts of your variables (especially if you include ADAFRUIT SSD1306 LCD driver which takes alone slightly above 1KByte of RAM for itself).
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Is there a way to convert a double into an integer without risking any undesired errors in the process? I read in Programming - Principles and Practice Using C++ (a book written by the creator of c++) that doubles cannot be turned into integers, but I've put it to the test, and it converts properly about 80% of the time. What's the best way to do this with no risk at all, if it's even possible?
So for example, this converts properly.
double bruh = 10.0;
int a = bruh;
cout << bruh << "\n";
But this doesn't.
double bruh = 10.9;
int a = bruh;
cout << bruh << "\n";
In short, it doesn't round automatically so I think that's what constitutes it as "unsafe".
It it not possible to convert all doubles to integers with no risk of losing data.
First, if the double contains a fractional part (42.9), that fractional part will be lost.
Second, doubles can hold a much larger range of values than most integers, something around 1.7e308, so when you get into the larger values you simply won't be able to store them into an integer.
way to convert a double into an integer without risking any undesired errors
in short, it doesn't round automatically so I think that's what constitutes it as "unsafe"
To convert to an integer value:
x = round(x);
To convert to an integer type:
Start with a round function like long lround(double x);. It "Returns the integer value that is nearest in value to x, with halfway cases rounded away from zero."
If the round result is outside the long range, problems occur and code may want to test for that first.
// Carefully form a double the is 1 more than LONG_MAX
#define LONG_MAXP1 ((LONG_MAX/2 + 1)*2.0)
long val = 0;
if (x - LONG_MAXP1 < -0.5 && x - LONG_MIN > -0.5) {
val = lround(x);
} else {
Handle_error();
}
Detail: in order to test if a double is in range to round to a long, it is important to test the endpoints carefully. The mathematical valid range is (LONG_MIN-0.5 ... LONG_MAX + 0.5), yet those endpoints may not be exactly representable as a double. Instead code uses nearby LONG_MIN and LONG_MAXP1 whose magnitudes are powers of 2 and easy to represent exactly as a double.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Is it possible to compute arithmetic-geometric mean without using an epsilon in C++?
Here is my code:
double agm(double a, double b)
{
if(a > b)
{
a = a + b;
b = a - b;
a = a - b;
}
double aCurrent(a), bCurrent(b),
aNext(a), bNext(b);
while(aCurrent - bCurrent != 0)
{
aNext = sqrt(aCurrent*bCurrent);
bNext = (aCurrent+bCurrent)*0.5;
aCurrent = aNext;
bCurrent = bNext;
}
return aCurrent;
}
double sqrt(double x)
{
double res(x * 0.5);
do
{
res = (res + x/res) * 0.5;
} while(abs(res*res - x) > 1.0e-9);
return res;
}
And it runs forever.
Actually it is very clear what I was asking. It is just that you never met the problem and maybe lazy to think about it and are saying at once that there is nothing to talk about.
So, here is the solution I was looking for:
Instead of eps we can just add the following condition
if(aCurrent <= aPrev || bPrev <= bCurrent || bCurrent <= aCurrent )
And if the condition is true, then it means that we have computed the arithmetic-geometric mean with the most precision possible on our machine. As you can see there is no eps.
Using an eps in the question and answer means comparing that we say that two double numbers are equal when the difference between them is less than eps.
Please, reconsider opening the question.
Of course you can. It suffices to limit the number of iterations to the maximum required for convergence in any case, which should be close to the logarithm of the number of significant bits in the floating-point representation.
The same reasoning holds for the square root. (With a good starting approximation based on the floating-point exponent, i.e. at most a factor 2 away from the exact root, 5 iterations always suffice for doubles).
As a side note, avoid using absolute tolerances. Floating-point values can vary in a very wide range. They can be so large that the tolerance is 0 in comparison, or so tiny that they are below the tolerance itself. Prefer relative tolerances, with the extra difficulty that there is no relative tolerance to 0.
No, it's not possible without using an epsilon. Floating point arithmetic is an approximation of real arithmetic, and usually generates roundoff errors. As a result, it's unlikely the two calculation sequences used to compute the AGM will ever converge to exactly the same floating point numbers. So rather than test whether two floating point numbers are equal, you need to test whether they're close enough to each other to consider them effectively equal. And that's done by calculating the difference and testing whether it's really small.
You can either use a hard-coded epsilon value, or calculate it relative to the size of the numbers. The latter tends to be better, because it allows you to work with different number scales. E.g. you shouldn't use the same epsilon to try to calculate the square root of 12345 and 0.000012345; 0.01 might be adequate for the large number, but you'd need something like 0.000001 for the small number.
See What every programmer should know about floating point
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 8 years ago.
Improve this question
I wrote a program in "dev-c++" about discussing about a point. We want to know that it is in or out a triangle. Why doesn't my program work correctly? What should I do?
This is my program:
#include <iostream>
#include <math.h>
int main()
{
int n,a,b,c,d;
int x[n];
int y[n];
n=1;
while (n<=4)
{
std:: cin >> x[n];
std:: cin >> y[n];
n=n+1;
}
a= fabs((1/2)*((x[1]*(y[2]-y[3]))+(x[2]*(y[3]-y[1]))+(x[3]*(y[1]-y[2]))));
b= fabs((1/2)*((x[1]*(y[2]-y[4]))+(x[2]*(y[4]-y[1]))+(x[4]*(y[1]-y[2]))));
c= fabs((1/2)*((x[1]*(y[3]-y[4]))+(x[3]*(y[4]-y[1]))+(x[4]*(y[1]-y[3]))));
d= fabs((1/2)*((x[2]*(y[3]-y[4]))+(x[3]*(y[4]-y[2]))+(x[4]*(y[2]-y[3]))));
if ((b+c+d)!= a)
{
std:: cout<< "out of triangle\n";
}
if (b+c+d==a)
{
std:: cout <<"in triangle\n";
}
}
The input of this program consists of integer coordinates only, but to check if a point lies inside a triangle this method needs to know the area of triangles. The area of a triangle is
A = width * height / 2
and because of that final division it may return a floating point number. Thus, the intermediate variables a, b, c, d need to be at least float.
As long as all of the constants and variables at the right hand side of an = are integer, C calculates the result as an integer as well. Only at the very last step the result gets converted to the destination type. Thus,
double x = 2*3/4;
will be calculated as 2*3/4 using integers and resulting in 6/4 -> 1, and only then converted to a double value: 1.000. Forcing the intermediates to a float type fixes it:
double x = 2.0*3/4;
and then x = 1.5.
Be aware that when using floating point numbers, you could have run into accuracy problems with the final comparison
if (b+c+d==a)
...
Fortunately, this will not be a problem with your divisions by 2. The decimal value 0.5 can be represented exactly in float and double formats, as long as the 'whole' part does not exceed the number of available digits. But it's a good thing to keep in mind nevertheless.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
Working in C language, I would like to round a float number to its inferior odd integer and its inferior even integer.
The speed of the solution is very important (because it is computed 2M*20 times per seconds).
I propose this solution :
x_even = (int)floor(x_f) & ~1;
x_odd = ((int)ceil(x_f) & ~1) -1;
I presume that the weak point is the floor and ceil operations, but I'm not even sure of that.
Does someone have a comment on this solution ; I'm interested about it's speed of execution, but if you have another solution to share, I'll be very happy to test it :-).
You don't explain what you mean by 'inferior', but assuming you mean 'greatest even/odd integer less than the given number', and assuming you have a 2s-complement machine, you want:
x_i = (int)floor(x_f);
x_even = x_i & ~1;
x_odd = x_i - (~x_i & 1);
If you want to avoid the implementation dependency of doing bitwise ops on possibly negative signed numbers, you could instead do it entirely in float:
x_even = 2.0 * floor(x_f * 0.5);
x_odd = x_even + 1.0 > x_f ? x_even - 1.0 : x_even + 1.0;
This also has the advantage of not overflowing for large numbers, though it does give you x_odd == x_even for large numbers (those too big for the floating point representation to represent an odd number).
Perhaps the ceil and floor function won't be necessary as transtypage from a double to an int is equivalent to the floor function for positive integer.
Try something like this for POSITIVE INTEGERs :
double k = 68.8 ; // Because we need something to seed with.
int even = ((int) k & ~1) ; // What you did
int test = ((int) (k+1) & ~1) ; // Little trick
int odd = (test>k) ? odd+1 : odd - 1 ;
I tested it on codepad, and it works well for on http://codepad.org/y3t0KgwW for C++, I think it will in C. If you test this solution, I'd be glad to know how fast it can be...
Notice that :
This is not a good answer as it shadows the existence of negative integers.
The range is limited to integers'.
I swapped odd and even numbers, I corrected it thank's to Chris' comment.
I'm just adding my humble stone :)