Showing posts with label Red/System. Show all posts
Showing posts with label Red/System. Show all posts

Sunday, 13 November 2016

Swift Int32.divideWithOverflow doesn't always actually protect against overflows!!

Good news update.

I've started looking into Swift with the intention of using it to build personal applications running under macOS. I needed to generate some tests of Red/System's integer processing. I would normally generate such tests in Rebol or Ruby but as Red/System integers overflow, rather than raising exceptions, I needed to use a language that supports overflowing integers.

Swift has a collection of <operand>WithOverflow functions. So I went ahead and wrote a Swift program to generate the tests. Then I came across a problem, I got an overflow exception when using divideWithOverflow. It seemed strange. Here is the culprit:

Int32.divideWithOverflow(Int32.min, -1)

Playground execution failed: error:myPlayground.playground:31:7: 
error: division '-2147483648 / -1' results in an overflow
Int32.divideWithOverflow(Int32.min, -1)

I checked on the Swift-User mailing list if that is the expected behaviour. Apparently it is. Perhaps the name of the function needs to be updated to divideWithOverflowExeceptWhenDividingMinByMinusOne? ;-)

As a sanity check, I wrote a very simple C program to check what should be returned when dividing -2147483648 by -1.

Here's the code:
#include <stdio.h>

int main(int argc, const char * argv[]) {

    int32_t i = -2147483648 / -1;
    printf("-2147483648 / -1 = %d\n", i);

    return 0;
}

Here's the output:
-2147483648 / -1 = -2147483648

Based on that I went ahead and wrote the test generator in C. I got quite a surprise when performing the calculations, I got an overflow exception. It seems that the compiler is happy when using integer literals but not 32-bit integers. The following code gives an overflow exception. (Funnily enough it doesn't when multiplying.)

This code

  #include <stdio.h>

  int main(int argc, const char * argv[]) {
    
      int32_t i = -2147483648;
      int32_t j = -1;
      int32_t k = i * j;
      printf("-2147483648 * -1 = %d\n", k);
      int32_t m = i / j;
      printf("-2147483648 / -1 = %d\n", m);
    
      return 0;
  }

prints

  -2147483648 * -1 = -2147483648

and then fails with an overflow exception.

Thanks to Nenad Rakocevic, the creator of Red Language, I found that the compilers are delegating the division to the cpu. The behaviour seems to be cpu dependant. The Intel processor in my laptop raises an overflow error whilst the ARM processor in a Raspberry Pi doesn't. (It does give somewhat inconsistent results though).

So I've learnt that if there is a small chance that you could be dividing -2147483648 by -1 in a program with "overflowing" integers you need to protect against it.



Tuesday, 8 July 2014

64 Bit Integer Arithmetic For Red/System

Red/System is the low-level dialect of the Red Programming Language. It is a compiled language, its datatypes and variables work like C, whereas its syntax is very similar to Red. The Red runtime is written in Red/System and the Red compiler outputs Red/System code (which is then compiled to native code).

The current version of Red/System has been written to meet those two needs and to do little more. Once Version 1.0 of Red is complete, the Red/System compiler will be re-written in Red (the current one is written in Rebol).

Using Red/System, it is very easy to write interfaces to external libraries written in C. There is a slight catch however, integers in Red/System are 32 bit integers and some libraries return 64 bit integers.

I've written a simple 64 bit integer arithmetic library for Red/System to make it easier to deal with such libraries. I expect that Red/System 2 will include built-in support for 64 bit integers so the library reflects its temporary nature.

The main functions are add, subtract, multiply, and divide. I used easy algorithms such as long multiplication and division.  There are a number of supporting functions and macros too.

You can find the library on Github.