From df8f8581153b4df7e7f042afd088b905f13b654c Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Tue, 23 Nov 2021 15:38:28 -0600 Subject: Enhanced RDoc for Float#next_float (#5160) * Enhanced RDoc for Float#next_float --- numeric.c | 100 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 54 insertions(+), 46 deletions(-) (limited to 'numeric.c') diff --git a/numeric.c b/numeric.c index d9431ea67d..ef5e23291b 100644 --- a/numeric.c +++ b/numeric.c @@ -1975,53 +1975,61 @@ flo_nextafter(VALUE flo, double value) * call-seq: * next_float -> float * - * Returns the next representable floating point number. + * Returns the next-larger representable \Float. + * + * These examples show the internally stored values (64-bit hexadecimal) + * for each \Float +f+ and for the corresponding f.next_float: + * + * f = 0.0 # 0x0000000000000000 + * f.next_float # 0x0000000000000001 + * + * f = 0.01 # 0x3f847ae147ae147b + * f.next_float # 0x3f847ae147ae147c + * + * In the remaining examples here, the output is shown in the usual way + * (result +to_s+); + * + * Float::MAX.next_float # => Infinity + * + * 0.01.next_float # => 0.010000000000000002 + * 1.0.next_float # => 1.0000000000000002 + * 100.0.next_float # => 100.00000000000001 + * + * f = 0.01 + * (0..19).each_with_index {|i| printf "%2d %-20a %s\n", i, f, f.to_s; f = f.next_float } + * + * Output: + * + * 0 0x1.47ae147ae147bp-7 0.01 + * 1 0x1.47ae147ae147cp-7 0.010000000000000002 + * 2 0x1.47ae147ae147dp-7 0.010000000000000004 + * 3 0x1.47ae147ae147ep-7 0.010000000000000005 + * 4 0x1.47ae147ae147fp-7 0.010000000000000007 + * 5 0x1.47ae147ae148p-7 0.010000000000000009 + * 6 0x1.47ae147ae1481p-7 0.01000000000000001 + * 7 0x1.47ae147ae1482p-7 0.010000000000000012 + * 8 0x1.47ae147ae1483p-7 0.010000000000000014 + * 9 0x1.47ae147ae1484p-7 0.010000000000000016 + * 10 0x1.47ae147ae1485p-7 0.010000000000000018 + * 11 0x1.47ae147ae1486p-7 0.01000000000000002 + * 12 0x1.47ae147ae1487p-7 0.010000000000000021 + * 13 0x1.47ae147ae1488p-7 0.010000000000000023 + * 14 0x1.47ae147ae1489p-7 0.010000000000000024 + * 15 0x1.47ae147ae148ap-7 0.010000000000000026 + * 16 0x1.47ae147ae148bp-7 0.010000000000000028 + * 17 0x1.47ae147ae148cp-7 0.01000000000000003 + * 18 0x1.47ae147ae148dp-7 0.010000000000000031 + * 19 0x1.47ae147ae148ep-7 0.010000000000000033 + * + * f = 0.0; 100.times { f += 0.1 } + * f # => 9.99999999999998 # should be 10.0 in the ideal world. + * 10-f # => 1.9539925233402755e-14 # the floating point error. + * 10.0.next_float-10 # => 1.7763568394002505e-15 # 1 ulp (unit in the last place). + * (10-f)/(10.0.next_float-10) # => 11.0 # the error is 11 ulp. + * (10-f)/(10*Float::EPSILON) # => 8.8 # approximation of the above. + * "%a" % 10 # => "0x1.4p+3" + * "%a" % f # => "0x1.3fffffffffff5p+3" # the last hex digit is 5. 16 - 5 = 11 ulp. * - * Float::MAX.next_float and Float::INFINITY.next_float is Float::INFINITY. - * - * Float::NAN.next_float is Float::NAN. - * - * For example: - * - * 0.01.next_float #=> 0.010000000000000002 - * 1.0.next_float #=> 1.0000000000000002 - * 100.0.next_float #=> 100.00000000000001 - * - * 0.01.next_float - 0.01 #=> 1.734723475976807e-18 - * 1.0.next_float - 1.0 #=> 2.220446049250313e-16 - * 100.0.next_float - 100.0 #=> 1.4210854715202004e-14 - * - * f = 0.01; 20.times { printf "%-20a %s\n", f, f.to_s; f = f.next_float } - * #=> 0x1.47ae147ae147bp-7 0.01 - * # 0x1.47ae147ae147cp-7 0.010000000000000002 - * # 0x1.47ae147ae147dp-7 0.010000000000000004 - * # 0x1.47ae147ae147ep-7 0.010000000000000005 - * # 0x1.47ae147ae147fp-7 0.010000000000000007 - * # 0x1.47ae147ae148p-7 0.010000000000000009 - * # 0x1.47ae147ae1481p-7 0.01000000000000001 - * # 0x1.47ae147ae1482p-7 0.010000000000000012 - * # 0x1.47ae147ae1483p-7 0.010000000000000014 - * # 0x1.47ae147ae1484p-7 0.010000000000000016 - * # 0x1.47ae147ae1485p-7 0.010000000000000018 - * # 0x1.47ae147ae1486p-7 0.01000000000000002 - * # 0x1.47ae147ae1487p-7 0.010000000000000021 - * # 0x1.47ae147ae1488p-7 0.010000000000000023 - * # 0x1.47ae147ae1489p-7 0.010000000000000024 - * # 0x1.47ae147ae148ap-7 0.010000000000000026 - * # 0x1.47ae147ae148bp-7 0.010000000000000028 - * # 0x1.47ae147ae148cp-7 0.01000000000000003 - * # 0x1.47ae147ae148dp-7 0.010000000000000031 - * # 0x1.47ae147ae148ep-7 0.010000000000000033 - * - * f = 0.0 - * 100.times { f += 0.1 } - * f #=> 9.99999999999998 # should be 10.0 in the ideal world. - * 10-f #=> 1.9539925233402755e-14 # the floating point error. - * 10.0.next_float-10 #=> 1.7763568394002505e-15 # 1 ulp (unit in the last place). - * (10-f)/(10.0.next_float-10) #=> 11.0 # the error is 11 ulp. - * (10-f)/(10*Float::EPSILON) #=> 8.8 # approximation of the above. - * "%a" % 10 #=> "0x1.4p+3" - * "%a" % f #=> "0x1.3fffffffffff5p+3" # the last hex digit is 5. 16 - 5 = 11 ulp. */ static VALUE flo_next_float(VALUE vx) -- cgit v1.2.1