Forum Discussion
Altera_Forum
Honored Contributor
16 years agoHi Jerome,
thank you for your reply. --- Quote Start --- Hello, You can find some answers in the tutorial "Using Nios II Floating-Point Custom Instructions" ... So you cannot use floating point hardware for double precision calculation, whatever the type of processor (e/s/f). --- Quote End --- Yes I looked in that - it is cleary written. you are right about hardware precision, but in fact it is possible to do double floating point math if no fp floatig point custom instruction hardware is used with Nios/e. Below I wrote one more program, which proves that. i want to keep valuable fp custom instruction hardware configuration but to find a solution whether it can be temporary disabled on demand in order to do precision-sensitive calculations. --- Quote Start --- For your case 3, I agree that if you disable it with pragma directives it should use software implementation as in case 1, but I don't know the second pragma directives you use (which finished with a 'd'), where do you find them. On their tutorial they put only the first ones (which finished with a 's'). --- Quote End --- This is what made me curious. I decided to use fp custom instruction hardware but disable it when I need software double precision calculation. About directives - that might be not very nice from me but I scanned some executable files for the possible "no_custom" text in them and found that compiler might supports both types of directives: # pragma no_custom_fxxxs // no custom xxx float single ? As in tutorial and # pragma no_custom_fxxxd // no custom xxx float double ? I supposed Therefore I tried both directives. Still I don't know if it is possible to get pure double precision (however software emulated) with Nios2+custom fp instruction present but disabled. With Regards, Sergei. -------------- Double precision math proof ---------------- the program #include <stdio.h> #include <math.h> #include <float.h> // Single precision variables // 15 digits double precision constants float as = 1.000000000000100; float bs = 1.000000000000055; // Double precision variables // 15 digits double precision constants double ad = 1.000000000000100; double bd = 1.000000000000055; #define no_custom_fadds #define no_custom_fsubs #define no_custom_fmuls #define no_custom_fdivs int main (void) { printf ("---------- single precision (float) -----------\n"); printf ("sizeof(a) = %lu bytes\n", sizeof(as)); printf ("single: a = %.15f\n", as); printf ("single: b = %.15f\n", bs); printf ("single: a-b = %.15f\n", as-bs); // Since a = 1+x, b = 1+y, where x,y << 1 // sqrt(a) = sqrt (1+x) ~ 1+x/2, sqrt(b) = sqrt (1+y) ~ 1+y/2 // sqrt(a)*sqrt(b) ~ (1+x/2)*(1+y/2) ~ (1+(x+y)/2) = (a+b)/2 printf ("sqrt(a)*sqrt(b) = %.15f\n", sqrt(as)*sqrt(bs)); printf ("(a+b)/2 = %.15f\n", (as+bs)/2); printf ("---------- double precision (double) -----------\n"); printf ("sizeof(a) = %lu bytes\n", sizeof(ad)); printf ("double: a = %.15f\n", ad); printf ("double: b = %.15f\n", bd); printf ("double: a-b = %.15f\n", ad-bd); // Since a = 1+x, b = 1+y, where x,y << 1 // sqrt(a) = sqrt (1+x) ~ 1+x/2, sqrt(b) = sqrt (1+y) ~ 1+y/2 // sqrt(a)*sqrt(b) ~ (1+x/2)*(1+y/2) ~ (1+(x+y)/2) = (a+b)/2 printf ("sqrt(a)*sqrt(b) = %.15f\n", sqrt(ad)*sqrt(bd)); printf ("(a+b)/2 = %.15f\n", (ad+bd)/2); printf ("---------- C/C++ compiler constants ------------\n"); printf ("Maximum float value %e\n", FLT_MAX); printf ("Maximum double value %e\n", DBL_MAX); while (1); return 0; } [/B][/B]case a: nios2/e no fp instruction: program prints: ---------- single precision (float) ----------- sizeof(a) = 4 bytes single: a = 1.000000000000000 single: b = 1.000000000000000 single: a-b = 0.000000000000000 sqrt(a)*sqrt(b) = 1.000000000000000 (a+b)/2 = 1.000000000000000 ---------- double precision (double) ----------- sizeof(a) = 8 bytes double: a = 1.000000000000100 double: b = 1.000000000000055 double: a-b = 0.000000000000045 sqrt(a)*sqrt(b) = 1.000000000000077 (a+b)/2 = 1.000000000000077 ---------- C/C++ compiler constants ------------ Maximum float value 3.402823e+38 Maximum double value 1.797693e+308 case b: nios2/e with fp instruction: program prints: ---------- single precision (float) ----------- sizeof(a) = 4 bytes single: a = 1.000000000000000 single: b = 1.000000000000000 single: a-b = 0.000000000000000 sqrt(a)*sqrt(b) = 1.000000000000000 (a+b)/2 = 1.000000000000000 ---------- double precision (double) ----------- sizeof(a) = 8 bytes double: a = 1.000000000000000 double: b = 1.000000000000000 double: a-b = 0.000000000000000 sqrt(a)*sqrt(b) = 1.000000000000000 (a+b)/2 = 1.000000000000000 ---------- C/C++ compiler constants ------------ Maximum float value 3.402823e+38 Maximum double value inf