OK. I noticed there is a PRECISION input variable. Some of the same issues might apply there:

I already changed the default precision that Octave saves data files for exactly this reason. See
For num2str, I think user's are going to want compatibility so we should leave this at 16 digits.

That was easy, good.
I wonder if there should be a test to check the IEEE 754 rule I listed below regarding the conversion to a string and back from a string. (Comparing against an actual string might already achieve this.) That is, there should be some mode in which printing out the numbers and then bringing them back into Octave results in the exact same internal representation. Here's an example:
Note how b no longer equals a. If someone were to save their data into a file using num2str in order to make is "portable", s/he might not be happy about the above fact.
The minor capping change from 16 to 17 digits fixes this. I tried the following:
and the test above passes:
Note the extra digit of resolution.
Is there something to take into account that the number of digits resolution can vary from 1517? Is "shimming" still needed when the number of valid resolution digits is 15 for IEEE 754 when typically we'd want to ensure 17 digit resolution can be addressed?

The fix was actually quite simple. Octave now checks whether there are more than 15 digits to display and if there are then it uses the floating point format rather than integer format. All of the BIST tests now pass. I have marked them as passing so if they start failing again it will show up as a regression. For all of the above, see this cset (https://hg.savannah.gnu.org/hgweb/octave/rev/e55fb9685803).
Marking as fixed and closing report.

Matlab behavior has changed since this bug was originally reported. This is all to the good because sprintf is now compatible without us having to change anything. Mixed floating point / integer arrays are also displayed correctly.
The remaining difference is integer arrays with large values. I have retitle the bug report to reflect that. I'm also changing the classification to "Matlab Compatibility".
I pushed a changeset which updates the BIST tests for num2str to focus on this remaining difference. See https://hg.savannah.gnu.org/hgweb/octave/rev/8f8d3fef29a8.

I noticed this known bug in the buildbot results. It doesn't seem noted in any of the discussion posts, so I thought I'd mention that the Octave result for Rik's example:
is the same as what A.J. has shown for Matlab. That happens when Octave is attempting to find a reasonable display width and the number magnitudes span a very large range.
Otherwise, Octave is doing something different for narrow range, e.g.,:
So it would seem the same underlying exponent display mechanism is already present, but not necessarily active by default. And it isn't quite the same as displaying the values:
However, this probably doesn't address the "shim" issue that Rik mentioned in Comment #8. I don't know what one can consider valid or invalid. Using this rule from Wikipedia:
"
If a decimal string with at most 15 significant digits is converted to IEEE 754 doubleprecision representation, and then converted back to a decimal string with the same number of digits, the final result should match the original string. If an IEEE 754 doubleprecision number is converted to a decimal string with at least 17 significant digits, and then converted back to doubleprecision representation, the final result must match the original number.[1]
"
The Matlab rounding seems to stay within the rule. (As does the Octave nonrounding.) It would seem that those last decimals outside resolution are extraneous. Perhaps what those decimals turn out to be is compiler dependent, or CPU dependent, or library dependent. The rounding of the 18th significant digit might be a way to make all platforms have a consistent output for num2str().
I don't see it as too big of an issue. However, if Octave is left as is, then this can't be the test:
because the result will never be 100000000000000000000000. And changing it to
would likely fail on some systems. Any test should really only focus on the 1517 significant digits, whether that be the test itself (by somehow extracting the first 17 characters) or by internally forcing the remaining extraneous digits to something known (i.e., 0).
One last note. Wikipedia mentions that for some C/C++ compilers there is a possible issue of double rounding with x86 32bit systems.

Matlab's behavior has changed since R2014b. Here's examples from R2018a:

@Joe: Could you run this additional test and report back the result?

Results from Matlab will be interesting, but I doubt that they test that each number to be printed is an exact power of two. There are 1024 of those numbers compared to 2^53 (9e15) numbers representable in the mantissa. It really, really fails the 80/20 rule to worry about them.
According to Matlab's documentation for both sprintf and num2str, they are aware of the issue
Also, according to the documentation for num2str
That's fine, but my guess is that Matlab just uses a form of the %g format for both floating point and integer numbers. Octave, however, tries to switch format based on whether the input is an integer. The code is
I bet changing the integer case would fix some of this.

1517 decimal digits is true for arbitrary numbers, but powers of 2 can be converted to decimal exactly, up to 2^1023. So limiting to 1517 decimal digits doesn't make sense for ALL 64bit IEEE floating point values.
But yes, we should be switching to exponential display using some kind of rules that produce "pleasing" results. One problem is deciding what those rules should be.
What does Matlab do for num2str (2^512)? What about sprintf ('%.0f', 2^512)?
Also, if we "clean up" the output form our printf functions, then they will differ from what people will get when they use C++ streams or C stdio functions. Is that really what we want? If so, then we might want to make our functions easily available for use in .oct files.
A related issue is the max precision problem in bug #53456.

Adding in jwe because the behavior is fascinating. From Hartmut's tests in comment #3, the Matlab sprintf function returns
where the '1' in the sectond position is very real.
Octave's answer for the same code is
If I align the two
it seems pretty clear what Matlab has done. First, Octave uses the C library routine for sprintf so we get whatever default behavior is implemented when the precision exceeds that of the underlying number. But Matlab has written a shim layer for sprintf which calls the sprintf library, but then cleans up the result. However, they haven't been too clever about it. IEEE854 doubles have a variable precision of 1517 decimal digits. The extra '1' occurs because they are rounding the digit '9' which is the 18 significant figure and not valid.
In any case, once Matlab has printed 17 digits, it pads the rest of the string with zeros. This is pretty easy to do in C++ with the substr() function or operator[] access and a for loop.
So should Octave do something similar? And if so, where should it be done? It could be done just in our sprintf routine, but then other actions like printf would diverge in behavior. That means it would probably be better to do it in octave::stream.

@Joe: Are you proposing that the two assert statements be added as BIST tests to num2str.m?
Also, can you determine when Matlab switches from decimal to exponential notation?
Try running this code:
Octave never switches over to exponential notation

Oh sorry that's me creating a new one to make sure I don't get confused. I also realized I didn't double check my outputs with Matlab. It my comment should have read:
%! assert (num2str (1e23), "9.999999999999999e+22");
%! assert (num2str (1e25), "1e+25");
Also int2str has the same bug, how can I link that function to this bug?

Your code uses num2strE which is not an Octave core function. Try 'which num2strE' to find the location. You will need to report a bug against whoever wrote that function.

I think the test should read:
%! assert (num2strE (1e23), "1e+23");
%! assert (num2strE (12345678901234567890), "1.234567890123457e+20");
Also int2str has the same bug, how can I link that function to this bug?

Matlab R2014b:
(The second 1 in the first result is real.)

For comparison, could someone try the following in Matlab?

This is still present in Octave 4.2.0.

Example code:
This should be '1' with 25 zeros after it.
Matlab correctly masks large integer inputs to just 16 significant digits.
For something really wacky try
