changeset 33207:a92e59904393 bytecode-interpreter

maint: Merge default to bytecode-interpreter
author Arun Giridhar <arungiridhar@gmail.com>
date Thu, 14 Mar 2024 17:28:46 -0400
parents 1e2b93a4840d (current diff) 1ac1aeab7027 (diff)
children 70d44ca38603
files
diffstat 14 files changed, 272 insertions(+), 292 deletions(-) [+]
line wrap: on
line diff
--- a/doc/interpreter/testfun.txi	Tue Mar 12 15:06:31 2024 -0400
+++ b/doc/interpreter/testfun.txi	Thu Mar 14 17:28:46 2024 -0400
@@ -186,6 +186,12 @@
 %!shared @var{a}, @var{b}
 @end example
 
+Modifications to shared variables persist from one test to the next
+@strong{only} if the test succeeds.  Thus, if one test modifies a shared
+variable, later tests cannot know which value of the shared variable to expect
+because the pass/fail status of earlier tests is unknown.  For this reason, it
+is not recommended to modify shared variables in tests.
+
 You can also share test functions:
 
 @example
--- a/etc/NEWS.10.md	Tue Mar 12 15:06:31 2024 -0400
+++ b/etc/NEWS.10.md	Thu Mar 14 17:28:46 2024 -0400
@@ -17,6 +17,14 @@
 
 - `nchoosek` algorithm is now ~2x faster and provides greater precision.
 
+- `nextpow2` algorithm is now more accurate for inputs very close to a power
+of 2.  The output class now matches the input class for Matlab compatibility.
+The function no longer accepts complex inputs and will emit an error for these
+inputs.
+
+- `jsonencode` now outputs integers and floating point integers without ".0"
+  suffix.
+
 ### Graphical User Interface
 
 ### Graphics backend
--- a/libinterp/corefcn/jsonencode.cc	Tue Mar 12 15:06:31 2024 -0400
+++ b/libinterp/corefcn/jsonencode.cc	Thu Mar 14 17:28:46 2024 -0400
@@ -65,13 +65,13 @@
     {
       double value = obj.scalar_value ();
 
-      // Any numeric input from the interpreter will be in double type so in
-      // order to detect ints, we will check if the floor of the input and the
-      // input are equal using fabs (A - B) < epsilon method as it is more
-      // accurate.  If value > 999999, MATLAB will encode it in scientific
-      // notation (double).
-      if (fabs (floor (value) - value) < std::numeric_limits<double>::epsilon ()
-          && fabs (value) <= 999999)
+      // Detect floating point numbers which are actually integers by checking
+      // whether the number and the integer portion of the number are the same
+      // to within eps.
+      // FIXME: If value > 999999, MATLAB will encode it in scientific
+      // notation, but rapidJSON will output all digits.
+      if (fabs (trunc (value) - value) < std::numeric_limits<double>::epsilon ())
+
         writer.Int64 (value);
       // Possibly write NULL for non-finite values (-Inf, Inf, NaN, NA)
       else if (ConvertInfAndNaN && ! octave::math::isfinite (value))
@@ -79,6 +79,21 @@
       else
         writer.Double (value);
     }
+  else if (obj.isinteger ())
+    {
+       if (obj.is_uint64_type ())
+         {
+            uint64_t value = obj.uint64_value ();
+            writer.Uint64 (value);
+         }
+       else
+         {
+            // Write all other integers as 64-bit values and let RapidJSON
+            // determine number of digits to keep.
+            int64_t value = obj.int64_value ();
+            writer.Int64 (value);
+         }
+    }
   else if (obj.is_bool_scalar ())
     writer.Bool (obj.bool_value ());
   else
@@ -404,9 +419,10 @@
 encode (T& writer, const octave_value& obj, const bool& ConvertInfAndNaN)
 {
   if (obj.is_real_scalar ())
+    // Numeric scalars.
     encode_numeric (writer, obj, ConvertInfAndNaN);
-  // As I checked for scalars, this will detect numeric & logical arrays
   else if (obj.isnumeric () || obj.islogical ())
+    // Numeric and logical arrays.
     encode_array (writer, obj, ConvertInfAndNaN, obj.dims ());
   else if (obj.is_string ())
     encode_string (writer, obj, obj.dims ());
--- a/liboctave/array/CMatrix.cc	Tue Mar 12 15:06:31 2024 -0400
+++ b/liboctave/array/CMatrix.cc	Thu Mar 14 17:28:46 2024 -0400
@@ -28,6 +28,7 @@
 #endif
 
 #include <algorithm>
+#include <cmath>
 #include <complex>
 #include <istream>
 #include <limits>
@@ -733,6 +734,14 @@
   return anorm;
 }
 
