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