# HG changeset patch # User Markus Mützel # Date 1648056473 -3600 # Node ID df26decca96bc6a01dd70e9244bd034097c97776 # Parent 9b3b0dbb4eba17649fc5475bc6bcbab062a41fd7 Tweak check for maximum possible increment of integer ranges (bug #62212). * ibinterp/octave-value/ov.cc (range_numel (T base, double increment, T limit)): Use condition that compensates the impact of floating point representation. * test/range.tst: Tag tests as fixed. diff -r 9b3b0dbb4eba -r df26decca96b libinterp/octave-value/ov.cc --- a/libinterp/octave-value/ov.cc Wed Mar 23 15:35:36 2022 +0100 +++ b/libinterp/octave-value/ov.cc Wed Mar 23 18:27:53 2022 +0100 @@ -3250,16 +3250,16 @@ double abs_increment = std::abs (increment); - if (abs_increment > max_val) + // Technically, this condition should be `abs_increment > max_val`. + // But intmax('uint64') is not representable exactly as floating point + // number. Instead, it "rounds" up by 1 to 2^64. To account for + // this, use the following expression which works for all unsigned + // integer types. + if ((abs_increment-1.) >= max_val) return 1; UT unsigned_increment = range_increment (increment); - // If the increment wasn't zero before but it is now, the cast to UT - // wrapped around. The range can only have one value. - if (unsigned_increment == 0) - return 1; - return range_numel_aux (base, unsigned_increment, limit); } diff -r 9b3b0dbb4eba -r df26decca96b test/range.tst --- a/test/range.tst Wed Mar 23 15:35:36 2022 +0100 +++ b/test/range.tst Wed Mar 23 18:27:53 2022 +0100 @@ -608,7 +608,7 @@ %! endfor ## integer range with large double increments -%!test <62212> # ascending ranges +%!test <*62212> # ascending ranges %! types = {"int8", "int16", "int32", "int64"}; %! for i_type = 1:numel (types) %! assert (intmin (types{i_type}) : -double (intmin (types{i_type})) : intmax (types{i_type}), ... @@ -621,7 +621,7 @@ %! [intmin(types{i_type}), intmax(types{i_type})-1]); %! endif %! endfor -%!test <62212> # descending ranges +%!test <*62212> # descending ranges %! types = {"int8", "int16", "int32", "int64"}; %! for i_type = 1:numel (types) %! assert (intmax (types{i_type}) : double (intmin (types{i_type})) : intmin (types{i_type}), ...