+// Local function to check if matrix is singular based on rcond.
+static inline
+bool
+is_singular (const double rcond)
+{
+  return (std::abs (rcond) <= std::numeric_limits<double>::epsilon ());
+}
+
 ComplexMatrix
 ComplexMatrix::inverse () const
 {
@@ -1603,10 +1612,7 @@
           if (info != 0)
             info = -2;
 
-          // Prevent use of extra precision.
-          double rcond_plus_one = rcon + 1.0;
-
-          if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+          if (is_singular (rcon) || octave::math::isnan (rcon))
             {
               info = -2;
 
@@ -1702,10 +1708,7 @@
           if (info != 0)
             info = -2;
 
-          // Prevent use of extra precision.
-          double rcond_plus_one = rcon + 1.0;
-
-          if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+          if (is_singular (rcon) || octave::math::isnan (rcon))
             {
               info = -2;
 
@@ -1795,10 +1798,7 @@
                   if (info != 0)
                     info = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcon + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+                  if (is_singular (rcon) || octave::math::isnan (rcon))
                     {
                       info = -2;
 
@@ -1891,10 +1891,7 @@
                   if (info != 0)
                     info = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcon + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+                  if (is_singular (rcon) || octave::math::isnan (rcon))
                     {
                       if (sing_handler)
                         sing_handler (rcon);
--- a/liboctave/array/CSparse.cc	Tue Mar 12 15:06:31 2024 -0400
+++ b/liboctave/array/CSparse.cc	Thu Mar 14 17:28:46 2024 -0400
@@ -27,8 +27,10 @@
 #  include "config.h"
 #endif
 
+#include <cmath>
 #include <complex>
 #include <istream>
+#include <limits>
 #include <ostream>
 
 #include "quit.h"
@@ -651,6 +653,14 @@
   return retval;
 }
 
+// Local function to check if matrix is singular based on rcond.
+static inline
+bool
+is_singular (const double rcond)
+{
+  return (std::abs (rcond) <= std::numeric_limits<double>::epsilon ());
+}
+
 SparseComplexMatrix
 SparseComplexMatrix::inverse () const
 {
@@ -1723,10 +1733,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -2006,10 +2013,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -2236,10 +2240,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -2519,10 +2520,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -2769,10 +2767,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -3071,10 +3066,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -3324,10 +3316,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -3625,10 +3614,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -4413,10 +4399,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -4547,10 +4530,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -4684,10 +4664,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -4851,10 +4828,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -5027,10 +5001,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -5158,10 +5129,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -5297,10 +5265,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -5468,10 +5433,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -5633,11 +5595,8 @@
       else
         rcond = 1.;
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
       if (status == UMFPACK_WARNING_singular_matrix
-          || rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+          || is_singular (rcond) || octave::math::isnan (rcond))
         {
           UMFPACK_ZNAME (report_numeric) (Numeric, control);
 
@@ -5784,10 +5743,7 @@
             }
           else
             {
-              // Prevent use of extra precision.
-              double rcond_plus_one = rcond + 1.0;
-
-              if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+              if (is_singular (rcond) || octave::math::isnan (rcond))
                 {
                   err = -2;
 
@@ -6034,10 +5990,7 @@
             }
           else
             {
-              // Prevent use of extra precision.
-              double rcond_plus_one = rcond + 1.0;
-
-              if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+              if (is_singular (rcond) || octave::math::isnan (rcond))
                 {
                   err = -2;
 
@@ -6317,10 +6270,7 @@
             }
           else
             {
-              // Prevent use of extra precision.
-              double rcond_plus_one = rcond + 1.0;
-
-              if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+              if (is_singular (rcond) || octave::math::isnan (rcond))
                 {
                   err = -2;
 
@@ -6546,10 +6496,7 @@
             }
           else
             {
-              // Prevent use of extra precision.
-              double rcond_plus_one = rcond + 1.0;
-
-              if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+              if (is_singular (rcond) || octave::math::isnan (rcond))
                 {
                   err = -2;
 
@@ -6682,11 +6629,8 @@
               retval.maybe_compress ();
 
               rcond = Info (UMFPACK_RCOND);
-              // Prevent use of extra precision.
-              double rcond_plus_one = rcond + 1.0;
-
               if (status == UMFPACK_WARNING_singular_matrix
-                  || rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  || is_singular (rcond) || octave::math::isnan (rcond))
                 {
                   err = -2;
 
--- a/liboctave/array/dMatrix.cc	Tue Mar 12 15:06:31 2024 -0400
+++ b/liboctave/array/dMatrix.cc	Thu Mar 14 17:28:46 2024 -0400
@@ -28,6 +28,7 @@
 #endif
 
 #include <algorithm>
+#include <cmath>
 #include <istream>
 #include <limits>
 #include <ostream>
@@ -447,6 +448,14 @@
   return anorm;
 }
 
+// Local function to check if matrix is singular based on rcond.
+static inline
+bool
+is_singular (const double rcond)
+{
+  return (std::abs (rcond) <= std::numeric_limits<double>::epsilon ());
+}
+
 Matrix
 Matrix::inverse () const
 {
@@ -1274,10 +1283,7 @@
           if (info != 0)
             info = -2;
 
-          // Prevent use of extra precision.
-          double rcond_plus_one = rcon + 1.0;
-
-          if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+          if (is_singular (rcon) || octave::math::isnan (rcon))
             {
               info = -2;
 
@@ -1372,10 +1378,7 @@
           if (info != 0)
             info = -2;
 
-          // Prevent use of extra precision.
-          double rcond_plus_one = rcon + 1.0;
-
-          if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+          if (is_singular (rcon) || octave::math::isnan (rcon))
             {
               info = -2;
 
@@ -1461,10 +1464,7 @@
                   if (info != 0)
                     info = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcon + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+                  if (is_singular (rcon) || octave::math::isnan (rcon))
                     {
                       info = -2;
 
@@ -1551,10 +1551,7 @@
                   if (info != 0)
                     info = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcon + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+                  if (is_singular (rcon) || octave::math::isnan (rcon))
                     {
                       if (sing_handler)
                         sing_handler (rcon);
--- a/liboctave/array/dSparse.cc	Tue Mar 12 15:06:31 2024 -0400
+++ b/liboctave/array/dSparse.cc	Thu Mar 14 17:28:46 2024 -0400
@@ -27,7 +27,9 @@
 #  include "config.h"
 #endif
 
+#include <cmath>
 #include <istream>
+#include <limits>
 #include <ostream>
 
 #include "quit.h"
@@ -594,6 +596,14 @@
 
 */
 
+// Local function to check if matrix is singular based on rcond.
+static inline
+bool
+is_singular (const double rcond)
+{
+  return (std::abs (rcond) <= std::numeric_limits<double>::epsilon ());
+}
+
 SparseMatrix
 SparseMatrix::inverse () const
 {
@@ -1657,10 +1667,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -1940,10 +1947,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -2172,10 +2176,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -2457,10 +2458,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -2711,10 +2709,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -3012,10 +3007,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -3267,10 +3259,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -3570,10 +3559,7 @@
             octave::warn_singular_matrix (rcond);
         }
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
-      if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+      if (is_singular (rcond) || octave::math::isnan (rcond))
         {
           err = -2;
 
@@ -4363,10 +4349,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -4496,10 +4479,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -4633,10 +4613,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -4800,10 +4777,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -4977,10 +4951,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -5142,10 +5113,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -5304,10 +5272,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -5498,10 +5463,7 @@
                   if (err != 0)
                     err = -2;
 
-                  // Prevent use of extra precision.
-                  double rcond_plus_one = rcond + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+                  if (is_singular (rcond) || octave::math::isnan (rcond))
                     {
                       err = -2;
 
@@ -5674,11 +5636,8 @@
       else
         rcond = 1.;
 
-      // Prevent use of extra precision.
-      double rcond_plus_one = rcond + 1.0;
-
       if (status == UMFPACK_WARNING_singular_matrix
-          || rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+          || is_singular (rcond) || octave::math::isnan (rcond))
         {
           UMFPACK_DNAME (report_numeric) (Numeric, control);
 
@@ -5826,10 +5785,7 @@
             }
           else
             {
-              // Prevent use of extra precision.
-              double rcond_plus_one = rcond + 1.0;
-
-              if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+              if (is_singular (rcond) || octave::math::isnan (rcond))
                 {
                   err = -2;
 
@@ -6048,10 +6004,7 @@
             }
           else
             {
-              // Prevent use of extra precision.
-              double rcond_plus_one = rcond + 1.0;
-
-              if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+              if (is_singular (rcond) || octave::math::isnan (rcond))
                 {
                   err = -2;
 
@@ -6302,10 +6255,7 @@
             }
           else
             {
-              // Prevent use of extra precision.
-              double rcond_plus_one = rcond + 1.0;
-
-              if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+              if (is_singular (rcond) || octave::math::isnan (rcond))
                 {
                   err = -2;
 
@@ -6545,10 +6495,7 @@
             }
           else
             {
-              // Prevent use of extra precision.
-              double rcond_plus_one = rcond + 1.0;
-
-              if (rcond_plus_one == 1.0 || octave::math::isnan (rcond))
+              if (is_singular (rcond) || octave::math::isnan (rcond))
                 {
                   err = -2;
 
--- a/liboctave/array/fCMatrix.cc	Tue Mar 12 15:06:31 2024 -0400
+++ b/liboctave/array/fCMatrix.cc	Thu Mar 14 17:28:46 2024 -0400
@@ -28,6 +28,7 @@
 #endif
 
 #include <algorithm>
+#include <cmath>
 #include <complex>
 #include <istream>
 #include <limits>
@@ -736,6 +737,14 @@
   return anorm;
 }
 
+// Local function to check if matrix is singular based on rcond.
+static inline
+bool
+is_singular (const float rcond)
+{
+  return (std::abs (rcond) <= std::numeric_limits<float>::epsilon ());
+}
+
 FloatComplexMatrix
 FloatComplexMatrix::inverse () const
 {
@@ -1605,10 +1614,7 @@
                   if (info != 0)
                     info = -2;
 
-                  // Prevent use of extra precision.
-                  float rcond_plus_one = rcon + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+                  if (is_singular (rcon) || octave::math::isnan (rcon))
                     {
                       info = -2;
 
@@ -1708,10 +1714,7 @@
                   if (info != 0)
                     info = -2;
 
-                  // Prevent use of extra precision.
-                  float rcond_plus_one = rcon + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+                  if (is_singular (rcon) || octave::math::isnan (rcon))
                     {
                       info = -2;
 
@@ -1805,10 +1808,7 @@
                   if (info != 0)
                     info = -2;
 
-                  // Prevent use of extra precision.
-                  float rcond_plus_one = rcon + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+                  if (is_singular (rcon) || octave::math::isnan (rcon))
                     {
                       info = -2;
 
@@ -1901,10 +1901,7 @@
                   if (info != 0)
                     info = -2;
 
-                  // Prevent use of extra precision.
-                  float rcond_plus_one = rcon + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+                  if (is_singular (rcon) || octave::math::isnan (rcon))
                     {
                       if (sing_handler)
                         sing_handler (rcon);
--- a/liboctave/array/fMatrix.cc	Tue Mar 12 15:06:31 2024 -0400
+++ b/liboctave/array/fMatrix.cc	Thu Mar 14 17:28:46 2024 -0400
@@ -28,6 +28,7 @@
 #endif
 
 #include <algorithm>
+#include <cmath>
 #include <istream>
 #include <limits>
 #include <ostream>
@@ -453,6 +454,14 @@
   return anorm;
 }
 
+// Local function to check if matrix is singular based on rcond.
+static inline
+bool
+is_singular (const float rcond)
+{
+  return (std::abs (rcond) <= std::numeric_limits<float>::epsilon ());
+}
+
 FloatMatrix
 FloatMatrix::inverse () const
 {
@@ -1284,10 +1293,7 @@
                   if (info != 0)
                     info = -2;
 
-                  // Prevent use of extra precision.
-                  float rcond_plus_one = rcon + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+                  if (is_singular (rcon) || octave::math::isnan (rcon))
                     {
                       info = -2;
 
@@ -1388,10 +1394,7 @@
                   if (info != 0)
                     info = -2;
 
-                  // Prevent use of extra precision.
-                  float rcond_plus_one = rcon + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+                  if (is_singular (rcon) || octave::math::isnan (rcon))
                     {
                       info = -2;
 
@@ -1485,10 +1488,7 @@
                   if (info != 0)
                     info = -2;
 
-                  // Prevent use of extra precision.
-                  float rcond_plus_one = rcon + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+                  if (is_singular (rcon) || octave::math::isnan (rcon))
                     {
                       info = -2;
 
@@ -1572,10 +1572,7 @@
                   if (info != 0)
                     info = -2;
 
-                  // Prevent use of extra precision.
-                  float rcond_plus_one = rcon + 1.0;
-
-                  if (rcond_plus_one == 1.0 || octave::math::isnan (rcon))
+                  if (is_singular (rcon) || octave::math::isnan (rcon))
                     {
                       if (sing_handler)
                         sing_handler (rcon);
--- a/scripts/general/nextpow2.m	Tue Mar 12 15:06:31 2024 -0400
+++ b/scripts/general/nextpow2.m	Thu Mar 14 17:28:46 2024 -0400
@@ -25,16 +25,17 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {} {@var{n} =} nextpow2 (@var{x})
-## Compute the exponent for the smallest power of two larger than the input.
+## Compute the exponent of the next power of two not smaller than the input.
 ##
-## For each element in the input array @var{x}, return the first integer
+## For each element in the input array @var{x}, return the smallest integer
 ## @var{n} such that
 ## @tex
 ## $2^n \ge |x|$.
 ## @end tex
 ## @ifnottex
-## 2^n @geq{} abs (x).
+## @code{2^@var{n} @geq{} abs (@var{x})}.
 ## @end ifnottex
+## For input elements equal to zero, return zero.
 ##
 ## @seealso{pow2, log2}
 ## @end deftypefn
@@ -47,10 +48,23 @@
 
   if (! isnumeric (x))
     error ("nextpow2: X must be numeric");
+  elseif (! isreal (x))
+    error ("nextpow2: X must be real");
   endif
 
-  n = ceil (log2 (abs (x)));
-  n(x == 0) = 0;  # special case
+  [f, n] = log2 (abs (x));
+  n(f == 0.5)--;
+
+  if (isfloat (x))
+    idx_nan = isnan (x);
+    n(idx_nan) = x(idx_nan);
+    n(isinf (x)) = Inf;
+  else
+    n = cast (n, class (x));
+    if (intmax (x) > flintmax ())
+      n((2 .^ n) < abs (x))++;
+    endif
+  endif
 
 endfunction
 
@@ -70,8 +84,75 @@
 %!assert (nextpow2 (Inf), Inf)
 %!assert (nextpow2 (-Inf), Inf)
 %!assert (nextpow2 (NaN), NaN)
-%!assert (nextpow2 ([1, Inf, 3, -Inf, 9, NaN]), [0, Inf, 2, Inf, 4, NaN])
+%!assert (nextpow2 (NA), NA)
+%!assert (nextpow2 ([1, Inf, 3, -Inf, 9, NaN, NA]), ...
+%!                  [0, Inf, 2,  Inf, 4, NaN, NA])
+
+%!test
+%! p = (-1074:1023).';
+%! x = 2 .^ p;
+%! x = [x, x + eps(x)];
+%! x = [x, -x];
+%! n = nextpow2 (x);
+%! assert (n(:, 1), p);
+%! assert (n(:, 3), p);
+%! assert (n(:, 2), p + 1);
+%! assert (n(:, 4), p + 1);
+
+%!assert (nextpow2 (realmax ()), 1024)
+%!assert (nextpow2 (-realmax ()), 1024)
+
+%!test
+%! p = single (-149:127).';
+%! x = 2 .^ p;
+%! x = [x, x + eps(x)];
+%! x = [x, -x];
+%! n = nextpow2 (x);
+%! assert (n(:, 1), p);
+%! assert (n(:, 3), p);
+%! assert (n(:, 2), p + 1);
+%! assert (n(:, 4), p + 1);
+
+%!assert (nextpow2 (realmax ('single')), single (128))
+%!assert (nextpow2 (-realmax ('single')), single (128))
+
+%!test
+%! p = int32 (0:30).';
+%! x = 2 .^ p;
+%! x = [x, x + 1];
+%! x = [x, -x];
+%! n = nextpow2 (x);
+%! assert (n(:, 1), p);
+%! assert (n(:, 3), p);
+%! assert (n(:, 2), p + 1);
+%! assert (n(:, 4), p + 1);
+
+%!assert (nextpow2 (int32 (0)), int32 (0))
+%!assert (nextpow2 (intmin ('int32')), int32 (31))
+%!assert (nextpow2 (intmax ('int32')), int32 (31))
+
+%!assert (nextpow2 (uint32 (0)), uint32 (0))
+%!assert (nextpow2 (intmax ('uint32')), uint32 (32))
+
+%!test
+%! p = int64 (0:62).';
+%! x = 2 .^ p;
+%! x = [x, x + 1];
+%! x = [x, -x];
+%! n = nextpow2 (x);
+%! assert (n(:, 1), p);
+%! assert (n(:, 3), p);
+%! assert (n(:, 2), p + 1);
+%! assert (n(:, 4), p + 1);
+
+%!assert (nextpow2 (int64 (0)), int64 (0))
+%!assert (nextpow2 (intmin ('int64')), int64 (63))
+%!assert (nextpow2 (intmax ('int64')), int64 (63))
+
+%!assert (nextpow2 (uint64 (0)), uint64 (0))
+%!assert (nextpow2 (intmax ('uint64')), uint64 (64))
 
 ## Test input validation
 %!error <Invalid call> nextpow2 ()
 %!error <X must be numeric> nextpow2 ("t")
+%!error <X must be real> nextpow2 (1 + 2i)
--- a/scripts/plot/draw/patch.m	Tue Mar 12 15:06:31 2024 -0400
+++ b/scripts/plot/draw/patch.m	Thu Mar 14 17:28:46 2024 -0400
@@ -314,24 +314,6 @@
 %!   close (hf);
 %! end_unwind_protect
 
-%!test <*65421>
-%! hf = figure ("visible", "off");
-%! unwind_protect
-%!   h1 = patch ("Vertices",[0, 0; 0, 1; 1, 0;1, 1], ...
-%!             "Faces", [1, 2, 3; 2, 3, 4], "CData", 1);
-%!   h2 = patch ("Vertices",[0, 0; 0, 1; 1, 0;1, 1], "CData", 1, ...
-%!             "Faces", [1, 2, 3; 2, 3, 4]);
-%!   h1_data = get (h1);
-%!   h2_data = get (h2);
-%!   assert ({h1_data.xdata, h1_data.ydata}, ...
-%!                  {[0, 0; 0, 1; 1, 1], [0, 1; 1, 0; 0, 1]});
-%!   assert ({h1_data.xdata,  h1_data.ydata}, {h2_data.xdata, h2_data.ydata});
-%!   assert (h1_data.faces, [1, 2, 3; 4, 5, 6]);
-%!   assert (h1_data.faces, h2_data.faces);
-%! unwind_protect_cleanup
-%!   close (hf);
-%! end_unwind_protect
-
 ## Test input validation
 %!error <invalid color specification C> patch (1, 1, 'x')
 %!error <invalid TrueColor data C> patch (1, 1, rand (1,2,3))
--- a/scripts/plot/draw/private/__patch__.m	Tue Mar 12 15:06:31 2024 -0400
+++ b/scripts/plot/draw/private/__patch__.m	Thu Mar 14 17:28:46 2024 -0400
@@ -176,16 +176,6 @@
     args = varargin;
   endif
 
-  ## All args now Property/Value pairs.
-  ## Ensure geometry properties come before other properties (see bug #65421).
-  geom_props = {"xdata", "ydata", "zdata", "faces", "vertices"};
-  geom_args = or (cellfun (@strcmpi, {args(1:2:end)}, geom_props, ...
-                           "UniformOutput", false){:});
-  neworder = zeros (size (args));
-  neworder(1:2:end) = [find(geom_args), find(! geom_args)] * 2 - 1;
-  neworder(2:2:end) = neworder(1:2:end) + 1;
-  args = args(neworder);
-
   if (isempty (p))
     p = gca ();
   endif
--- a/scripts/startup/site-rcfile	Tue Mar 12 15:06:31 2024 -0400
+++ b/scripts/startup/site-rcfile	Thu Mar 14 17:28:46 2024 -0400
@@ -6,19 +6,33 @@
 ## This file contains commands that should be executed each time Octave starts
 ## for every user at this site.
 
-if ispc () && isguirunning () ...
-    && ~strcmp (winqueryreg ("HKEY_CURRENT_USER", 'Console\%%Startup', "DelegationConsole"), ...
-                "{B23D10C0-E52E-411E-9D5B-C09FDF709C7D}")
-  warn_str = ["WARNING: You are using an incompatible Windows configuration!\n", ...
-              "Microsoft's new Terminal App is not compatible with Octave.\n", ...
-              "Please follow the instructions on the following page and set the ", ...
-              "default terminal to \"Windows Console Host\":\n", ...
-              "https://octave.discourse.group/t/4981/"];
-  warning ("octave:terminal-app", warn_str);
-  answer = questdlg ([warn_str, "\n\nWould you like to open that page in your browser?"], ...
-                     "Incompatible Configuration", "Yes", "No", "Yes");
-  if strcmp (answer, "Yes")
-    system ("start https://octave.discourse.group/t/4981/");
+if (ispc () && isguirunning ())
+  try
+    is_windows_console_host = ...
+      strcmp (winqueryreg ("HKEY_CURRENT_USER", 'Console\%%Startup', "DelegationConsole"), ...
+              "{B23D10C0-E52E-411E-9D5B-C09FDF709C7D}");
+  catch
+    ## The above might fail for old versions of Windows 10 where that
+    ## registry key didn't exist.  Assume that the Windows Console Host
+    ## is being used in this case.
+    is_windows_console_host = true;
+  end_try_catch
+
+  if (! is_windows_console_host)
+    warn_str = ["WARNING: You are using an incompatible Windows configuration!\n", ...
+                "Microsoft's new Terminal App is not compatible with Octave.\n", ...
+                "Please follow the instructions on the following page and set the ", ...
+                "default terminal to \"Windows Console Host\":\n", ...
+                "https://octave.discourse.group/t/4981/"];
+    warning ("octave:terminal-app", warn_str);
+    answer = questdlg ([warn_str, "\n\nWould you like to open that page in your browser?"], ...
+                       "Incompatible Configuration", "Yes", "No", "Yes");
+    if (strcmp (answer, "Yes"))
+      system ("start https://octave.discourse.group/t/4981/");
+    endif
+    clear warn_str answer
   endif
-  clear warn_str answer
+
+  clear is_windows_console_host
+
 endif
--- a/test/json/jsonencode_BIST.tst	Tue Mar 12 15:06:31 2024 -0400
+++ b/test/json/jsonencode_BIST.tst	Thu Mar 14 17:28:46 2024 -0400
@@ -17,6 +17,8 @@
 %! assert (isequal (jsonencode (50.025), '50.025'));
 %! %% FIXME: Uncomment when bug #64960 is fixed
 %! %% assert (isequal (jsonencode (single (50.025)), '50.025'));
+%! assert (isequal (jsonencode (uint64 (1e6)), '1000000'));
+%! assert (isequal (jsonencode (int64 (-1e6)), '-1000000'));
 %! assert (isequal (jsonencode (NaN), 'null'));
 %! assert (isequal (jsonencode (NA), 'null'));    % Octave-only test
 %! assert (isequal (jsonencode (Inf), 'null'));
@@ -112,6 +114,8 @@
 %!testif HAVE_RAPIDJSON
 %! assert (isequal (jsonencode ([]), '[]'));
 %! assert (isequal (jsonencode ([1, 2, 3, 4]), '[1,2,3,4]'));
+%! % Matlab encodes flints with values above 1e6-1 in scientific notation.  Octave writes integers.
+%! assert (isequal (jsonencode ([1.23e6, 2]), '[1230000,2]'));
 %! assert (isequal (jsonencode ([true; false; true]), '[true,false,true]'));
 
 %% Test arrays