in reply to Re^4: Supporting long long types in XS (NV,PV)
in thread Supporting long long types in XS

Joost asks:
can floating point arithmatic on integers (I mean operations on < 52 bit ints stored in doubles) lose precision?
BrowserUK writes:
printf "%d\n", $nv;;
print $nv & 1;;
Neither printf "%d" nor $nv & 1 is "floating point arithmatic".

Replies are listed 'Best First'.
Re^6: Supporting long long types in XS (NV,PV)
by BrowserUk (Patriarch) on Nov 21, 2006 at 22:46 UTC

    Not "floating point arithmetic", but they are "operations on < 52 bit ints stored in doubles", which is after all what he said; "I mean ...".

    But, by the by, I also left it to his judgement to reach a conclusion. I know mine. I know yours. Most people here do. Now he, and everyone else can make up their own minds whether the transition from IVs to NVs is transparent; or flawed and dangerous.

    From my perspective, it is impossible to code the use and manipulation of integral values in such a way that you can benefit from the extended range that storing those integrals in an NV permits, without also coding such that you never treat those integrals as integers. Ie. as IVs.

    That means never using %d. Never using bitwise opcodes. Never reading or writing binary values. and much more. If these operations were not useful, then there would be no purpose of having them. In Perl or C or assembler. Hell. The chip manufacturers should simply remove 50% of their opcodes & microcode and reassign the transistors. What are they thinking of.

    But the reality is, they are useful. They perform and permit algorithms that cannot be easily (never mind efficiently), be coded without the much maligned "bit-twiddling". With extremely rare and specialist exception, every computer language incorporates integer (as in fixed-length, power of 2 bits, hardware dependant sized) operations. And for a very large percentage of computer programs, they are all that is needed.

    And the programs that avoid the use of floating point math, also avoid the vagaries of of it's many failure modes.

    Whilst I love the concept of Perl's transparent transitions between different storage classes of number, the reality of perl's implementation is so flaky that I cannot endorse reliance upon it for anything vaguely critical. Even perl's floating point operations on floating point values are suspect:

    perl -e"print 4.5 % -1.25" 0 \ruby\bin\ruby -e"print 4.5 % -1.25" -0.5 perl -e"print 4.5 % 1.25" 0 \ruby\bin\ruby -e"print 4.5 % 1.25" 0.75

    Given the wikipedia (assuming you consider that reasonably authoritative on this matter), for the modulo operator:

    Given two numbers, a and n, a modulo n (abbreviated as a mod n) is the remainder, on division of a by n.

    Which seems more correct to you?

    Of course, the answer may be that they are both suspect. Wikipedia goes on to say:

    Although typically performed with a and n both being integers, many computing systems allow other types of numeric operands.

    And if you try those operations in a language that arguably takes great pains to get it's math right:

    Prelude> 4.5 `mod` 1.25 <interactive>:1:4: Ambiguous type variable `a' in the constraints: `Integral a' arising from use of `mod' at <interactive>:1:4-8 `Fractional a' arising from the literal `4.5' at <interactive>:1 +:0-2 Probable fix: add a type signature that fixes these type variable( +s)

    then you might reach the conclusion that even the much vaunted use of % 2 as a substitute for & 1, so as to benefit from the transparent transition to > 32-bit integral values is suspect.

    I do, but you're free to reach your own conclusions. Just as joost is.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Although typically performed with a and n both being integers, many computing systems allow other types of numeric operands.

      I always thought this might not be the case for Perl though.

      From my 1992 copy of "Programming perl" (1st Edition; p83)
      The % operator converts to integers before finding the remainder.

      Though I'm not exactly sure what perlop wants to tell me aboput that topic.

      Multiplicative Operators:
      Binary ``%'' computes the modulus of two numbers. Given integer operands $a and $b: If $b is positive, then $a % $b is $a minus the largest multiple of $b that is not greater than $a. If $b is negative, then $a % $b is $a minus the smallest multiple of $b that is not less than $a (i.e. the result will be less than or equal to zero). Note that when use integer is in scope, ``%'' gives you direct access to the modulus operator as implemented by your C compiler. This operator is not as well defined for negative operands, but it will execute faster.

        The POSIX pod defines fmod as:

        It returns the remainder $r = $x - $n*$y, where $n = trunc($x/$y). The $r has the same sign as $x and magnitude (absolute value) less than the magnitude of $y.

        The weird thing is, the 'obvious' implementation of mod seems to work fine?

        Perl> sub mod{ my( $a, $n ) = @_; return $a - $n * int( $a / $n ); };; Perl> print mod( 4.5, 1.25 );; ## prints 0.75 Perl> print mod( 4.5, -1.25 );; ## prints 0.75 Perl> print mod( -4.5, -1.25 );; ## prints -0.75 Perl> print mod( -4.5, 1.25 );; ## prints -0.75

        Which compares favourably with the results of my C compilers view of the world:

        Perl> use POSIX qw[ fmod ];; Perl> print fmod( 4.5, 1.25 );; ## prints 0.75 Perl> print fmod( 4.5, -1.25 );; ## prints 0.75 Perl> print fmod( -4.5, 1.25 );; ## prints -0.75 Perl> print fmod( -4.5, 1.25 );; ## prints -0.75

        I'm not sure how ruby arrives at it's take on the subject? Uses abs on the arguements, divides, truncates and multiplies, then sets the sign of the results according to the divisor?

        c:\test>\ruby\bin\ruby -e"p 4.5 % 1.25" ## prints 0.75 c:\test>\ruby\bin\ruby -e"p 4.5 % -1.25" ## prints -0.5 c:\test>\ruby\bin\ruby -e"p -4.5 % 1.25" ## prints 0.5 c:\test>\ruby\bin\ruby -e"p -4.5 % -1.25" ## prints -0.75

        That still makes more sense than the current perl implementation.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.