This article by Ruby-china a post "by the decimal point of precision problem lead to design problems" lead, the post is also my hair, in view of the reply when learned a lot of content, have a little sentiment, so want to sum up.
First declare the programming language selected in this article is Ruby and the operating environment is Ubuntu.
In the preparation of finance, E-commerce and other applications, often encounter decimals, decimal multiplication, divide, add, subtract scenes.
Most languages represent decimals, have single-precision float, double doubles, and a more precise decimal, whichever is known as a floating-point number.
A floating-point number is an approximate value, not an exact value. As for why imprecise, this involves the bottom of the operating system, and the preservation of the binary. Some of the following articles are available on floating-point numbers and on the loss of precision in floating-point calculations.
Floating point numbers
The difference between fixed-point number and float point
Avoid error understanding of Float,double,decimal in C #
Floating-point Operation Precision Loss
Comparison of floating point numbers
The arithmetic of floating-point numbers will have the problem of precision loss, which will result in the logical operation of floating-point numbers beyond the understanding of daily life.
Problems:
IRB (main):005:0> 1.3-1.0 = = 0.3
=> false
Subvert the common sense in our lives, because the result of 1.3-1.0 in the computer is 0.30000000000000004.
There is also a d * g/g not necessarily equal to D, d/g * g is not necessarily equal to D.
This results in a lot of times, you can't use = = to directly compare two floating-point numbers, because the floating-point number is not an exact value, but an approximation.
What do we do?
Since it is approximate, that is to say they are very close, the gap is 0.00000000001 and so on, anyway very small. We can use this feature to write a function of our two floating-point comparisons. As long as we confirm that the gap between the two floating-point numbers is as small as a value we can accept, the two floating-point numbers are considered equal. For example, if we define less than 0.000000001, even if the two floating-point numbers are equal, we can write the following code.
Module floatequal
def equal (b) return
Self==b | | (self-b). ABS < 0.000000001
end
(1.3-1.0). Extend (floatequal). equal (0.3) # True
Another is the Saito, an integer comparison method, mentioned in the post. What is an integer comparison method? Is that the two sides of the comparison are converted to integers, exactly, that is, both sides are magnified 10 times times, or 100 times times, or 1000 times times, anyway, is to enlarge the same multiples, to ensure that both sides are integers, this time to calculate, and then compare.
Why, then? Because the preservation of the integer does not exist the accuracy loss problem, the integer arithmetic does not exist the accuracy loss question, therefore the computation result comparison can be correct, may directly use = = to compare,
(1.3*10-1.0*10) = = 0.3*10 # True
You can also use BigDecimal to compare floating-point numbers in Ruby, or to arithmetic floating-point numbers, and to avoid problems caused by loss of precision.
Bigdecimal.new ("1.3")-bigdecimal.new ("1") ==bigdecimal.new ("0.3") # True