# HG changeset patch # User Carlo de Falco # Date 1349940374 -7200 # Node ID 77bea4060a6274e732bbda2cbebcf90091f85a69 # Parent 96b7343b8a419fc727a30f9aca10b1bf7f66028f Fix incorrect behaviour of eps () for matrix input (bug #37539) * data.cc(Feps): Correct matlab incompatible behaviour of eps when called with one matrix argument. diff --git a/libinterp/interpfcn/data.cc b/libinterp/interpfcn/data.cc --- a/libinterp/interpfcn/data.cc +++ b/libinterp/interpfcn/data.cc @@ -4116,53 +4116,57 @@ { if (args(0).is_single_type ()) { - float val = args(0).float_value (); + Array val = 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 + { + float *xval = val.fortran_vec (); + Array ret (val); + float *xret = ret.fortran_vec (); + + for (octave_idx_type i = 0; i < val.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"); + xval[i] = ::fabsf (xval[i]); + if (xisnan (xval[i]) || xisinf (xval[i])) + xret[i] = lo_ieee_nan_value (); + else if (xval[i] < std::numeric_limits::min ()) + xret[i] = powf (2.0, -149e0); + else + { + int expon; + frexpf (xval[i], &expon); + xret[i] = std::pow (static_cast (2.0), + static_cast (expon - 24)); + } } + retval = octave_value (ret); } } else { - double val = args(0).double_value (); + Array val = 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 + double *xval = val.fortran_vec (); + Array ret (val); + double *xret = ret.fortran_vec (); + + for (octave_idx_type i = 0; i < val.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"); + xval[i] = ::fabs (xval[i]); + if (xisnan (xval[i]) || xisinf (xval[i])) + xret[i] = lo_ieee_nan_value (); + else if (xval[i] < std::numeric_limits::min ()) + xret[i] = pow (2.0, -1074e0); + else + { + int expon; + frexp (xval[i], &expon); + xret[i] = std::pow (static_cast (2.0), + static_cast (expon - 53)); + } + retval = octave_value (ret); } } } @@ -4184,6 +4188,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 +4199,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, ,