exp(x)

ZXNet echo conference «code.zx»

From Stanislav Yudin To All 7 December 2002

Hello everyone! Hey, who's the smartest here? :) It is necessary to implement it in assembler Z80 subject function. Or maybe someone has a ready-made solution? If possible, you can complicate the task by ensuring that the program does not used RAM and worked only in ROM. Stanislav

From Kirill Frolov To Stanislav Yudin 8 December 2002

Press RESET immediately, Stanislav! 07 Dec 02 22:55, Stanislav Yudin wrote to All: SY> Hey, who's the smartest here? :) Need to be implemented in assembly language Z80 SY> subject function. Or maybe someone has a ready-made solution? SY> If possible, you can complicate the task by ensuring that SY> the program did not use RAM and worked only in ROM. === Cut === ; These functions allow the mantissa and exponent of floating ; numbers to be manipulated separately. psect text global _frexp, _ldexp ; double frexp(value, eptr) ; double value; ; int * eptr; _frexp: push ix ld ix,0 add ix,sp ld a,(ix+7) ;get old exponent ld b,a ;save sign bit and 80h ;mask it out add a,64 ;add in bias ld d,a ;store new exponent back ld a,b ;now get exponent and 7Fh ;clea sign bit sub 64 ;remove bias ld l,(ix+8) ;get pointer ld h,(ix+9) ld(hl),a inc hl rla sbc a,a ld (hl),a ;store upper byte ld l,(ix+4) ;now get value to return ld h,(ix+5) ld e,(ix+6) ex de,hl ;already have sign in d pop ix ret _ldexp: push ix ld ix,0 add ix,sp ld a,(ix+8) and 7Fh ld c,a ld a,(ix+7) ld h,a and 80h ld b,a ld a,h add a,c and 7Fh or b ld h,a ld l,(ix+6) ld d,(ix+5) ld e,(ix+4) pop ix ret === Cut === double eval_poly(x, d, n) double x, d[]; int n; { int i; double res; res = d[i = n]; while(i) res = x * res + d[--i]; return res; } double log(x) double x; { int exp; static double coeff[] = { 0.0000000000, /* a0 */ 0.9999964239, /* a1 */ -0.4998741238, /* a2 */ 0.3317990258, /* a3 */ -0.2407338084, /* a4 */ 0.1676540711, /* a5 */ -0.0953293897, /* a6 */ 0.0360884937, /* a7 */ -0.0064535442, /* a8 */ }; /* zero or -ve arguments are not defined */ if(x <= 0.0) return 0.0; x = frexp(x, &exp) * 2.0 - 1.0; exp--; x = eval_poly(x, coeff, sizeof coeff/sizeof coeff[0] - 1); return x + 0.69314718055995 * exp; } double log10(x) double x; { return log(x) * 0.4342944819; } double exp(x) double x; { int exp; char sign; static double coeff[] = { 1.0000000000e+00, 6.9314718056e-01, 2.4022650695e-01, 5.5504108945e-02, 9.6181261779e-03, 1.3333710529e-03, 1.5399104432e-04, 1.5327675257e-05, 1.2485143336e-06, 1.3908092221e-07, }; if(x == 0.0) return 1.0; sign = x < 0.0; if(sign) x = -x; x *= 1.4426950409; /* convert to log2 */ exp = (int)floor(x); x -= (double)exp; x = ldexp(eval_poly(x, coeff, sizeof coeff/sizeof coeff[0] - 1), exp); if(sign) return 1.0/x; return x; } double pow(x, y) double x, y; { if(y == 0.0) return 1.0; if(x < 0.0) return 0.0; if(x == 0.0) return 0.0; x = exp(log(x) * y); return x; }