printf integer format compatibility

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

printf integer format compatibility

John W. Eaton
Administrator
While looking at some problems with printing 64-bit integer values with
printf, I found that Matlab's printf function silently switches from
integer formats like '%d' or '%u' to '%e' when values are not integers
or when they exceed the maximum value possible for a 64-bit integer
type.  Matlab also seems to be ignoring size specifications for integer
formats, so although formats like '%hd' (short int) are accepted, there
seems to be no change in output compared to just using '%d'.  And '%d'
always handles up to 64-bit integers without needing 'l' or 'll'.

I checked in the following change on the default branch:

   http://hg.savannah.gnu.org/hgweb/octave/rev/491b0adfec95

Now you can expect behavior like the following, which appears to be
compatible with Matlab:

   sprintf('%d',intmin('int32'))    %% ans = -2147483648
   sprintf('%d',intmax('int32'))    %% ans = 2147483647
   sprintf('%d',intmin('int64'))    %% ans = -9223372036854775808
   sprintf('%d',intmax('int64'))    %% ans = 9223372036854775807
   sprintf('%d',intmin('uint32'))   %% ans = 0
   sprintf('%d',intmax('uint32'))   %% ans = 4294967295
   sprintf('%d',intmin('uint64'))   %% ans = 0
   sprintf('%d',intmax('uint64'))   %% ans = 1.84467e+19
   sprintf('%d',realmin('single'))  %% ans = 1.17549e-38
   sprintf('%d',realmax('single'))  %% ans = 3.40282e+38
   sprintf('%d',realmin('double'))  %% ans = 2.22507e-308
   sprintf('%d',realmax('double'))  %% ans = 1.79769e+308

There is still one difference:  Matlab switches to '%e' and Octave is
currently switching to '%g'.  Should we follow Matlab exactly here?  I
generally prefer '%g' over '%e' because it seems easier to me to read
numbers without unnecessary e+04 style exponents appended.

This change caused a few new test failures in cases where '%d' was
previously assumed to always produce an integer result.  I fixed one
problem in the datestr function by rounding the printf argument that was
used with a '%d' format.  I could use some help fixing the stemleaf
function since I'm not sure what the intent is there.

jwe




Reply | Threaded
Open this post in threaded view
|

Re: printf integer format compatibility

Michael Godfrey
On 04/16/2014 02:50 PM, John W. Eaton wrote:
> I could use some help fixing the stemleaf function since I'm not sure
> what the intent is there.
As i said, I have looked at the first failure, but it passes outside
make check...

The test returns a result which shows the expected result of the call
to stemleaf. When run outside make check the result matches the
expected string. Also, only 4 of the 17 tests fail even though the
tests follow the same sequence, but with differing input data.

I will look at it more.

Michael


Reply | Threaded
Open this post in threaded view
|

Re: printf integer format compatibility

Michael Godfrey
In reply to this post by John W. Eaton
On 04/16/2014 02:50 PM, John W. Eaton wrote:
> This change caused a few new test failures in cases where '%d' was
> previously assumed to always produce an integer result.  I fixed one
> problem in the datestr function by rounding the printf argument that
> was used with a '%d' format.  I could use some help fixing the
> stemleaf function since I'm not sure what the intent is there.
I found the problem; there are cases where previously an integer value was
printed, now the value, for example, is 35.5.  I will check on what
conversion
I was using in that case and decide how to fix it.

Are you sure that the change you made is what I intend to stick with?

Michael


Reply | Threaded
Open this post in threaded view
|

Re: printf integer format compatibility

Michael Godfrey
In reply to this post by John W. Eaton
On 04/16/2014 02:50 PM, John W. Eaton wrote:
> This change caused a few new test failures in cases where '%d' was
> previously assumed to always produce an integer result.  I fixed one
> problem in the datestr function by rounding the printf argument that
> was used with a '%d' format.  I could use some help fixing the
> stemleaf function since I'm not sure what the intent is there.
>
> jwe
>
As I said, the fact that %d now produces non-integer results in some
cases is the
cause of the stemleaf.m failures.  Right now, I think that this actually
was a coding error
in stemleaf.m: I was allowing a non-integer step size when it should be
integer.

