Floating-point precision processing in ACM

Source: Internet
Author: User
Tags acos asin float number

In ACM, accuracy issues are very common. Where the calculation of the geometric headache is generally the size of the code and the accuracy of the problem, code, as long as the usual attention to accumulate template is not a problem. Accuracy problem is not good to say, sometimes a precision problem may become a bottleneck, so you debug half a day can not find the error.

1. Why do floating point numbers have precision problems:

Floating-point numbers (in C + +), generally used more is the float, double.

&NBSP,

number of bytes

decimal precision number of digits

float

4

-3.4e-38~3.4e38

6~7

double

8

-1.7e-308~1.7e308

14~15

If the memory is not very tight or the accuracy requirement is not very low, the general choice is double. The 14-bit precision (which is a valid digit bit, not the number of digits after the decimal point) is usually sufficient. Note that the problem comes, the number of data precision digits reached 14 bits, but some floating-point operations result in precision and can not reach such a high, may be accurate results only 10~12 bit around. What about the lower one? Nature is an unexpected figure. This brings us to the question that even theoretically the same values, because they are obtained by different computational processes, are likely to be different (in general) for the lower number. This phenomenon does not seem to have much impact, but it can have a deadly effect on an operation: = =. Well, the judgment is equal. Note that the = = = of floating-point numbers in C + + requires exactly the same to return true. Consider the following example:

#include <stdio.h>#include<math.h>intMain () {DoubleA = ASIN (SQRT (2.0) /2) *4.0; Doubleb = ACOs (-1.0 ); printf ("A =%.20lf\n", a); printf ("B =%.20lf\n", B); printf ("A-B =%.20lf\n"Ab); printf ("A = = b =%d\n", A = =b); return 0;}

Output:

A = 3.14159265358979360000

b = 3.14159265358979310000

A-B = 0.00000000000000044409

A = = b = 0

Our solution is to introduce EPS to assist in judging the equality of floating-point numbers.

2. eps

EPS is abbreviated from Epsilon, which represents a small amount, but this small quantity also ensures that the uncertainty is much larger than the result of floating-point arithmetic. The most common value of EPS is about 1e-8. After introducing EPS, we determine that two floating-point numbers A and B are equal in the following way:

Define the three exit functions as follows: Int SGN (double a) {return a <-eps? -1:a < EPS 0:1;}

The calculation of the size of various judgments should be corrected as follows:

Traditional meaning

Correction notation 1

Correction Notation 2

A = = B

SGN (A-b) = = 0

Fabs (a–b) < EPS

A! = B

SGN (A-b)! = 0

Fabs (a–b) > EPS

A < b

SGN (A-B) < 0

A–b <-eps

A <= b

SGN (A-B) <= 0

A–b < EPS

A > B

SGN (A-B) > 0

A–b > EPS

A >= b

SGN (A-B) >= 0

A–b >-eps

In this way, we can judge the difference between the floating points which are very close to each other, and the number of the difference between the different values and the EPS is unequal.

PS: Develop good habits and try not to judge floating-point numbers. For example, my amendment does not appear in the 2. = =.

3. Function out-of-bounds for EPS

If sqrt (a), ASIN (a), and a in ACOs (a) are calculated and passed in, you have to be careful.

If a is supposed to be 0, because of a floating-point error, it may actually be a very small negative number (such as 1e-12), so that sqrt (a) deserves 0, directly because a does not define the domain and error.

Similarly, if a is supposed to be ±1, then ASIN (a), ACOs (a) can also be faulted.

Therefore, for this function, a must be corrected beforehand.

4. Output Trap I

This section, as in the next section, is caused by problems that require output floating-point numbers. And it's all about rounding.

When it comes to rounding, just a little bit more about it, as far as I know there are three common methods:

1. printf ("%.3lf", a); Three decimal places reserved for a, rounded by fourth bit

2. (int) A; Rounding A by 0

3. Ceil (a);   Floor (a); As the name implies, up forensics, down rounding. It is important to note that both functions return a double, not an int

The first of these is very common in the output (nonsense ...).

Now consider a situation where the topic requires output to retain two decimal places. The exact value of the correct answer to a case is 0.005, which is supposed to output 0.01, but your result may be 0.005000000001 (congratulations), or 0.004999999999 (tragedy), if you output according to printf ("%.2lf", a), Then your encounter will be the same as the words in parentheses.

The workaround is that if a is positive, the output is a+eps, otherwise the output a-eps

Typical case: POJ2826

5. Output Trap II

ICPC topic output has an unwritten rule (sometimes written), do not output: 0.000

Let's start by figuring out when to press printf ("%.3lf\n", a) output to show this result.

Give the result directly: A∈ ( -0.000499999 ...,-0.000 ...). 1)

So, if you find that a falls within this range, please output 0.000 directly. A more insured approach is to use sprintf to directly determine whether the output is not-0.000 to be processed again.

Typical case: UVA746

6. Range out of bounds

This is strictly not a category of precision, but dine is still possible. Note that although a double can represent a large range of numbers, it is not a poor size, which says the maximum is 1e308. So there are times when you have to be careful, like when you are connected, you need to change the logarithm when necessary.

Typical case: HDU3558

7. About Set<t>

Sometimes we may have this need to insert a floating-point number and query for an operation that has been inserted. The handwritten hash table is a method (the hash function should be carefully designed), but the set is not more convenient. But the set seems to be weighed by = =? Looks like it won't work. After observation, set is not by = = To judge the equality, is through <, specifically, as long as the a<b and B<a are not established, it is considered equal to A and B, can be found,

If the smaller is defined as: BOOL operator < (const dat DAT) Const{return val < dat.val-eps;} can solve the problem. (the base type cannot overload the operator, so it is encapsulated)

8. Input value fluctuation is too large

This is not a common situation, but it can help you become more familiar with EPS. If a question input says, give a float number A, 1e-20 < a < 1e20. Do you dare to use 1e-8 EPS? It is reasonable to scale the EPS to the appropriate size according to the input scale.

Typical case: Hustoj 1361

9. Some recommendations

The functions that are prone to large floating-point errors are ASIN and ACOS. Please use atan2 as much as possible.

In addition, if the data is clearly stated to be an integer, and the range is small, using int or long long instead of double is an excellent choice, so there is no floating-point error.


Floating-point precision processing in ACM

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.