Subject: Re: Castings...
To: Neil A. Carson <neil@causality.com>
From: Chris G. Demetriou <cgd@pa.dec.com>
List: tech-kern
Date: 10/08/1997 17:26:32
> Situation:
> 	1 Casting a negative floating point number to a unsigned integer
> also
> 	2   12 % -5 (both long longs)
> 
> Initially on the ARM we returned a NaN for the 1, (now zero) and the
> present long long code returns -2 --- surely this should be 2, and a
> remainder always be positive???

At least under Digital UNIX, the division/remainder rules appear to
be:

	x = N / M
	y = N % M

constrained by:

	x * M + y == N 

	N / M == -((-N) / M )
	N % M == -((-N) % M )

	N / M == -(N / (-M))
	N % M == N % (-M)

In other words:

443 [dnaunix] tmp % cat bar.c

main(){
        printf("%d\n", 12 / 5);
        printf("%d\n", 12 % 5);

        printf("%d\n", - 12 / 5);
        printf("%d\n", - 12 % 5);

        printf("%d\n", 12 / - 5);
        printf("%d\n", 12 % - 5);

        printf("%d\n", -12 / - 5);
        printf("%d\n", -12 % - 5);
}
444 [dnaunix] tmp % cc bar.c
445 [dnaunix] tmp % ./a.out
2
2
-2
-2
-2
2
2
-2


Also, casting a negative floating point number to an unsigned integer
appears to happen "through" 'int', i.e.:

459 [dnaunix] tmp % cat bar.c

main(){
        double d;
        unsigned int x;
        unsigned long y;

        d = -10.5;

        x = d;
        printf("%x\n", x);

        y = d;
        printf("%lx\n", y);
}
460 [dnaunix] tmp % cc bar.c
461 [dnaunix] tmp % ./a.out
fffffff6
fffffffffffffff6


The same programs generate similar results on NetBSD/i386, modulo the
fact that the 'long' printf ends up being identical to the 'int'
printf.




chris