Skip to end of metadata
Go to start of metadata

There is no content with the specified labels

Information for Editors
In order to have a new guideline automatically listed above be sure to label it int and rule.

Risk Assessment Summary

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

 


6 Comments

  1. Into the Perl internals all numbers are converted to double, including integers. If you dont bother on checking the limits and precision of your code it should be interesting to activate the bignum directive:

    $perl -E '
    my $big_int = 18446744073709551616;
    my $very_big_int = $big_int * 2; #lost of precision
    say $very_big_int;'
    3.68934881474191e+19


    $ perl -E 'use bignum;
    my $big_int = 18446744073709551616;
    my $very_big_int = $big_int * 2; #Keep precision
    say $very_big_int;'
    36893488147419103232

    It will keep integer preciosion for numbers as big as your memory can handle.

    1. Your code behaves as advertised on my 64-bit Ubuntu box.

      I doubt all integers would be converted to floating-point...that would introduce lots of precision errors. See FLP02-C. Avoid using floating-point numbers when precise computation is needed for instance. On my box, only numbers or calculations that exceed 2^64 get converted.

      Still, this does have interesting consequences, particularly because precision loss is not something people expect when they do integer arithmetic. Especially when people use untrusted integers...see, for instance IDS32-PL. Validate any integer that is used as an array index.

      1. People do not expect loosing precision on integer math and not use to check boundaries in dynamic languages like Perl.

      2. >>I doubt all integers would be converted to floating point

        Yea, not all integers are converted but can be converted at any time, depending on size, architecture and operators used. You see, in Perl the data type is converted dynamically.

        A scalar can be a character, a string, a integer or a floating-point. So whe have to concern about the rules bellow:

        1. Perl code is very portable, the very same code run in my Windows 32 bits notebook, my Debian Linux station and my Solaris 64 bits server;
        2. "Although we might speak of a scalar as “containing” a number or a string, scalars are typeless: you are not required to declare your scalars to be of type integer or floating point or string or whatever." (ref. Programming Perl 4ed, pg 65);
        3. "Thus the limits for Perl numbers stored as native integers would typically be -2**31..2**32-1, with appropriate modifications in the case of 64-bit integers" (ref. perldoc perlnum);
          1. in your box just number over 2^64 were converted, but in a 32bits machine the conversion begins at 2^32.
        4. For scalar, when used as numbers, 6 convertions are possibles:
          1. native integer --> native floating point (*)
          2. native integer --> decimal string
          3. native floating_point --> native integer (*)
          4. native floating_point --> decimal string (*)
          5. decimal string --> native integer
            1. If the decimal string --> native integer conversion cannot be done without loss of information, the result is compatible with the conversion sequence decimal_string --> native_floating_point --> native_integer
        5. The binary operators +-*/%==!=><>=<= and the unary operators -abs and -- will attempt to convert arguments to integers.
        6. Operators such as ** , sin and expforce arguments to floating point format.
          1. so, in any machine 2^32 will force a floating point

        So it is hard to predict when your integers will be converted to floating point format and becames harder when you write multiplataform code. The bignum directive is a good idea to overcome this process when you need very accurated data.

        *native means C language type.

        Hope it is usefull.

        1. Thanks for the background. INT01-PL can contain any future discussion on this topic.

          On my 32-bit machine, all numbers over 2^32 get converted to floating point (I'd guess double), but on my 64-bit machine, all numbers over 2^48 get converted. So it's more complex than just what the size of C's int or long data type.

          More importantly, it's not really addressed. The perlnumber page contains most of this, plus the info you cite, but nothing about numeric limits. I wouldn't be surprised if the limits have changed over different versions of Perl.