Search code examples
type-conversionwolframalpha

Arithmetically simulate 32-bit integer overflow


Is there a way to arithmetically simulate 32-bit, twos-complement integer overflow with numbers of a type whose value space is a strict superset of that of the 32-bit twos-complement integers? I need to perform such an operation in, for example, WolframAlpha, which has no explicit typing and no type casting.

The output of my desired convertTo32BitSignedInt(aValue) function needs to be the same as if I had cast the value in a language that supports it, such as Java: (int)aValue.

By example, the output of convertTo32BitSignedInt(17643225600) needs to be 463356416, the same as I had used the following cast (int)17643225600.

For the moment, my convertTo32BitSignedInt function (in pseudo code) looks like this and I am pretty sure it's not the better solution.

if(x > 2147483647 && floor(x / 2147483647 ) == 1){
    return (x - 2*2147483648);
}else if(x > 2147483647 && (x % 2147483647 == 0) && (x % 2 == 0)){
    return -1 * (x / 2147483647);
}else if(x > 2147483647 && (x % 2147483647 == 0) && (x % 2 > 0)){
    return -1 * ((x - 2147483647) / 2147483647) + 2147483647;
}else if(x > 2147483647 && (x % 2147483647 > 0) && (x % 2 == 0)){
    return  -1 * floor(x / 2147483647) + (x % 2147483647);
}
//...

Use Case:

I try to demonstrate a certain behavior that will occures when there is a 32-bit signed integer overflow in a java program using a recursive implementation of the factorial function.

public int factorial(int n) {
    return n == 1 || n==0 ? 1 : n * factorial(n - 1);
}

This int implementation, for factorial(13) gives 1932053504, because 13 * 479001600 > 2147483647, the 32-bit signed integer maximum value.

I use WolframAlpha for the demonstration. WolframAlpha allows numbers > 2147483647 and I want to simulate these number as 32-bit integer numbers. WolframAlpha gives the real answer which is 6227020800. I would like to be able to convert 6227020800 as 1932053504.


Solution

  • Edit: this is a rip & replace of my initial answer

    You can do something roughly like this:

    convertTo32BitSignedInt(aValue) {
        bits32 = BitAnd(aValue, BitShiftLeft(1, 32) - 1);
        sign = BitShiftRight(bits32, 31);
    
        return bits32 - BitShiftLeft(sign, 32);
    }