Function to determine if two numbers are nearly equal when rounded to n significant decimal digits

前端 未结 11 1859

I have been asked to test a library provided by a 3rd party. The library is known to be accurate to n significant figures. Any less-significant errors can safely be

11条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-03 02:48

    This is a fairly common issue with floating point numbers. I solve it based on the discussion in Section 1.5 of Demmel[1]. (1) Calculate the roundoff error. (2) Check that the roundoff error is less than some epsilon. I haven't used python in some time and only have version 2.4.3, but I'll try to get this correct.

    Step 1. Roundoff error

    def roundoff_error(exact, approximate):
        return abs(approximate/exact - 1.0)
    

    Step 2. Floating point equality

    def float_equal(float1, float2, epsilon=2.0e-9):
        return (roundoff_error(float1, float2) < epsilon)
    

    There are a couple obvious deficiencies with this code.

    1. Division by zero error if the exact value is Zero.
    2. Does not verify that the arguments are floating point values.

    Revision 1.

    def roundoff_error(exact, approximate):
        if (exact == 0.0 or approximate == 0.0):
            return abs(exact + approximate)
        else:
            return abs(approximate/exact - 1.0)
    
    def float_equal(float1, float2, epsilon=2.0e-9):
        if not isinstance(float1,float):
            raise TypeError,"First argument is not a float."
        elif not isinstance(float2,float):
            raise TypeError,"Second argument is not a float."
        else:
            return (roundoff_error(float1, float2) < epsilon)
    

    That's a little better. If either the exact or the approximate value is zero, than the error is equal to the value of the other. If something besides a floating point value is provided, a TypeError is raised.

    At this point, the only difficult thing is setting the correct value for epsilon. I noticed in the documentation for version 2.6.1 that there is an epsilon attribute in sys.float_info, so I would use twice that value as the default epsilon. But the correct value depends on both your application and your algorithm.

    [1] James W. Demmel, Applied Numerical Linear Algebra, SIAM, 1997.

提交回复
热议问题