Riccardo wrote:
I've looked more closely into this one. Something goes bad when d2f bytecode instruction is exectued in this case. the implementation in intrp/icode.h looks innocent enough, but I'm not sure what should happen precisely when max double is assigned to a float in C. I've written a test case, and attached it, so it'd be nice if you could run it on your netbsd-ppc machine and report the results.


NetBSD/ppc 2.0 beta, gcc 3.3.3:
d = 1.79769e+308         f = inf         g=inf
d = 1    f = 7fefffff    g=ffffffff
f.f = 3.40282e+38        f.i = 7f7fffff

OpenBSD/sparc 3.4, gcc 2.95.2
d = 1.79769e+308         f = Inf         g=Inf
d = 7fefffff     f = ffffffff    g=7f800000
f.f = 3.40282e+38        f.i = 7f7fffff

Darwin 6.8, apple cc
d = 1.79769e+308         f = Inf         g=Inf
d = 7fefffff     f = ffffffff    g=7f800000
f.f = 3.40282e+38        f.i = 7f7fffff

the behavior seems consistent to me
what is the result at your place?

The only thing that's consistent is the last line :) Looks like my test was broken, could you try this version on NetBSD ppc?


I suspect that d2f is broken in the interpreter. The Java language spec demands that in case of overflow the value of float is a signed infinity, but the C standard says oveflow results in undefined behaviour. So I assume we'd have to check whether the double is representable as a float before we convert it, and handle the special cases that would invoke undefined behaviour ourself.

I'm working on a patch.

cheers,
dalibor topic
#include <stdio.h>

union dtype {
double d;
int l [sizeof(double)/sizeof(int)];
};
typedef union dtype dtype;

union ftype {
float f;
int i[sizeof(float)/sizeof(int)];
};
typedef union ftype ftype;

void printhex(const char * name, const int * word, int len) {
	int i;

	printf("%s = ", name);
	for (i = 0; i < len; ++ i) {
		printf(" %x", word[i]);
	}
	puts("");
}

int main(void) {
	dtype d;
	ftype f;
	ftype g;

	printf("sizeof(double) = %d\n", sizeof(double));
	printf("sizeof(float) = %d\n", sizeof(float));
	printf("sizeof(int) = %d\n", sizeof(int));
	printf("sizeof(long) = %d\n", sizeof(long));
	printf("sizeof(long long) = %d\n", sizeof(long long));

	printf("sizeof(dtype.l) = %d\n", sizeof(d.l));
	printf("sizeof(ftype.i) = %d\n", sizeof(f.i));

	d.d = 1.7976931348623157E308;

	f.f = d.d;
	g.f = (float) d.d;

	printf("d = %g\t f = %g\t g=%g\n", d.d, f.f, g.f);

	printhex("d", d.l, sizeof(d.l)/sizeof(int));
	printhex("f", f.i, sizeof(f.i)/sizeof(int));
	printhex("g", g.i, sizeof(g.i)/sizeof(int));
/*
	printf("d = %Lx\t f = %x\t g=%x\n", d.l, f.i, g.i); 	
*/
	f.f = 3.4028234663852885981e+38f;
	printf("f.f = %g\n", f.f);

	printhex("f.i", f.i, sizeof(f.i)/sizeof(int));

	g.f *= -1.0;
	printf("g.f = %g\n", g.f);

	printhex("g.i", g.i, sizeof(g.i)/sizeof(int));

	return 0;
}

Reply via email to