psmile_ddadd.c

Go to the documentation of this file.
00001 /*-----------------------------------------------------------------------
00002 * Copyright 2008-2010, DKRZ, Hamburg, Germany.
00003 * All rights reserved. Use is subject to OASIS4 license terms.
00004 *-----------------------------------------------------------------------*/
00005 
00006 #include <stddef.h>
00007 #include "PSMILe_f2c.h"
00008 
00009 /*This function is based on the code from the MPFUN90 library
00010  *http://crd.lbl.gov/~dhbailey/mpdist/
00011  *
00012  *It was necessary to rewrite this function in C, because F90
00013  *does not support the volatile keyword. This keyword is
00014  *necessary to avoid compiler optimisations which use more than
00015  *64bit for intermediate floating point results.
00016  *However, this has some performance drawbacks. Another possible
00017  *solution is to force the compiler to use 64bit arithmetics for
00018  *this function. Unfortunately, this would require compiler
00019  *specific flags. Therefore, I will use this general solution for
00020  *now and may add optimisations for different compilers later.
00021  */
00022 
00023 /* This function add two double-double precision numbers.*/
00024 
00025 #ifdef ANSI_C
00026 
00027 void psmile_ddadd (double * dda, double * ddb)
00028 
00029 #else
00030 
00031 void psmile_ddadd (dda, ddb)
00032 
00033 double * dda, * ddb;
00034 
00035 #endif
00036 
00037 {
00038    volatile double e, t1, t2, t2_1, t2_2, t2_3;
00039 /* Compute dda + ddb using Knuth's trick.*/
00040    t1 = dda[0] + ddb[0];
00041    e = t1 - dda[0];
00042    t2_1 = t1 - e;
00043    t2_2 = dda[0] - t2_1;
00044    t2_3 = ddb[0] - e;
00045    t2   = t2_3 + t2_2;
00046    t2  += dda[1];
00047    t2  += ddb[1];
00048 
00049 /* The result is t1 + t2, after normalization.*/
00050    ddb[0] = t1 + t2;
00051    e = t1 + t2;
00052    e -= t1;
00053    ddb[1] = t2 - e;
00054    
00055    return;
00056 }

Generated on 18 Mar 2011 for Oasis4 by  doxygen 1.6.1