Mercurial > hg > octave-lojdl
changeset 15509:f0dfdc7faa71
Fix incorrect behaviour of eps () for matrix input (bug #37539).
* data.cc(Feps): For matrix input, iterate over each element and
calculate eps value.
author | Carlo de Falco <cdf@users.sourceforge.net> |
---|---|
date | Thu, 11 Oct 2012 09:26:14 +0200 |
parents | cea08e743c2c |
children | 3ae8c1ee7365 |
files | libinterp/interpfcn/data.cc |
diffstat | 1 files changed, 40 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/interpfcn/data.cc +++ b/libinterp/interpfcn/data.cc @@ -4116,53 +4116,53 @@ { if (args(0).is_single_type ()) { - float val = args(0).float_value (); + Array<float> 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<float>::min ()) - retval = fill_matrix (octave_value ("single"), 0e0, - powf (2.0, -149e0), "eps"); - else + { + Array<float> epsval (x.dims ()); + + for (octave_idx_type i = 0; i < x.numel (); i++) { - int expon; - frexpf (val, &expon); - val = std::pow (static_cast <float> (2.0), - static_cast <float> (expon - 24)); - retval = fill_matrix (octave_value ("single"), - std::numeric_limits<double>::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<float>::min ()) + epsval(i) = powf (2.0, -149e0); + else + { + int expon; + frexpf (val, &expon); + epsval(i) = std::pow (static_cast <float> (2.0), + static_cast <float> (expon - 24)); + } } + retval = epsval; } } else { - double val = args(0).double_value (); + Array<double> 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<double>::min ()) - retval = fill_matrix (octave_value_list (), - pow (2.0, -1074e0), 0e0, "eps"); - else + Array<double> epsval (x.dims ()); + + for (octave_idx_type i = 0; i < x.numel (); i++) { - int expon; - frexp (val, &expon); - val = std::pow (static_cast <double> (2.0), - static_cast <double> (expon - 53)); - retval = fill_matrix (octave_value_list (), val, - std::numeric_limits<float>::epsilon (), - "eps"); + double val = ::fabs (x(i)); + if (xisnan (val) || xisinf (val)) + epsval(i) = lo_ieee_nan_value (); + else if (val < std::numeric_limits<double>::min ()) + epsval(i) = pow (2.0, -1074e0); + else + { + int expon; + frexp (val, &expon); + epsval(i) = std::pow (static_cast <double> (2.0), + static_cast <double> (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, ,