# HG changeset patch # User Carlo de Falco # Date 1349940374 -7200 # Node ID f0dfdc7faa71b09a98977d4e087582918aab1dc3 # Parent cea08e743c2cc2d12514112ffd4cba3bfa44cf32 Fix incorrect behaviour of eps () for matrix input (bug #37539). * data.cc(Feps): For matrix input, iterate over each element and calculate eps value. diff -r cea08e743c2c -r f0dfdc7faa71 libinterp/interpfcn/data.cc --- a/libinterp/interpfcn/data.cc Thu Oct 11 20:02:34 2012 -0700 +++ b/libinterp/interpfcn/data.cc Thu Oct 11 09:26:14 2012 +0200 @@ -4116,53 +4116,53 @@ { if (args(0).is_single_type ()) { - float val = args(0).float_value (); + Array x = args(0).float_array_value (); if (! error_state) - { - val = ::fabsf (val); - if (xisnan (val) || xisinf (val)) - retval = fill_matrix (octave_value ("single"), - lo_ieee_nan_value (), - lo_ieee_float_nan_value (), "eps"); - else if (val < std::numeric_limits::min ()) - retval = fill_matrix (octave_value ("single"), 0e0, - powf (2.0, -149e0), "eps"); - else + { + Array epsval (x.dims ()); + + for (octave_idx_type i = 0; i < x.numel (); i++) { - int expon; - frexpf (val, &expon); - val = std::pow (static_cast (2.0), - static_cast (expon - 24)); - retval = fill_matrix (octave_value ("single"), - std::numeric_limits::epsilon (), - val, "eps"); + float val = ::fabsf (x(i)); + if (xisnan (val) || xisinf (val)) + epsval(i) = lo_ieee_nan_value (); + else if (val < std::numeric_limits::min ()) + epsval(i) = powf (2.0, -149e0); + else + { + int expon; + frexpf (val, &expon); + epsval(i) = std::pow (static_cast (2.0), + static_cast (expon - 24)); + } } + retval = epsval; } } else { - double val = args(0).double_value (); + Array x = args(0).array_value (); if (! error_state) { - val = ::fabs (val); - if (xisnan (val) || xisinf (val)) - retval = fill_matrix (octave_value_list (), - lo_ieee_nan_value (), - lo_ieee_float_nan_value (), "eps"); - else if (val < std::numeric_limits::min ()) - retval = fill_matrix (octave_value_list (), - pow (2.0, -1074e0), 0e0, "eps"); - else + Array epsval (x.dims ()); + + for (octave_idx_type i = 0; i < x.numel (); i++) { - int expon; - frexp (val, &expon); - val = std::pow (static_cast (2.0), - static_cast (expon - 53)); - retval = fill_matrix (octave_value_list (), val, - std::numeric_limits::epsilon (), - "eps"); + double val = ::fabs (x(i)); + if (xisnan (val) || xisinf (val)) + epsval(i) = lo_ieee_nan_value (); + else if (val < std::numeric_limits::min ()) + epsval(i) = pow (2.0, -1074e0); + else + { + int expon; + frexp (val, &expon); + epsval(i) = std::pow (static_cast (2.0), + static_cast (expon - 53)); + } + retval = epsval; } } } @@ -4184,6 +4184,8 @@ %!assert (eps (realmin/16), 2^(-1074)) %!assert (eps (Inf), NaN) %!assert (eps (NaN), NaN) +%!assert (eps ([1/2 1 2 realmax 0 realmin/2 realmin/16 Inf NaN]), +%! [2^(-53) 2^(-52) 2^(-51) 2^971 2^(-1074) 2^(-1074) 2^(-1074) NaN NaN]) %!assert (eps (single (1/2)), single (2^(-24))) %!assert (eps (single (1)), single (2^(-23))) %!assert (eps (single (2)), single (2^(-22))) @@ -4193,6 +4195,9 @@ %!assert (eps (realmin ("single")/16), single (2^(-149))) %!assert (eps (single (Inf)), single (NaN)) %!assert (eps (single (NaN)), single (NaN)) +%!assert (eps (single ([1/2 1 2 realmax("single") 0 realmin("single")/2 realmin("single")/16 Inf NaN])), +%! single ([2^(-24) 2^(-23) 2^(-22) 2^104 2^(-149) 2^(-149) 2^(-149) NaN NaN])) + */ DEFUN (pi, args, ,