Mercurial > octave
changeset 30415:e22183b892c6
maint: merge stable to default.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Thu, 02 Dec 2021 14:47:40 +0100 |
parents | 1fda8d2229d7 (current diff) 391b35ef8b24 (diff) |
children | 9f4442cccedf |
files | |
diffstat | 1 files changed, 17 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/specfun/nchoosek.m Wed Dec 01 21:49:21 2021 +0100 +++ b/scripts/specfun/nchoosek.m Thu Dec 02 14:47:40 2021 +0100 @@ -121,11 +121,11 @@ ## Since Odd*Even is guaranteed to be Even, also take out a factor ## of 2 from numerator and denominator. if (rem (k, 2)) # k is odd - numer = [(v-k+1:v-(k+1)/2) .* (v-1:-1:v-(k-1)/2) / 2, v]; - denom = [(1:k/2) .* (k-1:-1:(k+1)/2) / 2, k]; + numer = [((v-k+1:v-(k+1)/2) .* (v-1:-1:v-(k-1)/2)) / 2, v]; + denom = [((1:(k-1)/2) .* (k-1:-1:(k+1)/2)) / 2, k]; else # k is even - numer = (v-k+1:v-k/2) .* (v:-1:v-k/2+1) / 2; - denom = (1:k/2) .* (k:-1:k/2+1) / 2; + numer = ((v-k+1:v-k/2) .* (v:-1:v-k/2+1)) / 2; + denom = ((1:k/2) .* (k:-1:k/2+1)) / 2; endif ## Remove common factors from numerator and denominator @@ -140,9 +140,13 @@ numer = numer(numer > 1); until (isempty (denom)) - C = prod (numer); - if (C > flintmax) - warning ("nchoosek: possible loss of precision"); + C = prod (numer, "native"); + if (isfloat (C) && C > flintmax (C)) + warning ("Octave:nchoosek:large-output-float", ... + "nchoosek: possible loss of precision"); + elseif (isinteger (C) && C == intmax (C)) + warning ("Octave:nchoosek:large-output-integer", ... + "nchoosek: result may have saturated at intmax"); endif elseif (k == 0) C = v(zeros (1, 0)); # Return 1x0 object for Matlab compatibility @@ -269,6 +273,11 @@ %! assert (isstruct (x)); %! assert (fieldnames (x), {"a"; "b"}); +%!test <61565> +%! x = nchoosek (uint8 (10), uint8 (5)); +%! assert (x, uint8 (252)); +%! assert (class (x), "uint8"); + ## Test input validation %!error <Invalid call> nchoosek () %!error <Invalid call> nchoosek (1) @@ -282,3 +291,4 @@ %!error <N must be a non-negative integer .= K> nchoosek (-100, 45) %!error <N must be a non-negative integer .= K> nchoosek (100.5, 45) %!warning <possible loss of precision> nchoosek (100, 45); +%!warning <result .* saturated> nchoosek (uint64 (80), uint64 (40));