On Fri, Jun 17, 2011 at 2:46 PM, Derek Homeier <derek@astro.physik.uni-goettingen.de> wrote:
On 17.06.2011, at 8:05PM, Mark Wiebe wrote:

> On Thu, Jun 16, 2011 at 8:18 PM, Derek Homeier <derek@astro.physik.uni-goettingen.de> wrote:
>> On 17.06.2011, at 2:02AM, Mark Wiebe wrote:
>>
>> >> ok, that was a lengthy hunt, but it's in printing the string in make_iso_8601_date:
>> >>
>> >>    tmplen = snprintf(substr, sublen, "%04" NPY_INT64_FMT, dts->year);
>> >>    fprintf(stderr, "printed %d[%d]: dts->year=%lld: %s\n", tmplen, sublen, dts->year, substr);
>> >>
>> >> produces
>> >>
>> >> >>> np.datetime64('1970-03-23 20:00:00Z', 'D')
>> >> printed 4[62]: dts->year=1970: 0000
>> >> numpy.datetime64('0000-03-23','D')
>> >>
>> >> It seems snprintf is not using the correct format for INT64 (as I happened to do in fprintf before
>> >> realising I had to use "%lld" ;-) - could it be this is a general issue, which just does not show up
>> >> on little-endian machines because they happen to pass the right half of the int64 to printf?
>> >> BTW, how is this supposed to be handled (in 4 digits) if the year is indeed beyond the 32bit range
>> >> (i.e. >~ 0.3 Hubble times...)? Just wondering if one could simply cast it to int32 before print.
>> >>
>> > I'd prefer to fix the NPY_INT64_FMT macro. There's no point in having it if it doesn't work... What is NumPy setting it to for that platform?
>> >
>> Of course (just felt somewhat lost among all the #defines). It clearly seems to be mis-constructed
>> on PowerPC 32:
>> NPY_SIZEOF_LONG is 4, thus NPY_INT64_FMT is set to NPY_LONGLONG_FMT - "Ld",
>> but this does not seem to handle int64 on big-endian Macs - explicitly printing "%Ld", dts->year
>> also produces 0.
>> Changing the snprintf format to "%04" "lld" produces the correct output, so if nothing else
>> avails, I suggest to put something like
>>
>> #  elseif (defined(__ppc__)  || defined(__ppc64__))
>>     #define LONGLONG_FMT   "lld"
>>     #define ULONGLONG_FMT  "llu"
>> #  else
>>
>> into npy_common.h (or possibly simply "defined(__APPLE__)", since %lld seems to
>> work on 32bit i386 Macs just as well).
>>
> Probably a minimally invasive change is best, also this kind of thing deserves a comment explaining the problem that was encountered with the specific platforms, so that in the future when people examine this part they can understand why this is there. Do you want to make a pull request for this change?
>
I'd go with the defined(__APPLE__) then, since %Ld produces wrong results on both 32bit platforms. More precisely, this print
"%Ld - %Ld", dts->year, dts->year
produces "0 - 1970" on ppc and "1970 - 0" on i386, while "%lld - %lld" prints "1970 - 1970" on both archs. There still is an issue (I now remember this came up with a different test a few months ago), that none of the formats seems to be able to actually print numbers > 2**32 (or 2**31, don't remember), but this seemed out of reach for anyone on this list.

That proves that it's wrong on i386 as well, and it makes perfect sense for big endian and little endian architectures.

-Mark
 

Cheers,
                                                       Derek

_______________________________________________
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion