in reply to XS, C doubles and -Duselongdouble

  1. Carp provides for 'misreporting' the location of errors via $Carp::CarpLevel = 1;
  2. Seems right to me too. Take that with exactly as much authority as it deserves :)
  3. Seems to me there two possible ways:

    • It could yell about the possible loss of precision as a C compiler would when you assign a long double to a double.

      In that respect, when the XS code is compiled, the C compiler probably is yelling about it.

      I've looked for a proper way of pursuading XS to display warnings produced by the C compiler without success. I generally resort to adding an obviously fatal error at the end of the inline C--a # in column one of the last line works:). When the fatal error is reported, you also get to see all the warning errors that were previously kept hidden from you.

    • It could attempt to detect whether the number of significant bits set in the mantissa of the long double exceeds 53.

      *I'm not sure whether you want it to be your perl code, the XS-precompiler or the Inline generated wrappper stubs, or the C-code?

      For any given processor, or rather for a given real format, that would be a fairly simple operation. Just requiring a bit mask of the appropriate bits of the long double to check.

      For IEEE representation, you should be able to work out the appropriate bytes/bits to mask from IEEE 754 80-bit Extended double (long double) to 64-bit double unpack.

      Doing it such that it would be portable across platforms that don't use IEEE format reals could be a lot harder.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^2: XS, C doubles and -Duselongdouble
by syphilis (Archbishop) on Jun 10, 2007 at 14:26 UTC
    Carp provides for 'misreporting' the location of errors via $Carp::CarpLevel = 1;

    Yep - that does it nicely. (After I posted the sopw I realised that particular question didn't have a real lot to do with "XS", "C doubles", or "-Duselongdouble" :-)

    In that respect, when the XS code is compiled, the C compiler probably is yelling about it

    Haven't noticed any complaints from gcc - even if the SvNV() is not explicitly cast to a double. On windows, with an MSVC-built perl, you aren't going to get a "proper" -Duselongdouble build of perl ... in that any Microsoft compiler that knows about long doubles will tell you that sizeof(long double) == sizeof(double) == 8.
    With MinGW, it should be theoretically possible to build a -Duse64bitint and -Duselongdouble build of perl .... but since MinGW uses the msvcrt.dll runtime library, I don't think it would be possible for such a perl to printf() the long double values correctly.

    I generally resort to adding an obviously fatal error at the end of the inline C

    The idea of the use Inline C => Config => BUILD_NOISY => 1; is that it provides verbosity (including any compiler warnings), thus eliminating the need to take such measures.

    It could attempt to detect whether the number of significant bits set in the mantissa of the long double exceeds 53

    Yes - that's what I was trying to think of. It's just a matter of finding the position of the least significant (set) bit in the argument that's given to perl_foo(). It's the perl code (the 'perl_foo' function to be precise) that needs to determine whether there has been a loss of precision.

    Thanks BrowserUk.

    Cheers,
    Rob
      It's just a matter of finding the position of the least significant (set) bit

      It's probably quicker to just test that there are no bits set in the lowest 8 bits (64-52) of the mantissa. Those 8 bits are stored in the last (10th) byte of the real*10 representation. So it should just be a case of (assuming you have the 10 bytes packed in scalar)

      if( substr $packedReal10, -1 ) { warn 'Loss of precision...'; }
      any Microsoft compiler that knows about long doubles will tell you that sizeof(long double) == sizeof(double) == 8.

      Gah. How stupid is that. You know, I have a funny feeling that I saw a set of 80bit real math functions kicking around inside one of the system DLLs. In theory, it would be possible to wrap a header file and an import library around that and get access to them from C/C++. I can't remember where I (think) I saw them and a quick grep didn't locate them. I'll have another look later.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Gah. How stupid is that.

        Stupidity is hard to quantify ... so I'm therefore relieved that the question was rhetorical :-)
        I was recently directed to http://blogs.msdn.com/ericflee/archive/2004/06/10/152852.aspx ... which I found to be rather interesting, somewhat amusing, and a little disturbing.

        Cheers,
        Rob