Hi 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