But, I need to think about this a bit more before committing the change.
The fact that the
changed code passes the tests (also revised) under previous version of
Octave is a good sign.

I suspect that there will be some other places where this change in the
behavior
of %d will reveal problems.

Michael


Reply | Threaded
Open this post in threaded view
|

Re: printf integer format compatibility

John W. Eaton
Administrator
In reply to this post by Michael Godfrey
On 04/16/2014 05:54 PM, Michael D. Godfrey wrote:

> I found the problem; there are cases where previously an integer value was
> printed, now the value, for example, is 35.5.  I will check on what
> conversion
> I was using in that case and decide how to fix it.

I think it is using '%d' but the value that is being printed is not an
integer.  So previously it was truncated.  Now it displays a decimal
fraction.

> Are you sure that the change you made is what I intend to stick with?

Yes, I intend to keep this for compatibility reasons.

jwe



Reply | Threaded
Open this post in threaded view
|

Re: printf integer format compatibility

John W. Eaton
Administrator
In reply to this post by Michael Godfrey
On 04/16/2014 07:00 PM, Michael D. Godfrey wrote:

> I suspect that there will be some other places where this change in the
> behavior
> of %d will reveal problems.

Yes, I'm sure it will.  I added the following text to the NEWS file:

    ** Integer formats used in the printf family of functions now work for
       64-bit integers and are more compatible with Matlab when printing
       non-integer values.  Now instead of truncating, Octave will switch
       the effective format to '%g' in the following circumstances:

         * the value of an integer type (int8, uint32, etc.) value exceeds
           the maximum for the format specifier.  For '%d', the limit is
           intmax ('int64') and for '%u' it is intmax ('uint64').

         * round(x) != x or the value is outside the range allowed by the
           integer format specifier.

       There is still one difference:  Matlab switches to '%e' and Octave
       is currently switching to '%g'.

What do people think about using '%g' instead of '%e' as Matlab does?
Should we just go ahead and use '%e'?

jwe



Reply | Threaded
Open this post in threaded view
|

Re: printf integer format compatibility

Michael Godfrey
On 04/17/2014 01:24 AM, John W. Eaton wrote:

> On 04/16/2014 07:00 PM, Michael D. Godfrey wrote:
>
>> I suspect that there will be some other places where this change in the
>> behavior
>> of %d will reveal problems.
>
> Yes, I'm sure it will.  I added the following text to the NEWS file:
>
>    ** Integer formats used in the printf family of functions now work for
>       64-bit integers and are more compatible with Matlab when printing
>       non-integer values.  Now instead of truncating, Octave will switch
>       the effective format to '%g' in the following circumstances:
>
>         * the value of an integer type (int8, uint32, etc.) value exceeds
>           the maximum for the format specifier.  For '%d', the limit is
>           intmax ('int64') and for '%u' it is intmax ('uint64').
>
>         * round(x) != x or the value is outside the range allowed by the
>           integer format specifier.
>
>       There is still one difference:  Matlab switches to '%e' and Octave
>       is currently switching to '%g'.
>
> What do people think about using '%g' instead of '%e' as Matlab does?
> Should we just go ahead and use '%e'?
>
> jwe
John,

The changeset attached to bug #42132 corrects the problem in stemleaf.m.

I will think a bit about the %g vs. %e question...

Michael


Reply | Threaded
Open this post in threaded view
|

Re: printf integer format compatibility

Michael Godfrey
In reply to this post by John W. Eaton
On 04/17/2014 01:24 AM, John W. Eaton wrote:
> What do people think about using '%g' instead of '%e' as Matlab does?
> Should we just go ahead and use '%e'?
>
> jwe
I sort of go with %e. But, I also noticed that the switch from
%g to %e for just
x = pi*1000
then
x  pi*10000

does not match up with when %g switches.

Maybe another argument for %e?
Michael