Numerical Recipes Forum  

Go Back   Numerical Recipes Forum > Obsolete Editions Forum > C++ Programming with NR

Reply
 
Thread Tools Display Modes
  #1  
Old 09-09-2002, 09:54 AM
JoelMiller JoelMiller is offline
Member
 
Join Date: May 2002
Posts: 3
Question Trouble Adding Quadruple Precision

First, if anyone knows a clean way to add quadruple precision to numerical recipes in C++ please tell me (or I suppose I could even learn Fortran if that's easier).

I'm trying to change some calculations to quaduple precision. I expected it to be straightforward to redefine DP to be quadruple as opposed to double. So I downloaded a package from http://www.nersc.gov/~dhb/mpdist/mpdist.html and have successfully implemented simple calculations (e.g., 4*4 etc).

Here is a sample program, so you can see how the code works:

CODE:
**************************************
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "qd.h"
#include <cmath>
#include "x86.h"

using std::cout;
using std::cin;
using std::endl;

int main() {
unsigned short old_cw;
x86_fix_start(&old_cw);

qd_real a, b, c;

cout << "Enter a:";
cin >> a;
cout << "Enter b:";
cin >> b;

c = a + b;

qd_real asquared = a*a;
qd_real bsquared = sqr(b);

cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "2ab = " << 2*a*b << endl;
cout << "a*a = " << asquared << endl;
cout << "b*b = " << bsquared << endl;
cout << "a*a-b*b = " << asquared -bsquared << endl;
cout << "a + b = " << c << endl;
cout << "sin(c) = " << sin(c) << endl;

x86_fix_end(&old_cw);

return 0;
}

********************************************
OUTPUT:

Enter a:5
Enter b:3
a = 5.000000000000000000000000000000000000000000000000 000000000000000E0
b = 3.000000000000000000000000000000000000000000000000 000000000000000E0
2ab = 3.000000000000000000000000000000000000000000000000 000000000000000E1
a*a = 2.500000000000000000000000000000000000000000000000 000000000000000E1
b*b = 9.000000000000000000000000000000000000000000000000 000000000000000E0
a*a-b*b = 1.600000000000000000000000000000000000000000000000 000000000000000E1
a + b = 8.000000000000000000000000000000000000000000000000 000000000000000E0
sin(c) = 9.893582466233817778081235982452886721164190808857 612628177152199E-1

*********************************************

I'm now trying to redefine 'DP' to be quadruple precision by changing the lines in nrtypes.h and nrutil.h mentioned on page 17 of the text to 'typedef qd_real DP;'

However, it is getting errors in compilation:
**********************************************
In file included from nrutil.h:1,
from nr.h:5,
from bsstep.cpp:2:
nrutil_nr.h:10: syntax error before `;'
nrutil_nr.h:416: `DP' was not declared in this scope
nrutil_nr.h:416: template argument 1 is invalid
nrutil_nr.h:416: ISO C++ forbids declaration of `cc_p' with no type
nrutil_nr.h:416: ISO C++ forbids declaration of `cr_p' with no type

etc.
********************************************
Line 10 of nrutil_nr.h was the line that was changed to 'typedef qd_real DP;'

I suspect that it has something to do with the fact that x86_fix_start and _end are in main. Somehow it doesn't know about qd_real when it goes through nr.h

Any ideas/suggestions would be greatly appreciated.
Reply With Quote
  #2  
Old 09-10-2002, 09:41 AM
kibitzer kibitzer is offline
Registered User
 
Join Date: Sep 2002
Posts: 10
Have you tried

#include "qd.h"

in the 2 nr files where the typedefs are?
Reply With Quote
  #3  
Old 09-10-2002, 11:45 AM
JoelMiller JoelMiller is offline
Member
 
Join Date: May 2002
Posts: 3
Well, I thought I had...

That seems to have cleared up most of the problems. Still getting a few errors, but I think I can track them down.

thanks,

Joel
Reply With Quote
  #4  
Old 11-20-2002, 04:42 PM
Eatsum.com Eatsum.com is offline
Member
 
Join Date: Nov 2002
Location: Australia and Newyork
Posts: 6
Code changes:
Replace double by long double when declaring data type.
All mathematical functions, such as pow, fabs etc., take a double argument and return a double. The quadruple precision equivalents have an added l at the end of the function name, eg. powl, fabsl.
When printing or scanning a long double, you must use %Le or %Lf.

Now when compiling:
Use cc128 instead of cc. If using a Makefile, cc128 is located at /usr/bin/cc128 on the IBM SP2.
Make sure you are not linking in the library libc.a (denoted by -lc when linking). cc128 uses libc128.a automatically (needed for printf to understand %Le etc.) unless told to do otherwise.

Note:
Optimiser's may and can cause a problem when using quadruple precision. Check results from programs run with and without optimisation.
When compiling with cc128, you don't need to use the -qlongdouble flag.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump


All times are GMT -5. The time now is 04:49 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.