Thursday, 6 June 2019

The Perl Negative Modulus Bug

This is a bug that has been in Perl for all the years I have used it. There is a workaround, but I choose to avoid using Perl for anything beyond simple math.

The bug only shows when you try to calculate the modulus of negative values.


#!/usr/bin/perl

$A = 106;
printf("Division\n");
printf("106 / 10 = 10\t<- expected\n");
printf("%d / 10 = %01d\t<- correct\n", $A, $A / 10);

printf("\n");
printf("Modulus\n");
printf("106 %% 10 = 6\t<- expected\n");
printf("%d %% 10 = %d\t<- correct\n", $A,  $A % 10);

printf("\n\nNegative values\n");

$A = -106;
printf("Division\n");
printf("%d / 10 = 10\t<- expected\n", $A);
printf("%d / 10 = %01d\t<- correct\n", $A, $A / 10);

printf("\n");
printf("Modulus\n");
printf("%d %% 10 = -6\t<- expected\n", $A);
printf("%d %% 10 = %d\t<- WHAT THE!!!\n", $A,  $A % 10);

This is the output.

Division
106 / 10 = 10 <- expected
106 / 10 = 10 <- correct

Modulus
106 % 10 = 6 <- expected
106 % 10 = 6 <- correct


Negative values
Divsion
-106 / 10 = 10 <- expected
-106 / 10 = -10 <- correct

Modulus
-106 % 10 = -6 <- expected
-106 % 10 = 4 <- WHAT THE!!!


1 comment:

  1. Here is the same code in C and the correct output that it gives.

    #include

    int main(int argc, char **argv)
    {
    int A;

    A = 106;
    printf("Division\n");
    printf("106 / 10 = 10\t<- expected\n");
    printf("%d / 10 = %01d\t<- correct\n", A, A / 10);

    printf("\n");
    printf("Modulus\n");
    printf("106 %% 10 = 6\t<- expected\n");
    printf("%d %% 10 = %d\t<- correct\n", A, A % 10);


    A = -106;
    printf("\n\nNegative values\n");

    printf("Division\n");
    printf("%d / 10 = 10\t<- expected\n", A);
    printf("%d / 10 = %01d\t<- correct\n", A, A / 10);

    printf("\n");
    printf("Modulus\n");
    printf("%d %% 10 = -6\t<- expected\n", A);
    printf("%d %% 10 = %d\t<- correct\n", A, A % 10);
    }


    Division
    106 / 10 = 10 <- expected
    106 / 10 = 10 <- correct

    Modulus
    106 % 10 = 6 <- expected
    106 % 10 = 6 <- correct


    Negative values
    Division
    -106 / 10 = 10 <- expected
    -106 / 10 = -10 <- correct

    Modulus
    -106 % 10 = -6 <- expected
    -106 % 10 = -6 <- correct

    ReplyDelete