diff libinterp/octave-value/ov.cc @ 28588:ee9b1081471f

allow integer constants > flintmax to be represented exactly (bug #45945) * ov-magic-int.h, ov-magic-int.cc: New files to provide "magic" integer data type that can store integer constants larger than flintmax but that behaves like a double constant in nearly all cases. The primary exception is when the value is processed by the int64 and uint64 functions. * libinterp/octave-value/module.mk: Update. * op-mi.cc: New file. Provide unary + and - operators for magic integers so that explicit positive or negative magic integers will work as expected. * libinterp/operators/module.mk: Update. * ov-base.h (octave_base_value::is_magic_int): New virtual function. * ov.h, ov.cc (octave_value::is_magic_int): New function. (octave_value::storable_value, octave_value::make_storable_value): Also handle magic integer values. (octave_value::install_types): Install octave_magic_int and octave_magic_uint types. * lex.ll (flintmax): New static function. (base_lexer::handle_number<10>): Create magic integers from constants that contain only digits and have values in the range flintmax to std::numeric_limits<uint64_t>::max(). * pt-eval.cc (tree_evaluator::bind_ans): Display stored value.
author John W. Eaton <jwe@octave.org>
date Mon, 20 Jul 2020 17:43:16 -0400
parents d4563c5d4060
children e70c859c4bff
line wrap: on
line diff
--- a/libinterp/octave-value/ov.cc	Fri Jul 17 14:36:47 2020 -0700
+++ b/libinterp/octave-value/ov.cc	Mon Jul 20 17:43:16 2020 -0400
@@ -76,6 +76,7 @@
 #include "ov-usr-fcn.h"
 #include "ov-fcn-handle.h"
 #include "ov-typeinfo.h"
+#include "ov-magic-int.h"
 #include "ov-null-mat.h"
 #include "ov-lazy-idx.h"
 #include "ov-java.h"
@@ -2123,6 +2124,8 @@
   octave_value retval = *this;
   if (isnull ())
     retval = octave_value (rep->empty_clone ());
+  else if (is_magic_int ())
+    retval = octave_value (rep->double_value ());
   else
     retval.maybe_economize ();
 
@@ -2139,6 +2142,13 @@
         delete rep;
       rep = rc;
     }
+  else if (is_magic_int ())
+    {
+      octave_base_value *rc = new octave_scalar (rep->double_value ());
+      if (--rep->count == 0)
+        delete rep;
+      rep = rc;
+    }
   else
     maybe_economize ();
 }
@@ -3022,6 +3032,8 @@
   octave_float_complex_matrix::register_type (ti);
   octave_float_complex_diag_matrix::register_type (ti);
   octave_perm_matrix::register_type (ti);
+  octave_magic_int::register_type (ti);
+  octave_magic_uint::register_type (ti);
   octave_null_matrix::register_type (ti);
   octave_null_str::register_type (ti);
   octave_null_sq_str::register_type (ti);