diff --git a/examples/cadna/gauss.cpp b/examples/cadna/gauss.cpp index 36f3d27134fcce302708f2b50351c8384a2270ba..95a86b71ed5ed89b52e0671df1a978817e22f629 100644 --- a/examples/cadna/gauss.cpp +++ b/examples/cadna/gauss.cpp @@ -28,8 +28,8 @@ void gauss() std::array, 4> a; std::array xsol; - int idim = a.size(); - int idim1 = a[0].size(); + int idim = static_cast(a.size()); + int idim1 = static_cast(a[0].size()); xsol[0] = 1.f; xsol[1] = 1.f; diff --git a/examples/cadna/jacobi.cpp b/examples/cadna/jacobi.cpp index 27dc06b1e22ef15e8fbfe071d9f4265d89aa15b5..82bac123b2bc2bf60ecb6fb828c7da40c4a3ca6f 100644 --- a/examples/cadna/jacobi.cpp +++ b/examples/cadna/jacobi.cpp @@ -18,7 +18,7 @@ int nrand = 23; float random1() { nrand = (nrand*5363 + 143) % 1387; - return 2.0*nrand/1387.0 - 1.0; + return static_cast(2.0*nrand/1387.0 - 1.0); } /* diff --git a/examples/performances/lulesh.cpp b/examples/performances/lulesh.cpp index dc380b15dd20a1b1cf7bdec84ab533370e6052e9..9e000e048e556f548706ebcf213a6040da818820 100644 --- a/examples/performances/lulesh.cpp +++ b/examples/performances/lulesh.cpp @@ -63,10 +63,8 @@ Additional BSD Notice */ #include -#include -#include -#include -#include +#include +#include #include #ifndef SHAMAN_TAGGED_ERROR @@ -2970,8 +2968,9 @@ int main(int argc, char *argv[]) } } - timeval start, end; - gettimeofday(&start, NULL); + using namespace std::chrono; + steady_clock::time_point start = steady_clock::now(); + /* timestep to solution */ @@ -2985,9 +2984,9 @@ int main(int argc, char *argv[]) #endif } - gettimeofday(&end, NULL); - double elapsed_time = double(end.tv_sec - start.tv_sec) + double(end.tv_usec - start.tv_usec) *1e-6; - + steady_clock::time_point end = steady_clock::now(); + duration time_span = duration_cast>(end - start); + double elapsed_time = time_span.count(); // in seconds printf("\n\nElapsed time = %12.6e\n\n", elapsed_time); diff --git a/src/shaman.h b/src/shaman.h index eac55a8681a75a8a0343cb0914d458de7e12fbed..4c07870bd2ba8d626825f99b2b626c6eabfacb8b 100644 --- a/src/shaman.h +++ b/src/shaman.h @@ -277,7 +277,6 @@ namespace Sstd templated const bool isunordered(const Snum& n1, const Snum& n2); //methods templated std::string to_string(const Snum &n); - template const char* to_Cstring(const T &n); } #endif diff --git a/src/shaman/functions.h b/src/shaman/functions.h index 3187f88b9355089a578fb9d7268e58e9378da8bd..92d4d5ed87121af7a1ae803f039c50d9c00489d9 100644 --- a/src/shaman/functions.h +++ b/src/shaman/functions.h @@ -102,1338 +102,1049 @@ } #endif +namespace Sstd { //----------------------------------------------------------------------------- // TRIGONOMETRIC FUNCTIONS -namespace Sstd +SHAMAN_FUNCTION(cos); +SHAMAN_FUNCTION(sin); +SHAMAN_FUNCTION(tan); +SHAMAN_FUNCTION(atan); + +// acos +templated const Snum acos(const Snum& n) { - SHAMAN_FUNCTION(cos); - SHAMAN_FUNCTION(sin); - SHAMAN_FUNCTION(tan); - SHAMAN_FUNCTION(atan); + numberType result = std::acos(n.number); - // acos - templated const Snum acos(const Snum& n) + preciseType preciseCorrectedResult; + preciseType correctedNumber = n.corrected_number(); + if (correctedNumber > 1) + { + preciseCorrectedResult = 0; + } + else if (correctedNumber < -1) { - numberType result = std::acos(n.number); + preciseCorrectedResult = M_PI; + } + else + { + preciseCorrectedResult = std::acos(correctedNumber); + } + preciseType totalError = preciseCorrectedResult - result; - preciseType preciseCorrectedResult; - preciseType correctedNumber = n.corrected_number(); - if (correctedNumber > 1) - { - preciseCorrectedResult = 0; - } - else if (correctedNumber < -1) - { - preciseCorrectedResult = M_PI; - } - else - { - preciseCorrectedResult = std::acos(correctedNumber); - } - preciseType totalError = preciseCorrectedResult - result; + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if(n.error == 0) + { + newErrorComp = Serror(totalError); + } + else + { + preciseType preciseResult = std::acos((preciseType)n.number); + preciseType functionError = preciseResult - result; + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if(n.error == 0) - { - newErrorComp = Serror(totalError); - } - else - { - preciseType preciseResult = std::acos((preciseType)n.number); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); - newErrorComp.addError(functionError); - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - - // asin - templated const Snum asin(const Snum& n) +// asin +templated const Snum asin(const Snum& n) +{ + numberType result = std::asin(n.number); + + preciseType preciseCorrectedResult; + preciseType correctedNumber = n.corrected_number(); + if (correctedNumber > 1) { - numberType result = std::asin(n.number); + preciseCorrectedResult = M_PI/2.; + } + else if (correctedNumber < -1) + { + preciseCorrectedResult = -M_PI/2; + } + else + { + preciseCorrectedResult = std::asin(correctedNumber); + } + preciseType totalError = preciseCorrectedResult - result; - preciseType preciseCorrectedResult; - preciseType correctedNumber = n.corrected_number(); - if (correctedNumber > 1) - { - preciseCorrectedResult = M_PI/2.; - } - else if (correctedNumber < -1) - { - preciseCorrectedResult = -M_PI/2; - } - else - { - preciseCorrectedResult = std::asin(correctedNumber); - } - preciseType totalError = preciseCorrectedResult - result; + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if(n.error == 0) + { + newErrorComp = Serror(totalError); + } + else + { + preciseType preciseResult = std::asin((preciseType)n.number); + preciseType functionError = preciseResult - result; + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if(n.error == 0) +// atan2 +templated const Snum atan2(const Snum& n1, const Snum& n2) +{ + numberType result = std::atan2(n1.number, n2.number); + preciseType preciseCorrectedResult = std::atan2(n1.corrected_number(), n2.corrected_number()); + preciseType totalError = preciseCorrectedResult - result; + + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + preciseType preciseResult = std::atan2((preciseType)n1.number, (preciseType)n2.number); + preciseType functionError = preciseResult - result; + if((n1.error == 0.) && (n2.error == 0.)) + { + newErrorComp = Serror(totalError); + } + else if (n2.error == 0.) + { + preciseType proportionalInput1Error = (totalError - functionError) / n1.error; + newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); + newErrorComp.addError(functionError); + } + else if (n1.error == 0.) + { + preciseType proportionalInput2Error = (totalError - functionError) / n2.error; + newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); + newErrorComp.addError(functionError); + } + else + { + preciseType preciseCorrectedBut1Result = std::atan2((preciseType)n1, n2.corrected_number()); + preciseType preciseCorrectedBut2Result = std::atan2(n1.corrected_number(), (preciseType)n2); + preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; + preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; + preciseType inputError = input1Error + input2Error; + if (inputError == 0.) { - newErrorComp = Serror(totalError); + // avoid division by zero + newErrorComp = Serror(functionError); } else { - preciseType preciseResult = std::asin((preciseType)n.number); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + preciseType proportionality = (totalError - functionError) / inputError; + preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); + preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); + newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); newErrorComp.addError(functionError); } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - - // atan2 - templated const Snum atan2(const Snum& n1, const Snum& n2) + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; +set_Sfunction2_casts(atan2); + +//----------------------------------------------------------------------------- +// HYPERBOLIC FUNCTIONS + +SHAMAN_FUNCTION(cosh); +SHAMAN_FUNCTION(sinh); +SHAMAN_FUNCTION(tanh); +SHAMAN_FUNCTION(asinh); + +// acosh +templated const Snum acosh(const Snum& n) +{ + numberType result = std::acosh(n.number); + + preciseType preciseCorrectedResult; + preciseType correctedNumber = n.corrected_number(); + if (correctedNumber < 1.) + { + preciseCorrectedResult = 0.; + } + else { - numberType result = std::atan2(n1.number, n2.number); - preciseType preciseCorrectedResult = std::atan2(n1.corrected_number(), n2.corrected_number()); - preciseType totalError = preciseCorrectedResult - result; + preciseCorrectedResult = std::acosh(correctedNumber); + } + preciseType totalError = preciseCorrectedResult - result; - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - preciseType preciseResult = std::atan2((preciseType)n1.number, (preciseType)n2.number); + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if(n.error == 0) + { + newErrorComp = Serror(totalError); + } + else + { + preciseType preciseResult = std::acosh((preciseType)n.number); preciseType functionError = preciseResult - result; - if((n1.error == 0.) && (n2.error == 0.)) - { - newErrorComp = Serror(totalError); - } - else if (n2.error == 0.) - { - preciseType proportionalInput1Error = (totalError - functionError) / n1.error; - newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); - newErrorComp.addError(functionError); - } - else if (n1.error == 0.) - { - preciseType proportionalInput2Error = (totalError - functionError) / n2.error; - newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); - newErrorComp.addError(functionError); - } - else - { - preciseType preciseCorrectedBut1Result = std::atan2((preciseType)n1, n2.corrected_number()); - preciseType preciseCorrectedBut2Result = std::atan2(n1.corrected_number(), (preciseType)n2); - preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; - preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; - preciseType inputError = input1Error + input2Error; - if (inputError == 0.) - { - // avoid division by zero - newErrorComp = Serror(functionError); - } - else - { - preciseType proportionality = (totalError - functionError) / inputError; - preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); - preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); - newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); - newErrorComp.addError(functionError); - } - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - set_Sfunction2_casts(atan2); -} + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; -using Sstd::cos; -using Sstd::sin; -using Sstd::tan; -using Sstd::atan; -using Sstd::acos; -using Sstd::asin; -using Sstd::atan2; +// atanh +templated const Snum atanh(const Snum& n) +{ + numberType result = std::atanh(n.number); + + preciseType preciseCorrectedResult; + preciseType correctedNumber = n.corrected_number(); + if(correctedNumber > 1. || correctedNumber < 1.) + { + preciseCorrectedResult = -INFINITY; + } + else + { + preciseCorrectedResult = std::atanh(correctedNumber); + } + preciseType totalError = preciseCorrectedResult - result; + + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if(n.error == 0) + { + newErrorComp = Serror(totalError); + } + else + { + preciseType preciseResult = std::asin((preciseType)n.number); + preciseType functionError = preciseResult - result; + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; //----------------------------------------------------------------------------- -// HYPERBOLIC FUNCTIONS +// EXPONENTIAL AND LOGARITHMIC FUNCTIONS + +SHAMAN_FUNCTION(exp); +SHAMAN_FUNCTION(exp2); +SHAMAN_FUNCTION(expm1); +SHAMAN_FUNCTION(ilogb); -namespace Sstd +// frexp +templated const Snum frexp(const Snum& n, int* exp) { - SHAMAN_FUNCTION(cosh); - SHAMAN_FUNCTION(sinh); - SHAMAN_FUNCTION(tanh); - SHAMAN_FUNCTION(asinh); + numberType result = std::frexp(n.number, exp); + int dummyExp; // a pointer integer in which to store the result, it can be safely discarded + preciseType preciseCorrectedResult = std::frexp(n.corrected_number(), &dummyExp); + preciseType totalError = preciseCorrectedResult - result; - // acosh - templated const Snum acosh(const Snum& n) - { - numberType result = std::acosh(n.number); + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if(n.error == 0) + { + newErrorComp = Serror(totalError); + } + else + { + preciseType preciseResult = std::frexp((preciseType)n.number, &dummyExp); + preciseType functionError = preciseResult - result; + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; - preciseType preciseCorrectedResult; - preciseType correctedNumber = n.corrected_number(); - if (correctedNumber < 1.) - { - preciseCorrectedResult = 0.; - } - else - { - preciseCorrectedResult = std::acosh(correctedNumber); - } - preciseType totalError = preciseCorrectedResult - result; +// ldexp +templated const Snum ldexp(const Snum& n, int exp) +{ + numberType result = std::ldexp(n.number, exp); + preciseType preciseCorrectedResult = std::ldexp(n.corrected_number(), exp); + preciseType totalError = preciseCorrectedResult - result; - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if(n.error == 0) - { - newErrorComp = Serror(totalError); - } - else - { - preciseType preciseResult = std::acosh((preciseType)n.number); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); - newErrorComp.addError(functionError); - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if(n.error == 0) + { + newErrorComp = Serror(totalError); + } + else + { + preciseType preciseResult = std::ldexp((preciseType)n.number, exp); + preciseType functionError = preciseResult - result; + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; - // atanh - templated const Snum atanh(const Snum& n) - { - numberType result = std::atanh(n.number); +// log +templated const Snum log(const Snum& n) +{ + numberType result = std::log(n.number); + preciseType totalError; + preciseType correctedNumber = n.corrected_number(); + if((correctedNumber <= 0.) && (n.number <= 0.)) + { + // resolves the case inf-inf + totalError = 0.; + } + else + { preciseType preciseCorrectedResult; - preciseType correctedNumber = n.corrected_number(); - if(correctedNumber > 1. || correctedNumber < 1.) + if (correctedNumber < 0) { preciseCorrectedResult = -INFINITY; } else { - preciseCorrectedResult = std::atanh(correctedNumber); + preciseCorrectedResult = std::log(correctedNumber); } - preciseType totalError = preciseCorrectedResult - result; - - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if(n.error == 0) - { - newErrorComp = Serror(totalError); - } - else - { - preciseType preciseResult = std::asin((preciseType)n.number); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); - newErrorComp.addError(functionError); - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; -} - -using Sstd::cosh; -using Sstd::sinh; -using Sstd::tanh; -using Sstd::asinh; -using Sstd::acosh; -using Sstd::atanh; + totalError = preciseCorrectedResult - result; + } -//----------------------------------------------------------------------------- -// EXPONENTIAL AND LOGARITHMIC FUNCTIONS + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if(n.error == 0) + { + newErrorComp = Serror(totalError); + } + else + { + preciseType preciseResult = std::log((preciseType)n.number); + preciseType functionError = preciseResult - result; + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; -namespace Sstd +// log10 +templated const Snum log10(const Snum& n) { - SHAMAN_FUNCTION(exp); - SHAMAN_FUNCTION(exp2); - SHAMAN_FUNCTION(expm1); - SHAMAN_FUNCTION(ilogb); + numberType result = std::log10(n.number); - // frexp - templated const Snum frexp(const Snum& n, int* exp) + preciseType totalError; + preciseType correctedNumber = n.corrected_number(); + if((correctedNumber <= 0.) && (n.number <= 0.)) { - numberType result = std::frexp(n.number, exp); - int dummyExp; // a pointer integer in which to store the result, it can be safely discarded - preciseType preciseCorrectedResult = std::frexp(n.corrected_number(), &dummyExp); - preciseType totalError = preciseCorrectedResult - result; - - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if(n.error == 0) - { - newErrorComp = Serror(totalError); - } - else - { - preciseType preciseResult = std::frexp((preciseType)n.number, &dummyExp); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); - newErrorComp.addError(functionError); - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - - // ldexp - templated const Snum ldexp(const Snum& n, int exp) - { - numberType result = std::ldexp(n.number, exp); - preciseType preciseCorrectedResult = std::ldexp(n.corrected_number(), exp); - preciseType totalError = preciseCorrectedResult - result; - - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if(n.error == 0) - { - newErrorComp = Serror(totalError); - } - else - { - preciseType preciseResult = std::ldexp((preciseType)n.number, exp); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); - newErrorComp.addError(functionError); - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - - // log - templated const Snum log(const Snum& n) + // resolves the case inf-inf + totalError = 0.; + } + else { - numberType result = std::log(n.number); - - preciseType totalError; - preciseType correctedNumber = n.corrected_number(); - if((correctedNumber <= 0.) && (n.number <= 0.)) + preciseType preciseCorrectedResult; + if (correctedNumber < 0) { - // resolves the case inf-inf - totalError = 0.; + preciseCorrectedResult = -INFINITY; } else { - preciseType preciseCorrectedResult; - if (correctedNumber < 0) + preciseCorrectedResult = std::log10(correctedNumber); + } + totalError = preciseCorrectedResult - result; + } + + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if(n.error == 0) { - preciseCorrectedResult = -INFINITY; + newErrorComp = Serror(totalError); } else { - preciseCorrectedResult = std::log(correctedNumber); + preciseType preciseResult = std::log10((preciseType)n.number); + preciseType functionError = preciseResult - result; + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); } - totalError = preciseCorrectedResult - result; + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; + +// modf +templated const Snum modf(const Snum& n, Snum* intpart) +{ + numberType intpartNumber; + numberType fractPartNumber = std::modf(n.number, &intpartNumber); + preciseType intpartPrecise; + preciseType fractPartPrecise = std::modf(n.corrected_number(), &intpartPrecise); + + preciseType fractTotalError = fractPartPrecise - fractPartNumber; + preciseType intTotalError = intpartPrecise - intpartNumber; + + #ifdef SHAMAN_TAGGED_ERROR + Serror fractErrorComp; + Serror intErrorComp; + if(n.error == 0) + { + fractErrorComp = Serror(fractTotalError); + intErrorComp = Serror(intTotalError); } + else + { + preciseType intPreciseResult; + preciseType fractPreciseResult = std::modf((preciseType)n.number, &intPreciseResult); - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if(n.error == 0) - { - newErrorComp = Serror(totalError); - } - else - { - preciseType preciseResult = std::log((preciseType)n.number); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); - newErrorComp.addError(functionError); - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; + preciseType intFunctionError = intPreciseResult - intpartNumber; + preciseType fractFunctionError = fractPreciseResult - fractPartNumber; + + preciseType intProportionalInputError = (intTotalError - intFunctionError) / n.error; + preciseType fractProportionalInputError = (fractTotalError - fractFunctionError) / n.error; + + intErrorComp = Serror(n.errorComposants, [intProportionalInputError](errorType e){return e*intProportionalInputError;}); + intErrorComp.addError(intFunctionError); + fractErrorComp = Serror(n.errorComposants, [fractProportionalInputError](errorType e){return e*fractProportionalInputError;}); + fractErrorComp.addError(fractFunctionError); + } + (*intpart).number = intpartNumber; + (*intpart).error = intTotalError; + (*intpart).errorComposants = intErrorComp; + return Snum(fractPartNumber, fractTotalError, fractErrorComp); + #else + (*intpart).number = intpartNumber; + (*intpart).error = intTotalError; + return Snum(fractPartNumber, fractTotalError); + #endif +}; - // log10 - templated const Snum log10(const Snum& n) - { - numberType result = std::log10(n.number); +// log1p +templated const Snum log1p(const Snum& n) +{ + numberType result = std::log1p(n.number); - preciseType totalError; - preciseType correctedNumber = n.corrected_number(); - if((correctedNumber <= 0.) && (n.number <= 0.)) + preciseType totalError; + preciseType correctedNumber = n.corrected_number(); + if((correctedNumber <= -1.) && (n.number <= -1.)) + { + // resolves the case inf-inf + totalError = 0.; + } + else + { + preciseType preciseCorrectedResult; + if (correctedNumber < -1.) { - // resolves the case inf-inf - totalError = 0.; + preciseCorrectedResult = -INFINITY; } else { - preciseType preciseCorrectedResult; - if (correctedNumber < 0) + preciseCorrectedResult = std::log1p(correctedNumber); + } + totalError = preciseCorrectedResult - result; + } + + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if(n.error == 0) { - preciseCorrectedResult = -INFINITY; + newErrorComp = Serror(totalError); } else { - preciseCorrectedResult = std::log10(correctedNumber); + preciseType preciseResult = std::log1p((preciseType)n.number); + preciseType functionError = preciseResult - result; + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); } - totalError = preciseCorrectedResult - result; - } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if(n.error == 0) - { - newErrorComp = Serror(totalError); - } - else - { - preciseType preciseResult = std::log10((preciseType)n.number); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); - newErrorComp.addError(functionError); - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; +// log2 +templated const Snum log2(const Snum& n) +{ + numberType result = std::log2(n.number); - // modf - templated const Snum modf(const Snum& n, Snum* intpart) + preciseType totalError; + preciseType correctedNumber = n.corrected_number(); + if((correctedNumber <= 0.) && (n.number <= 0.)) { - numberType intpartNumber; - numberType fractPartNumber = std::modf(n.number, &intpartNumber); - preciseType intpartPrecise; - preciseType fractPartPrecise = std::modf(n.corrected_number(), &intpartPrecise); - - preciseType fractTotalError = fractPartPrecise - fractPartNumber; - preciseType intTotalError = intpartPrecise - intpartNumber; + // resolves the case inf-inf + totalError = 0.; + } + else + { + preciseType preciseCorrectedResult; + if (correctedNumber < 0) + { + preciseCorrectedResult = -INFINITY; + } + else + { + preciseCorrectedResult = std::log2(correctedNumber); + } + totalError = preciseCorrectedResult - result; + } - #ifdef SHAMAN_TAGGED_ERROR - Serror fractErrorComp; - Serror intErrorComp; + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; if(n.error == 0) { - fractErrorComp = Serror(fractTotalError); - intErrorComp = Serror(intTotalError); + newErrorComp = Serror(totalError); } else { - preciseType intPreciseResult; - preciseType fractPreciseResult = std::modf((preciseType)n.number, &intPreciseResult); - - preciseType intFunctionError = intPreciseResult - intpartNumber; - preciseType fractFunctionError = fractPreciseResult - fractPartNumber; + preciseType preciseResult = std::log2((preciseType)n.number); + preciseType functionError = preciseResult - result; + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; - preciseType intProportionalInputError = (intTotalError - intFunctionError) / n.error; - preciseType fractProportionalInputError = (fractTotalError - fractFunctionError) / n.error; +// logb +templated const Snum logb(const Snum& n) +{ + numberType result = std::logb(n.number); - intErrorComp = Serror(n.errorComposants, [intProportionalInputError](errorType e){return e*intProportionalInputError;}); - intErrorComp.addError(intFunctionError); - fractErrorComp = Serror(n.errorComposants, [fractProportionalInputError](errorType e){return e*fractProportionalInputError;}); - fractErrorComp.addError(fractFunctionError); - } - (*intpart).number = intpartNumber; - (*intpart).error = intTotalError; - (*intpart).errorComposants = intErrorComp; - return Snum(fractPartNumber, fractTotalError, fractErrorComp); - #else - (*intpart).number = intpartNumber; - (*intpart).error = intTotalError; - return Snum(fractPartNumber, fractTotalError); - #endif - }; - - // log1p - templated const Snum log1p(const Snum& n) + preciseType totalError; + preciseType correctedNumber = n.corrected_number(); + if((correctedNumber <= 0.) && (n.number <= 0.)) { - numberType result = std::log1p(n.number); - - preciseType totalError; - preciseType correctedNumber = n.corrected_number(); - if((correctedNumber <= -1.) && (n.number <= -1.)) + // resolves the case inf-inf + totalError = 0.; + } + else + { + preciseType preciseCorrectedResult; + if (correctedNumber < 0) { - // resolves the case inf-inf - totalError = 0.; + preciseCorrectedResult = -INFINITY; } else { - preciseType preciseCorrectedResult; - if (correctedNumber < -1.) + preciseCorrectedResult = std::logb(correctedNumber); + } + totalError = preciseCorrectedResult - result; + } + + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if(n.error == 0) { - preciseCorrectedResult = -INFINITY; + newErrorComp = Serror(totalError); } else { - preciseCorrectedResult = std::log1p(correctedNumber); + preciseType preciseResult = std::logb((preciseType)n.number); + preciseType functionError = preciseResult - result; + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); } - totalError = preciseCorrectedResult - result; - } - - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if(n.error == 0) - { - newErrorComp = Serror(totalError); - } - else - { - preciseType preciseResult = std::log1p((preciseType)n.number); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); - newErrorComp.addError(functionError); - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; - // log2 - templated const Snum log2(const Snum& n) - { - numberType result = std::log2(n.number); +// scalbn +templated const Snum scalbn(const Snum &n, int power) +{ + numberType result = std::scalbn(n.number, power); + preciseType preciseCorrectedResult = std::scalbn(n.corrected_number(), power); + preciseType totalError = preciseCorrectedResult - result; - preciseType totalError; - preciseType correctedNumber = n.corrected_number(); - if((correctedNumber <= 0.) && (n.number <= 0.)) - { - // resolves the case inf-inf - totalError = 0.; - } - else - { - preciseType preciseCorrectedResult; - if (correctedNumber < 0) + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if(n.error == 0) { - preciseCorrectedResult = -INFINITY; + newErrorComp = Serror(totalError); } else { - preciseCorrectedResult = std::log2(correctedNumber); + preciseType preciseResult = std::scalbn((preciseType)n.number, power); + preciseType functionError = preciseResult - result; + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); } - totalError = preciseCorrectedResult - result; - } - - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if(n.error == 0) - { - newErrorComp = Serror(totalError); - } - else - { - preciseType preciseResult = std::log2((preciseType)n.number); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); - newErrorComp.addError(functionError); - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; - // logb - templated const Snum logb(const Snum& n) - { - numberType result = std::logb(n.number); +// scalbln +templated const Snum scalbln(const Snum &n, long int power) +{ + numberType result = std::scalbln(n.number, power); + preciseType preciseCorrectedResult = std::scalbln(n.corrected_number(), power); + preciseType totalError = preciseCorrectedResult - result; - preciseType totalError; - preciseType correctedNumber = n.corrected_number(); - if((correctedNumber <= 0.) && (n.number <= 0.)) - { - // resolves the case inf-inf - totalError = 0.; - } - else - { - preciseType preciseCorrectedResult; - if (correctedNumber < 0) + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if(n.error == 0) { - preciseCorrectedResult = -INFINITY; + newErrorComp = Serror(totalError); } else { - preciseCorrectedResult = std::logb(correctedNumber); + preciseType preciseResult = std::scalbln((preciseType)n.number, power); + preciseType functionError = preciseResult - result; + preciseType proportionalInputError = (totalError - functionError) / n.error; + newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + newErrorComp.addError(functionError); } - totalError = preciseCorrectedResult - result; - } - - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if(n.error == 0) - { - newErrorComp = Serror(totalError); - } - else - { - preciseType preciseResult = std::logb((preciseType)n.number); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); - newErrorComp.addError(functionError); - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; - // scalbn - templated const Snum scalbn(const Snum &n, int power) - { - numberType result = std::scalbn(n.number, power); - preciseType preciseCorrectedResult = std::scalbn(n.corrected_number(), power); - preciseType totalError = preciseCorrectedResult - result; +//----------------------------------------------------------------------------- +// POWER FUNCTIONS - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if(n.error == 0) - { - newErrorComp = Serror(totalError); - } - else - { - preciseType preciseResult = std::scalbn((preciseType)n.number, power); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); - newErrorComp.addError(functionError); - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; +SHAMAN_FUNCTION(cbrt); - // scalbln - templated const Snum scalbln(const Snum &n, long int power) - { - numberType result = std::scalbln(n.number, power); - preciseType preciseCorrectedResult = std::scalbln(n.corrected_number(), power); - preciseType totalError = preciseCorrectedResult - result; +// pow +templated const Snum pow(const Snum& n1, const Snum& n2) +{ + numberType result = std::pow(n1.number, n2.number); + preciseType preciseCorrectedResult = std::pow(n1.corrected_number(), n2.corrected_number()); + preciseType totalError = preciseCorrectedResult - result; - #ifdef SHAMAN_TAGGED_ERROR + #ifdef SHAMAN_TAGGED_ERROR Serror newErrorComp; - if(n.error == 0) + preciseType preciseResult = std::pow((preciseType)n1.number, (preciseType)n2.number); + preciseType functionError = preciseResult - result; + if((n1.error == 0.) && (n2.error == 0.)) + { + newErrorComp = Serror(totalError); + } + else if (n2.error == 0.) + { + preciseType proportionalInput1Error = (totalError - functionError) / n1.error; + newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); + newErrorComp.addError(functionError); + } + else if (n1.error == 0.) + { + preciseType proportionalInput2Error = (totalError - functionError) / n2.error; + newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); + newErrorComp.addError(functionError); + } + else + { + preciseType preciseCorrectedBut1Result = std::pow((preciseType)n1, n2.corrected_number()); + preciseType preciseCorrectedBut2Result = std::pow(n1.corrected_number(), (preciseType)n2); + preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; + preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; + preciseType inputError = input1Error + input2Error; + if (inputError == 0.) { - newErrorComp = Serror(totalError); + // avoid division by zero + newErrorComp = Serror(functionError); } else { - preciseType preciseResult = std::scalbln((preciseType)n.number, power); - preciseType functionError = preciseResult - result; - preciseType proportionalInputError = (totalError - functionError) / n.error; - newErrorComp = Serror(n.errorComposants, [proportionalInputError](errorType e){return e*proportionalInputError;}); + preciseType proportionality = (totalError - functionError) / inputError; + preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); + preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); + newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); newErrorComp.addError(functionError); } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; -} - -using Sstd::exp; -using Sstd::exp2; -using Sstd::expm1; -using Sstd::ilogb; -using Sstd::frexp; -using Sstd::ldexp; -using Sstd::log; -using Sstd::log10; -using Sstd::modf; -using Sstd::log1p; -using Sstd::log2; -using Sstd::logb; -using Sstd::scalbn; -using Sstd::scalbln; - -//----------------------------------------------------------------------------- -// POWER FUNCTIONS + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; +set_Sfunction2_casts(pow); -namespace Sstd +// sqrt +templated const Snum sqrt(const Snum& n) { - SHAMAN_FUNCTION(cbrt); - - // pow - templated const Snum pow(const Snum& n1, const Snum& n2) - { - numberType result = std::pow(n1.number, n2.number); - preciseType preciseCorrectedResult = std::pow(n1.corrected_number(), n2.corrected_number()); - preciseType totalError = preciseCorrectedResult - result; - - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - preciseType preciseResult = std::pow((preciseType)n1.number, (preciseType)n2.number); - preciseType functionError = preciseResult - result; - if((n1.error == 0.) && (n2.error == 0.)) - { - newErrorComp = Serror(totalError); - } - else if (n2.error == 0.) - { - preciseType proportionalInput1Error = (totalError - functionError) / n1.error; - newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); - newErrorComp.addError(functionError); - } - else if (n1.error == 0.) - { - preciseType proportionalInput2Error = (totalError - functionError) / n2.error; - newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); - newErrorComp.addError(functionError); - } - else - { - preciseType preciseCorrectedBut1Result = std::pow((preciseType)n1, n2.corrected_number()); - preciseType preciseCorrectedBut2Result = std::pow(n1.corrected_number(), (preciseType)n2); - preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; - preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; - preciseType inputError = input1Error + input2Error; - if (inputError == 0.) - { - // avoid division by zero - newErrorComp = Serror(functionError); - } - else - { - preciseType proportionality = (totalError - functionError) / inputError; - preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); - preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); - newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); - newErrorComp.addError(functionError); - } - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - set_Sfunction2_casts(pow); - - // sqrt - templated const Snum sqrt(const Snum& n) - { - numberType result = std::sqrt(n.number); - errorType newError; - - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - if (result == 0) - { - if(n.error == 0) - { - newError = 0; - newErrorComp = Serror(); - } - else - { - newError = (errorType) std::sqrt((preciseType) std::abs(n.error)); - errorType scaling = newError / n.error; - newErrorComp = Serror(n.errorComposants, [scaling](errorType e){return e*scaling;}); - } - } - else - { - numberType remainder = EFT::RemainderSqrt(n.number, result); - newError = (remainder + n.error) / (result + result); + numberType result = std::sqrt(n.number); + errorType newError; - newErrorComp = Serror(n.errorComposants); - newErrorComp.addError(remainder); - newErrorComp.divByScalar(result + result); - } - return Snum(result, newError, newErrorComp); - #else + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; if (result == 0) { if(n.error == 0) { newError = 0; + newErrorComp = Serror(); } else { newError = (errorType) std::sqrt((preciseType) std::abs(n.error)); + errorType scaling = newError / n.error; + newErrorComp = Serror(n.errorComposants, [scaling](errorType e){return e*scaling;}); } } else { numberType remainder = EFT::RemainderSqrt(n.number, result); newError = (remainder + n.error) / (result + result); - } - return Snum(result, newError); - #endif - }; - - // hypot - templated const Snum hypot(const Snum& n1, const Snum& n2) - { - numberType result = std::hypot(n1.number, n2.number); - preciseType preciseCorrectedResult = std::hypot(n1.corrected_number(), n2.corrected_number()); - preciseType totalError = preciseCorrectedResult - result; - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - preciseType preciseResult = std::hypot((preciseType)n1.number, (preciseType)n2.number); - preciseType functionError = preciseResult - result; - if((n1.error == 0.) && (n2.error == 0.)) - { - newErrorComp = Serror(totalError); - } - else if (n2.error == 0.) - { - preciseType proportionalInput1Error = (totalError - functionError) / n1.error; - newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); - newErrorComp.addError(functionError); - } - else if (n1.error == 0.) - { - preciseType proportionalInput2Error = (totalError - functionError) / n2.error; - newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); - newErrorComp.addError(functionError); - } - else - { - preciseType preciseCorrectedBut1Result = std::hypot((preciseType)n1, n2.corrected_number()); - preciseType preciseCorrectedBut2Result = std::hypot(n1.corrected_number(), (preciseType)n2); - preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; - preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; - preciseType inputError = input1Error + input2Error; - if (inputError == 0.) - { - // avoid division by zero - newErrorComp = Serror(functionError); - } - else - { - preciseType proportionality = (totalError - functionError) / inputError; - preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); - preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); - newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); - newErrorComp.addError(functionError); - } - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - set_Sfunction2_casts(hypot); + newErrorComp = Serror(n.errorComposants); + newErrorComp.addError(remainder); + newErrorComp.divByScalar(result + result); + } + return Snum(result, newError, newErrorComp); + #else + if (result == 0) + { + if(n.error == 0) + { + newError = 0; + } + else + { + newError = (errorType) std::sqrt((preciseType) std::abs(n.error)); + } + } + else + { + numberType remainder = EFT::RemainderSqrt(n.number, result); + newError = (remainder + n.error) / (result + result); + } + return Snum(result, newError); + #endif +}; - // hypot - templated const Snum hypot(const Snum& n1, const Snum& n2, const Snum& n3) - { - numberType result = std::hypot(n1.number, n2.number, n3.number); - preciseType preciseCorrectedResult = std::hypot(n1.corrected_number(), n2.corrected_number(), n3.corrected_number()); - preciseType totalError = preciseCorrectedResult - result; +// hypot +templated const Snum hypot(const Snum& n1, const Snum& n2) +{ + numberType result = std::hypot(n1.number, n2.number); + preciseType preciseCorrectedResult = std::hypot(n1.corrected_number(), n2.corrected_number()); + preciseType totalError = preciseCorrectedResult - result; #ifdef SHAMAN_TAGGED_ERROR Serror newErrorComp; - preciseType preciseResult = std::hypot((preciseType)n1.number, (preciseType)n2.number, (preciseType)n3.number); - preciseType preciseCorrectedBut1Result = std::hypot((preciseType)n1, n2.corrected_number(), n3.corrected_number()); - preciseType preciseCorrectedBut2Result = std::hypot(n1.corrected_number(), (preciseType)n2, n3.corrected_number()); - preciseType preciseCorrectedBut3Result = std::hypot(n1.corrected_number(), n2.corrected_number(), (preciseType)n3); - preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; - preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; - preciseType input3Error = preciseCorrectedResult - preciseCorrectedBut3Result; + preciseType preciseResult = std::hypot((preciseType)n1.number, (preciseType)n2.number); preciseType functionError = preciseResult - result; - if((n1.error == 0.) and (n2.error == 0.) and (n3.error == 0.)) + if((n1.error == 0.) && (n2.error == 0.)) { newErrorComp = Serror(totalError); } - else if ((n2.error == 0.) and (n3.error == 0.)) + else if (n2.error == 0.) { preciseType proportionalInput1Error = (totalError - functionError) / n1.error; newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); newErrorComp.addError(functionError); } - else if ((n1.error == 0.) and (n3.error == 0.)) + else if (n1.error == 0.) { preciseType proportionalInput2Error = (totalError - functionError) / n2.error; newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); newErrorComp.addError(functionError); } - else if ((n1.error == 0.) and (n2.error == 0.)) - { - preciseType proportionalInput3Error = (totalError - functionError) / n3.error; - newErrorComp = Serror(n3.errorComposants, [proportionalInput3Error](errorType e){return e*proportionalInput3Error;}); - newErrorComp.addError(functionError); - } - else if ((n3.error == 0) and (input1Error + input2Error != 0.)) - { - preciseType proportionality = (totalError - functionError) / (input1Error + input2Error); - preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); - preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); - newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); - newErrorComp.addError(functionError); - } - else if ((n2.error == 0) and (input1Error + input3Error != 0.)) - { - preciseType proportionality = (totalError - functionError) / (input1Error + input3Error); - preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); - preciseType proportionalInput3Error = proportionality * (input3Error / n3.error); - newErrorComp = Serror(n1.errorComposants, n3.errorComposants, [proportionalInput1Error, proportionalInput3Error](errorType e1, errorType e3){return e1*proportionalInput1Error + e3*proportionalInput3Error;}); - newErrorComp.addError(functionError); - } - else if ((n1.error == 0) and (input2Error + input3Error != 0.)) - { - preciseType proportionality = (totalError - functionError) / (input3Error + input2Error); - preciseType proportionalInput3Error = proportionality * (input3Error / n3.error); - preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); - newErrorComp = Serror(n3.errorComposants, n2.errorComposants, [proportionalInput3Error, proportionalInput2Error](errorType e3, errorType e2){return e3*proportionalInput3Error + e2*proportionalInput2Error;}); - newErrorComp.addError(functionError); - } - else if (input1Error + input2Error + input3Error != 0.) + else { + preciseType preciseCorrectedBut1Result = std::hypot((preciseType)n1, n2.corrected_number()); + preciseType preciseCorrectedBut2Result = std::hypot(n1.corrected_number(), (preciseType)n2); preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; - preciseType input3Error = preciseCorrectedResult - preciseCorrectedBut3Result; - preciseType proportionality = (totalError - functionError) / (input1Error + input2Error + input3Error); - preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); - preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); - preciseType proportionalInput3Error = proportionality * (input3Error / n3.error); - newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); - newErrorComp.addErrorsTimeScalar(n3.errorComposants, proportionalInput3Error); - newErrorComp.addError(functionError); - } - else - { - newErrorComp = Serror(functionError); - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - set_Sfunction3_casts(hypot); -} - -using Sstd::cbrt; -using Sstd::pow; -using Sstd::sqrt; -using Sstd::hypot; - -//----------------------------------------------------------------------------- -// ERROR AND GAMMA FUNCTIONS - -namespace Sstd -{ - SHAMAN_FUNCTION(erf); - SHAMAN_FUNCTION(erff); - SHAMAN_FUNCTION(erfl); - SHAMAN_FUNCTION(erfc); - SHAMAN_FUNCTION(erfcf); - SHAMAN_FUNCTION(erfcl); - SHAMAN_FUNCTION(tgamma); - SHAMAN_FUNCTION(lgamma); -} - -using Sstd::erf; -using Sstd::erff; -using Sstd::erfl; -using Sstd::erfc; -using Sstd::erfcf; -using Sstd::erfcl; -using Sstd::tgamma; -using Sstd::lgamma; - -//----------------------------------------------------------------------------- -// ROUNDING AND REMAINDER FUNCTIONS - -namespace Sstd -{ - SHAMAN_FUNCTION(ceil); - SHAMAN_FUNCTION(floor); - SHAMAN_FUNCTION(trunc); - SHAMAN_FUNCTION(round); - SHAMAN_FUNCTION(rint); - SHAMAN_FUNCTION(nearbyint); - - // fmod - templated const Snum fmod(const Snum& n1, const Snum& n2) - { - numberType result = std::fmod(n1.number, n2.number); - preciseType preciseCorrectedResult = std::fmod(n1.corrected_number(), n2.corrected_number()); - preciseType totalError = preciseCorrectedResult - result; - - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - preciseType preciseResult = std::fmod((preciseType)n1.number, (preciseType)n2.number); - preciseType functionError = preciseResult - result; - if((n1.error == 0.) && (n2.error == 0.)) - { - newErrorComp = Serror(totalError); - } - else if (n2.error == 0.) - { - preciseType proportionalInput1Error = (totalError - functionError) / n1.error; - newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); - newErrorComp.addError(functionError); - } - else if (n1.error == 0.) - { - preciseType proportionalInput2Error = (totalError - functionError) / n2.error; - newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); - newErrorComp.addError(functionError); - } - else - { - preciseType preciseCorrectedBut1Result = std::fmod((preciseType)n1, n2.corrected_number()); - preciseType preciseCorrectedBut2Result = std::fmod(n1.corrected_number(), (preciseType)n2); - preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; - preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; - preciseType inputError = input1Error + input2Error; - if (inputError == 0.) - { - // avoid division by zero - newErrorComp = Serror(functionError); - } - else - { - preciseType proportionality = (totalError - functionError) / inputError; - preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); - preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); - newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); - newErrorComp.addError(functionError); - } - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - set_Sfunction2_casts(fmod); - - // lround - templated inline const long int lround(const Snum& n) - { - return std::lround(n.number); - } - - // llround - templated inline const long long int llround(const Snum& n) - { - return std::llround(n.number); - } - - // lrint - templated inline const long int lrint(const Snum& n) - { - return std::lrint(n.number); - } - - // llrint - templated inline const long long int llrint(const Snum& n) - { - return std::llrint(n.number); - } - - // remainder - templated const Snum remainder(const Snum& n1, const Snum& n2) - { - numberType result = std::remainder(n1.number, n2.number); - preciseType preciseCorrectedResult = std::remainder(n1.corrected_number(), n2.corrected_number()); - preciseType totalError = preciseCorrectedResult - result; - - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - preciseType preciseResult = std::remainder((preciseType)n1.number, (preciseType)n2.number); - preciseType functionError = preciseResult - result; - if((n1.error == 0.) && (n2.error == 0.)) - { - newErrorComp = Serror(totalError); - } - else if (n2.error == 0.) - { - preciseType proportionalInput1Error = (totalError - functionError) / n1.error; - newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); - newErrorComp.addError(functionError); - } - else if (n1.error == 0.) + preciseType inputError = input1Error + input2Error; + if (inputError == 0.) { - preciseType proportionalInput2Error = (totalError - functionError) / n2.error; - newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); - newErrorComp.addError(functionError); + // avoid division by zero + newErrorComp = Serror(functionError); } else { - preciseType preciseCorrectedBut1Result = std::remainder((preciseType)n1, n2.corrected_number()); - preciseType preciseCorrectedBut2Result = std::remainder(n1.corrected_number(), (preciseType)n2); - preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; - preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; - preciseType inputError = input1Error + input2Error; - if (inputError == 0.) - { - // avoid division by zero - newErrorComp = Serror(functionError); - } - else - { - preciseType proportionality = (totalError - functionError) / inputError; - preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); - preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); - newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); - newErrorComp.addError(functionError); - } - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - set_Sfunction2_casts(remainder); - - // remquo - templated const Snum remquo(const Snum& n1, const Snum& n2, int* quot) - { - int dummyquot; - numberType result = std::remquo(n1.number, n2.number, quot); - preciseType preciseCorrectedResult = std::remquo(n1.corrected_number(), n2.corrected_number(), &dummyquot); - preciseType totalError = preciseCorrectedResult - result; - - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - preciseType preciseResult = std::remquo((preciseType)n1.number, (preciseType)n2.number, &dummyquot); - preciseType functionError = preciseResult - result; - if((n1.error == 0.) && (n2.error == 0.)) - { - newErrorComp = Serror(totalError); - } - else if (n2.error == 0.) - { - preciseType proportionalInput1Error = (totalError - functionError) / n1.error; - newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); - newErrorComp.addError(functionError); - } - else if (n1.error == 0.) - { - preciseType proportionalInput2Error = (totalError - functionError) / n2.error; - newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); + preciseType proportionality = (totalError - functionError) / inputError; + preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); + preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); + newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); newErrorComp.addError(functionError); } - else - { - preciseType preciseCorrectedBut1Result = std::remquo((preciseType)n1, n2.corrected_number(), &dummyquot); - preciseType preciseCorrectedBut2Result = std::remquo(n1.corrected_number(), (preciseType)n2, &dummyquot); - preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; - preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; - preciseType inputError = input1Error + input2Error; - if (inputError == 0.) - { - // avoid division by zero - newErrorComp = Serror(functionError); - } - else - { - preciseType proportionality = (totalError - functionError) / inputError; - preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); - preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); - newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); - newErrorComp.addError(functionError); - } - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - - // remquo casts - template - inline auto remquo(const S& n1, const T& n2, int* quot) -> SreturnType(n1.number,n2) - { - return remquo(SreturnType(n1.number,n2)(n1), SreturnType(n1.number,n2)(n2), quot); - }; - template - inline auto remquo(const T& n1, const S& n2, int* quot) -> SreturnType(n1, n2.number) - { - return remquo(SreturnType(n1,n2.number)(n1), SreturnType(n1,n2.number)(n2), quot); - }; - template - inline auto remquo(const S& n1, const S& n2, int* quot) -> SreturnType(n1.number, n2.number) - { - return remquo(SreturnType(n1.number,n2.number)(n1), SreturnType(n1.number,n2.number)(n2), quot); - }; -} - -using Sstd::ceil; -using Sstd::floor; -using Sstd::trunc; -using Sstd::round; -using Sstd::rint; -using Sstd::nearbyint; -using Sstd::fmod; -using Sstd::lround; -using Sstd::llround; -using Sstd::lrint; -using Sstd::llrint; -using Sstd::remainder; -using Sstd::remquo; - -//----------------------------------------------------------------------------- -// FLOATING POINT MANIPULATION FUNCTIONS + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; +set_Sfunction2_casts(hypot); -namespace Sstd +// hypot +templated const Snum hypot(const Snum& n1, const Snum& n2, const Snum& n3) { - // copysign - templated inline const Snum copysign(const Snum& n1, const Snum& n2) - { - Snum::checkUnstableBranch(n2, Snum(typename Snum::NumberType(0.))); + numberType result = std::hypot(n1.number, n2.number, n3.number); + preciseType preciseCorrectedResult = std::hypot(n1.corrected_number(), n2.corrected_number(), n3.corrected_number()); + preciseType totalError = preciseCorrectedResult - result; - numberType newNumber = std::copysign(n1.number, n2.number); - if (std::signbit(newNumber) == std::signbit(n1.number)) +#ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + preciseType preciseResult = std::hypot((preciseType)n1.number, (preciseType)n2.number, (preciseType)n3.number); + preciseType preciseCorrectedBut1Result = std::hypot((preciseType)n1, n2.corrected_number(), n3.corrected_number()); + preciseType preciseCorrectedBut2Result = std::hypot(n1.corrected_number(), (preciseType)n2, n3.corrected_number()); + preciseType preciseCorrectedBut3Result = std::hypot(n1.corrected_number(), n2.corrected_number(), (preciseType)n3); + preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; + preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; + preciseType input3Error = preciseCorrectedResult - preciseCorrectedBut3Result; + preciseType functionError = preciseResult - result; + if((n1.error == 0.) and (n2.error == 0.) and (n3.error == 0.)) + { + newErrorComp = Serror(totalError); + } + else if ((n2.error == 0.) and (n3.error == 0.)) + { + preciseType proportionalInput1Error = (totalError - functionError) / n1.error; + newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); + newErrorComp.addError(functionError); + } + else if ((n1.error == 0.) and (n3.error == 0.)) + { + preciseType proportionalInput2Error = (totalError - functionError) / n2.error; + newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); + newErrorComp.addError(functionError); + } + else if ((n1.error == 0.) and (n2.error == 0.)) + { + preciseType proportionalInput3Error = (totalError - functionError) / n3.error; + newErrorComp = Serror(n3.errorComposants, [proportionalInput3Error](errorType e){return e*proportionalInput3Error;}); + newErrorComp.addError(functionError); + } + else if ((n3.error == 0) and (input1Error + input2Error != 0.)) + { + preciseType proportionality = (totalError - functionError) / (input1Error + input2Error); + preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); + preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); + newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); + newErrorComp.addError(functionError); + } + else if ((n2.error == 0) and (input1Error + input3Error != 0.)) + { + preciseType proportionality = (totalError - functionError) / (input1Error + input3Error); + preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); + preciseType proportionalInput3Error = proportionality * (input3Error / n3.error); + newErrorComp = Serror(n1.errorComposants, n3.errorComposants, [proportionalInput1Error, proportionalInput3Error](errorType e1, errorType e3){return e1*proportionalInput1Error + e3*proportionalInput3Error;}); + newErrorComp.addError(functionError); + } + else if ((n1.error == 0) and (input2Error + input3Error != 0.)) + { + preciseType proportionality = (totalError - functionError) / (input3Error + input2Error); + preciseType proportionalInput3Error = proportionality * (input3Error / n3.error); + preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); + newErrorComp = Serror(n3.errorComposants, n2.errorComposants, [proportionalInput3Error, proportionalInput2Error](errorType e3, errorType e2){return e3*proportionalInput3Error + e2*proportionalInput2Error;}); + newErrorComp.addError(functionError); + } + else if (input1Error + input2Error + input3Error != 0.) { - return n1; + preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; + preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; + preciseType input3Error = preciseCorrectedResult - preciseCorrectedBut3Result; + preciseType proportionality = (totalError - functionError) / (input1Error + input2Error + input3Error); + preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); + preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); + preciseType proportionalInput3Error = proportionality * (input3Error / n3.error); + newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); + newErrorComp.addErrorsTimeScalar(n3.errorComposants, proportionalInput3Error); + newErrorComp.addError(functionError); } else { - return -n1; + newErrorComp = Serror(functionError); } - }; - set_Sfunction2_casts(copysign); + return Snum(result, totalError, newErrorComp); +#else + return Snum(result, totalError); +#endif +}; +set_Sfunction3_casts(hypot); - // nan - templated const Snum nan(const char* tagp) - { - return Snum(std::nan(tagp)); - }; +//----------------------------------------------------------------------------- +// ERROR AND GAMMA FUNCTIONS - // nextafter - templated inline const Snum nextafter(const Snum& n1, const Snum& n2) - { - Snum::checkUnstableBranch(n1, n2); +SHAMAN_FUNCTION(erf); +SHAMAN_FUNCTION(erff); +SHAMAN_FUNCTION(erfl); +SHAMAN_FUNCTION(erfc); +SHAMAN_FUNCTION(erfcf); +SHAMAN_FUNCTION(erfcl); +SHAMAN_FUNCTION(tgamma); +SHAMAN_FUNCTION(lgamma); + +//----------------------------------------------------------------------------- +// ROUNDING AND REMAINDER FUNCTIONS - numberType result = std::nextafter(n1.number, n2.number); - preciseType preciseCorrectedResult = std::nextafter(n1.corrected_number(), n2.corrected_number()); - preciseType totalError = preciseCorrectedResult - result; +SHAMAN_FUNCTION(ceil); +SHAMAN_FUNCTION(floor); +SHAMAN_FUNCTION(trunc); +SHAMAN_FUNCTION(round); +SHAMAN_FUNCTION(rint); +SHAMAN_FUNCTION(nearbyint); - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; +// fmod +templated const Snum fmod(const Snum& n1, const Snum& n2) +{ + numberType result = std::fmod(n1.number, n2.number); + preciseType preciseCorrectedResult = std::fmod(n1.corrected_number(), n2.corrected_number()); + preciseType totalError = preciseCorrectedResult - result; + + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + preciseType preciseResult = std::fmod((preciseType)n1.number, (preciseType)n2.number); + preciseType functionError = preciseResult - result; if((n1.error == 0.) && (n2.error == 0.)) { newErrorComp = Serror(totalError); } else if (n2.error == 0.) { - preciseType proportionalInput1Error = totalError / n1.error; + preciseType proportionalInput1Error = (totalError - functionError) / n1.error; newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); + newErrorComp.addError(functionError); } else if (n1.error == 0.) { - preciseType proportionalInput2Error = totalError / n2.error; + preciseType proportionalInput2Error = (totalError - functionError) / n2.error; newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); + newErrorComp.addError(functionError); } else { - preciseType preciseCorrectedBut1Result = std::nextafter((preciseType)n1, n2.corrected_number()); - preciseType preciseCorrectedBut2Result = std::nextafter(n1.corrected_number(), (preciseType)n2); + preciseType preciseCorrectedBut1Result = std::fmod((preciseType)n1, n2.corrected_number()); + preciseType preciseCorrectedBut2Result = std::fmod(n1.corrected_number(), (preciseType)n2); preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; preciseType inputError = input1Error + input2Error; if (inputError == 0.) { - newErrorComp = Serror(); + // avoid division by zero + newErrorComp = Serror(functionError); } else { - preciseType proportionality = totalError / inputError; + preciseType proportionality = (totalError - functionError) / inputError; preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); + newErrorComp.addError(functionError); } } return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - set_Sfunction2_casts(nextafter); + #else + return Snum(result, totalError); + #endif +}; +set_Sfunction2_casts(fmod); - // nexttoward - templated inline const Snum nexttoward(const Snum& n1, const Snum& n2) - { - Snum::checkUnstableBranch(n1, n2); +// lround +templated inline const long int lround(const Snum& n) +{ + return std::lround(n.number); +} - numberType result = std::nexttoward(n1.number, n2.number); - preciseType preciseCorrectedResult = std::nexttoward(n1.corrected_number(), n2.corrected_number()); - preciseType totalError = preciseCorrectedResult - result; +// llround +templated inline const long long int llround(const Snum& n) +{ + return std::llround(n.number); +} - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; +// lrint +templated inline const long int lrint(const Snum& n) +{ + return std::lrint(n.number); +} + +// llrint +templated inline const long long int llrint(const Snum& n) +{ + return std::llrint(n.number); +} + +// remainder +templated const Snum remainder(const Snum& n1, const Snum& n2) +{ + numberType result = std::remainder(n1.number, n2.number); + preciseType preciseCorrectedResult = std::remainder(n1.corrected_number(), n2.corrected_number()); + preciseType totalError = preciseCorrectedResult - result; + + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + preciseType preciseResult = std::remainder((preciseType)n1.number, (preciseType)n2.number); + preciseType functionError = preciseResult - result; if((n1.error == 0.) && (n2.error == 0.)) { newErrorComp = Serror(totalError); } else if (n2.error == 0.) { - preciseType proportionalInput1Error = totalError / n1.error; + preciseType proportionalInput1Error = (totalError - functionError) / n1.error; newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); + newErrorComp.addError(functionError); } else if (n1.error == 0.) { - preciseType proportionalInput2Error = totalError / n2.error; + preciseType proportionalInput2Error = (totalError - functionError) / n2.error; newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); + newErrorComp.addError(functionError); } else { - preciseType preciseCorrectedBut1Result = std::nexttoward((preciseType)n1, n2.corrected_number()); - preciseType preciseCorrectedBut2Result = std::nexttoward(n1.corrected_number(), (preciseType)n2); + preciseType preciseCorrectedBut1Result = std::remainder((preciseType)n1, n2.corrected_number()); + preciseType preciseCorrectedBut2Result = std::remainder(n1.corrected_number(), (preciseType)n2); preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; preciseType inputError = input1Error + input2Error; if (inputError == 0.) { - newErrorComp = Serror(); + // avoid division by zero + newErrorComp = Serror(functionError); } else { - preciseType proportionality = totalError / inputError; + preciseType proportionality = (totalError - functionError) / inputError; preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); - preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); - newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); - } - } - return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - set_Sfunction2_casts(nexttoward); -} - -using Sstd::copysign; -using Sstd::nan; -using Sstd::nextafter; -using Sstd::nexttoward; - -//----------------------------------------------------------------------------- -// MINIMUM MAXIMUM DIFFERENCE FUNCTIONS + preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); + newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); + newErrorComp.addError(functionError); + } + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; +set_Sfunction2_casts(remainder); -namespace Sstd +// remquo +templated const Snum remquo(const Snum& n1, const Snum& n2, int* quot) { - // fdim - templated inline const Snum fdim(const Snum& n1, const Snum& n2) - { - Snum::checkUnstableBranch(n1, n2); + int dummyquot; + numberType result = std::remquo(n1.number, n2.number, quot); + preciseType preciseCorrectedResult = std::remquo(n1.corrected_number(), n2.corrected_number(), &dummyquot); + preciseType totalError = preciseCorrectedResult - result; - numberType result = std::fdim(n1.number, n2.number); - preciseType preciseCorrectedResult = std::fdim(n1.corrected_number(), n2.corrected_number()); - preciseType totalError = preciseCorrectedResult - result; - - #ifdef SHAMAN_TAGGED_ERROR - Serror newErrorComp; - preciseType preciseResult = std::fdim((preciseType)n1.number, (preciseType)n2.number); + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + preciseType preciseResult = std::remquo((preciseType)n1.number, (preciseType)n2.number, &dummyquot); preciseType functionError = preciseResult - result; if((n1.error == 0.) && (n2.error == 0.)) { @@ -1453,8 +1164,8 @@ namespace Sstd } else { - preciseType preciseCorrectedBut1Result = std::fdim((preciseType)n1, n2.corrected_number()); - preciseType preciseCorrectedBut2Result = std::fdim(n1.corrected_number(), (preciseType)n2); + preciseType preciseCorrectedBut1Result = std::remquo((preciseType)n1, n2.corrected_number(), &dummyquot); + preciseType preciseCorrectedBut2Result = std::remquo(n1.corrected_number(), (preciseType)n2, &dummyquot); preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; preciseType inputError = input1Error + input2Error; @@ -1473,200 +1184,463 @@ namespace Sstd } } return Snum(result, totalError, newErrorComp); - #else - return Snum(result, totalError); - #endif - }; - set_Sfunction2_casts(fdim); + #else + return Snum(result, totalError); + #endif +}; - // min - templated inline const Snum min(const Snum& n1, const Snum& n2) - { - Snum::checkUnstableBranch(n1, n2); - return std::min(n1,n2); - }; - set_Sfunction2_casts(min); +// remquo casts +template +inline auto remquo(const S& n1, const T& n2, int* quot) -> SreturnType(n1.number,n2) +{ + return remquo(SreturnType(n1.number,n2)(n1), SreturnType(n1.number,n2)(n2), quot); +}; +template +inline auto remquo(const T& n1, const S& n2, int* quot) -> SreturnType(n1, n2.number) +{ + return remquo(SreturnType(n1,n2.number)(n1), SreturnType(n1,n2.number)(n2), quot); +}; +template +inline auto remquo(const S& n1, const S& n2, int* quot) -> SreturnType(n1.number, n2.number) +{ + return remquo(SreturnType(n1.number,n2.number)(n1), SreturnType(n1.number,n2.number)(n2), quot); +}; - // max - templated inline const Snum max(const Snum& n1, const Snum& n2) - { - Snum::checkUnstableBranch(n1, n2); - return std::max(n1,n2); - }; - set_Sfunction2_casts(max); +//----------------------------------------------------------------------------- +// FLOATING POINT MANIPULATION FUNCTIONS - // fmin - templated inline const Snum fmin(const Snum& n1, const Snum& n2) - { - return Sstd::min(n1, n2); - }; - set_Sfunction2_casts(fmin); +// copysign +templated inline const Snum copysign(const Snum& n1, const Snum& n2) +{ + Snum::checkUnstableBranch(n2, Snum(typename Snum::NumberType(0.))); - // fmax - templated inline const Snum fmax(const Snum& n1, const Snum& n2) + numberType newNumber = std::copysign(n1.number, n2.number); + if (std::signbit(newNumber) == std::signbit(n1.number)) { - return Sstd::max(n1, n2); - }; - set_Sfunction2_casts(fmax); -} + return n1; + } + else + { + return -n1; + } +}; +set_Sfunction2_casts(copysign); -using Sstd::fdim; -using Sstd::min; -using Sstd::max; -using Sstd::fmin; -using Sstd::fmax; +// nan +templated const Snum nan(const char* tagp) +{ + return Snum(std::nan(tagp)); +}; + +// nextafter +templated inline const Snum nextafter(const Snum& n1, const Snum& n2) +{ + Snum::checkUnstableBranch(n1, n2); + + numberType result = std::nextafter(n1.number, n2.number); + preciseType preciseCorrectedResult = std::nextafter(n1.corrected_number(), n2.corrected_number()); + preciseType totalError = preciseCorrectedResult - result; + + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if((n1.error == 0.) && (n2.error == 0.)) + { + newErrorComp = Serror(totalError); + } + else if (n2.error == 0.) + { + preciseType proportionalInput1Error = totalError / n1.error; + newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); + } + else if (n1.error == 0.) + { + preciseType proportionalInput2Error = totalError / n2.error; + newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); + } + else + { + preciseType preciseCorrectedBut1Result = std::nextafter((preciseType)n1, n2.corrected_number()); + preciseType preciseCorrectedBut2Result = std::nextafter(n1.corrected_number(), (preciseType)n2); + preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; + preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; + preciseType inputError = input1Error + input2Error; + if (inputError == 0.) + { + newErrorComp = Serror(); + } + else + { + preciseType proportionality = totalError / inputError; + preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); + preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); + newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); + } + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; +set_Sfunction2_casts(nextafter); + +// nexttoward +templated inline const Snum nexttoward(const Snum& n1, const Snum& n2) +{ + Snum::checkUnstableBranch(n1, n2); + + numberType result = std::nexttoward(n1.number, n2.number); + preciseType preciseCorrectedResult = std::nexttoward(n1.corrected_number(), n2.corrected_number()); + preciseType totalError = preciseCorrectedResult - result; + + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + if((n1.error == 0.) && (n2.error == 0.)) + { + newErrorComp = Serror(totalError); + } + else if (n2.error == 0.) + { + preciseType proportionalInput1Error = totalError / n1.error; + newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); + } + else if (n1.error == 0.) + { + preciseType proportionalInput2Error = totalError / n2.error; + newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); + } + else + { + preciseType preciseCorrectedBut1Result = std::nexttoward((preciseType)n1, n2.corrected_number()); + preciseType preciseCorrectedBut2Result = std::nexttoward(n1.corrected_number(), (preciseType)n2); + preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; + preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; + preciseType inputError = input1Error + input2Error; + if (inputError == 0.) + { + newErrorComp = Serror(); + } + else + { + preciseType proportionality = totalError / inputError; + preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); + preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); + newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); + } + } + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; +set_Sfunction2_casts(nexttoward); //----------------------------------------------------------------------------- -// OTHER FUNCTIONS +// MINIMUM MAXIMUM DIFFERENCE FUNCTIONS -namespace Sstd +// fdim +templated inline const Snum fdim(const Snum& n1, const Snum& n2) { - // abs - templated inline const Snum abs(const Snum& n) - { - Snum::checkUnstableBranch(n, Snum(typename Snum::NumberType(0.))); + Snum::checkUnstableBranch(n1, n2); - if (std::signbit(n.number)) // <=> n.number < 0 (but safe for nan) + numberType result = std::fdim(n1.number, n2.number); + preciseType preciseCorrectedResult = std::fdim(n1.corrected_number(), n2.corrected_number()); + preciseType totalError = preciseCorrectedResult - result; + + #ifdef SHAMAN_TAGGED_ERROR + Serror newErrorComp; + preciseType preciseResult = std::fdim((preciseType)n1.number, (preciseType)n2.number); + preciseType functionError = preciseResult - result; + if((n1.error == 0.) && (n2.error == 0.)) + { + newErrorComp = Serror(totalError); + } + else if (n2.error == 0.) + { + preciseType proportionalInput1Error = (totalError - functionError) / n1.error; + newErrorComp = Serror(n1.errorComposants, [proportionalInput1Error](errorType e){return e*proportionalInput1Error;}); + newErrorComp.addError(functionError); + } + else if (n1.error == 0.) { - return -n; + preciseType proportionalInput2Error = (totalError - functionError) / n2.error; + newErrorComp = Serror(n2.errorComposants, [proportionalInput2Error](errorType e){return e*proportionalInput2Error;}); + newErrorComp.addError(functionError); } else { - return n; + preciseType preciseCorrectedBut1Result = std::fdim((preciseType)n1, n2.corrected_number()); + preciseType preciseCorrectedBut2Result = std::fdim(n1.corrected_number(), (preciseType)n2); + preciseType input1Error = preciseCorrectedResult - preciseCorrectedBut1Result; + preciseType input2Error = preciseCorrectedResult - preciseCorrectedBut2Result; + preciseType inputError = input1Error + input2Error; + if (inputError == 0.) + { + // avoid division by zero + newErrorComp = Serror(functionError); + } + else + { + preciseType proportionality = (totalError - functionError) / inputError; + preciseType proportionalInput1Error = proportionality * (input1Error / n1.error); + preciseType proportionalInput2Error = proportionality * (input2Error / n2.error); + newErrorComp = Serror(n1.errorComposants, n2.errorComposants, [proportionalInput1Error, proportionalInput2Error](errorType e1, errorType e2){return e1*proportionalInput1Error + e2*proportionalInput2Error;}); + newErrorComp.addError(functionError); + } } - }; + return Snum(result, totalError, newErrorComp); + #else + return Snum(result, totalError); + #endif +}; +set_Sfunction2_casts(fdim); - // fabs - templated inline const Snum fabs(const Snum& n) - { - return Sstd::abs(n); - }; +// min +templated inline const Snum min(const Snum& n1, const Snum& n2) +{ + Snum::checkUnstableBranch(n1, n2); + return std::min(n1,n2); +}; +set_Sfunction2_casts(min); - // fma - templated const Snum fma(const Snum& n1, const Snum& n2, const Snum& n3) - { - numberType result = std::fma(n1.number, n2.number, n3.number); - - numberType remainder = EFT::ErrorFma(n1.number, n2.number, n3.number, result); - //errorType newError = remainder + (n1.number*n2.error + n2.number*n1.error) + n3.error; - errorType newError = std::fma(n2.number, n1.error, std::fma(n1.number, n2.error, remainder + n3.error)); - - #ifdef SHAMAN_TAGGED_ERROR - numberType number1 = n1.number; - numberType number2 = n2.number; - Serror newErrorComp(n1.errorComposants, n2.errorComposants, [number1, number2](errorType e1, errorType e2){return number1*e2 + number2*e1;}); - newErrorComp.addErrors(n3.errorComposants); - newErrorComp.addError(remainder); - return Snum(result, newError, newErrorComp); - #else - return Snum(result, newError); - #endif - }; - set_Sfunction3_casts(fma); -} +// max +templated inline const Snum max(const Snum& n1, const Snum& n2) +{ + Snum::checkUnstableBranch(n1, n2); + return std::max(n1,n2); +}; +set_Sfunction2_casts(max); -using Sstd::abs; -using Sstd::fabs; -using Sstd::fma; +// fmin +templated inline const Snum fmin(const Snum& n1, const Snum& n2) +{ + return Sstd::min(n1, n2); +}; +set_Sfunction2_casts(fmin); + +// fmax +templated inline const Snum fmax(const Snum& n1, const Snum& n2) +{ + return Sstd::max(n1, n2); +}; +set_Sfunction2_casts(fmax); //----------------------------------------------------------------------------- -// CLASSIFICATION FUNCTIONS +// OTHER FUNCTIONS -namespace Sstd +// abs +templated inline const Snum abs(const Snum& n) { - // fpclassify - templated inline const int fpclassify(const Snum &x) - { - return std::fpclassify(x.number); - }; + Snum::checkUnstableBranch(n, Snum(typename Snum::NumberType(0.))); - // isfinite - templated inline bool isfinite(const Snum &n) + if (std::signbit(n.number)) // <=> n.number < 0 (but safe for nan) { - return std::isfinite(n.number); - }; - - // isinf - templated inline bool isinf(const Snum &n) + return -n; + } + else { - return std::isinf(n.number); - }; + return n; + } +}; - // isnan - templated inline bool isnan(const Snum &n) - { - return std::isnan(n.number); - }; +// fabs +templated inline const Snum fabs(const Snum& n) +{ + return Sstd::abs(n); +}; - // isnormal - templated inline bool isnormal(const Snum &n) - { - // does not include unstability test to check 0 and subnormal - return std::isnormal(n.number); - }; +// fma +templated const Snum fma(const Snum& n1, const Snum& n2, const Snum& n3) +{ + numberType result = std::fma(n1.number, n2.number, n3.number); - // signbit - templated inline bool signbit(const Snum &n) - { - Snum::checkUnstableBranch(n, Snum(typename Snum::NumberType(0.))); - return std::signbit(n.number); - }; -} + numberType remainder = EFT::ErrorFma(n1.number, n2.number, n3.number, result); + //errorType newError = remainder + (n1.number*n2.error + n2.number*n1.error) + n3.error; + errorType newError = std::fma(n2.number, n1.error, std::fma(n1.number, n2.error, remainder + n3.error)); -using Sstd::fpclassify; -using Sstd::isfinite; -using Sstd::isinf; -using Sstd::isnan; -using Sstd::isnormal; -using Sstd::signbit; + #ifdef SHAMAN_TAGGED_ERROR + numberType number1 = n1.number; + numberType number2 = n2.number; + Serror newErrorComp(n1.errorComposants, n2.errorComposants, [number1, number2](errorType e1, errorType e2){return number1*e2 + number2*e1;}); + newErrorComp.addErrors(n3.errorComposants); + newErrorComp.addError(remainder); + return Snum(result, newError, newErrorComp); + #else + return Snum(result, newError); + #endif +}; +set_Sfunction3_casts(fma); + +//----------------------------------------------------------------------------- +// CLASSIFICATION FUNCTIONS + +// fpclassify +templated inline const int fpclassify(const Snum &x) +{ + return std::fpclassify(x.number); +}; + +// isfinite +templated inline bool isfinite(const Snum &n) +{ + return std::isfinite(n.number); +}; + +// isinf +templated inline bool isinf(const Snum &n) +{ + return std::isinf(n.number); +}; + +// isnan +templated inline bool isnan(const Snum &n) +{ + return std::isnan(n.number); +}; + +// isnormal +templated inline bool isnormal(const Snum &n) +{ + // does not include unstability test to check 0 and subnormal + return std::isnormal(n.number); +}; + +// signbit +templated inline bool signbit(const Snum &n) +{ + Snum::checkUnstableBranch(n, Snum(typename Snum::NumberType(0.))); + return std::signbit(n.number); +}; //----------------------------------------------------------------------------- // COMPARISON FUNCTIONS -namespace Sstd +// isgreater +templated inline const bool isgreater(const Snum &n1, const Snum &n2) { - // isgreater - templated inline const bool isgreater(const Snum &n1, const Snum &n2) - { - Snum::checkUnstableBranch(n1, n2); - return std::isgreater(n1.number, n2.number); - }; + Snum::checkUnstableBranch(n1, n2); + return std::isgreater(n1.number, n2.number); +}; - // isgreaterequal - templated inline const bool isgreaterequal(const Snum &n1, const Snum &n2) - { - Snum::checkUnstableBranch(n1, n2); - return std::isgreaterequal(n1.number, n2.number); - }; +// isgreaterequal +templated inline const bool isgreaterequal(const Snum &n1, const Snum &n2) +{ + Snum::checkUnstableBranch(n1, n2); + return std::isgreaterequal(n1.number, n2.number); +}; - // isless - templated inline const bool isless(const Snum &n1, const Snum &n2) - { - Snum::checkUnstableBranch(n1, n2); - return std::isless(n1.number, n2.number); - }; +// isless +templated inline const bool isless(const Snum &n1, const Snum &n2) +{ + Snum::checkUnstableBranch(n1, n2); + return std::isless(n1.number, n2.number); +}; - // islessequal - templated inline const bool islessequal(const Snum &n1, const Snum &n2) - { - Snum::checkUnstableBranch(n1, n2); - return std::islessequal(n1.number, n2.number); - }; +// islessequal +templated inline const bool islessequal(const Snum &n1, const Snum &n2) +{ + Snum::checkUnstableBranch(n1, n2); + return std::islessequal(n1.number, n2.number); +}; - // islessgreater - templated inline const bool islessgreater(const Snum &n1, const Snum &n2) - { - Snum::checkUnstableBranch(n1, n2); - return std::islessgreater(n1.number, n2.number); - }; +// islessgreater +templated inline const bool islessgreater(const Snum &n1, const Snum &n2) +{ + Snum::checkUnstableBranch(n1, n2); + return std::islessgreater(n1.number, n2.number); +}; - // isunordered - templated inline const bool isunordered(const Snum &n1, const Snum &n2) - { - return std::isunordered(n1.number, n2.number); - }; +// isunordered +templated inline const bool isunordered(const Snum &n1, const Snum &n2) +{ + return std::isunordered(n1.number, n2.number); +}; + +//----------------------------------------------------------------------------- +// STRING OPERATIONS + +/* + * function to convert a Snum into a string + * + * NOTE : code duplicated from .to_string() + */ +templated inline std::string to_string(const Snum& n) +{ + return n.to_string(); +}; + +//----------------------------------------------------------------------------- } +using Sstd::cos; +using Sstd::sin; +using Sstd::tan; +using Sstd::atan; +using Sstd::acos; +using Sstd::asin; +using Sstd::atan2; +using Sstd::cosh; +using Sstd::sinh; +using Sstd::tanh; +using Sstd::asinh; +using Sstd::acosh; +using Sstd::atanh; +using Sstd::exp; +using Sstd::exp2; +using Sstd::expm1; +using Sstd::ilogb; +using Sstd::frexp; +using Sstd::ldexp; +using Sstd::log; +using Sstd::log10; +using Sstd::modf; +using Sstd::log1p; +using Sstd::log2; +using Sstd::logb; +using Sstd::scalbn; +using Sstd::scalbln; +using Sstd::cbrt; +using Sstd::pow; +using Sstd::sqrt; +using Sstd::hypot; +using Sstd::erf; +using Sstd::erff; +using Sstd::erfl; +using Sstd::erfc; +using Sstd::erfcf; +using Sstd::erfcl; +using Sstd::tgamma; +using Sstd::lgamma; +using Sstd::ceil; +using Sstd::floor; +using Sstd::trunc; +using Sstd::round; +using Sstd::rint; +using Sstd::nearbyint; +using Sstd::fmod; +using Sstd::lround; +using Sstd::llround; +using Sstd::lrint; +using Sstd::llrint; +using Sstd::remainder; +using Sstd::remquo; +using Sstd::copysign; +using Sstd::nan; +using Sstd::nextafter; +using Sstd::nexttoward; +using Sstd::fdim; +using Sstd::min; +using Sstd::max; +using Sstd::fmin; +using Sstd::fmax; +using Sstd::abs; +using Sstd::fabs; +using Sstd::fma; +using Sstd::fpclassify; +using Sstd::isfinite; +using Sstd::isinf; +using Sstd::isnan; +using Sstd::isnormal; +using Sstd::signbit; using Sstd::isgreater; using Sstd::isgreaterequal; using Sstd::isless; @@ -1674,7 +1648,5 @@ using Sstd::islessequal; using Sstd::islessgreater; using Sstd::isunordered; -//----------------------------------------------------------------------------- - #undef set_Sfunction2_casts #undef set_Sfunction3_casts diff --git a/src/shaman/methods.h b/src/shaman/methods.h index 601df3240cf3b5d4062c50ada7066d6720ca6dac..7df01fb541248826d34a8551b7db6305d2b50ab2 100644 --- a/src/shaman/methods.h +++ b/src/shaman/methods.h @@ -171,7 +171,7 @@ templated inline std::ostream& operator<<(std::ostream& os, const Snum& n) int nbDigitsMax = std::numeric_limits::digits10 + 2; // since this is a maximum, we add two to avoid being too pessimistic (17 for double) numberType fdigits = std::floor(n.digits()); - if (not std::isfinite(n.number)) // not a traditional number + if (!std::isfinite(n.number)) // not a traditional number { os << n.number; } @@ -182,7 +182,7 @@ templated inline std::ostream& operator<<(std::ostream& os, const Snum& n) else if (fdigits <= 0) // no significant digits { // the first zeros might be significant - int digits = std::floor(Snum::digits(0, n.error)); + int digits = static_cast(Snum::digits(0, n.error)); if ((std::abs(n.number) >= 1) || (digits <= 0)) { @@ -198,7 +198,7 @@ templated inline std::ostream& operator<<(std::ostream& os, const Snum& n) } else // a perfectly fine number { - int digits = std::min((numberType) nbDigitsMax, fdigits); + int digits = static_cast(std::min((numberType) nbDigitsMax, fdigits)); os << std::scientific << std::setprecision(digits-1) << n.number; } @@ -243,25 +243,3 @@ templated std::string Snum::to_string() const stream << this; return stream.str(); } - -/* - * function to convert a Snum into a string - * - * NOTE : code duplicated from .to_string() - */ -templated inline std::string Sstd::to_string(const Snum& n) -{ - std::ostringstream stream; - stream << n; - return stream.str(); -}; - -/* - * convert a value into a C string (const char *) - */ -template -inline const char* Sstd::to_Cstring(const T& n) -{ - return Sstd::to_string(n).c_str(); -}; -