00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "fennel/common/CommonPreamble.h"
00025 #include "fennel/calculator/ExtMath.h"
00026 #include "fennel/calculator/ExtendedInstructionTable.h"
00027 #include "fennel/tuple/StandardTypeDescriptor.h"
00028 #include <cstdlib>
00029 #include <math.h>
00030
00031 FENNEL_BEGIN_NAMESPACE
00032
00033
00034 void
00035 mathLn(
00036 RegisterRef<double>* result,
00037 RegisterRef<double>* x)
00038 {
00039 assert(StandardTypeDescriptor::isApprox(x->type()));
00040
00041 if (x->isNull()) {
00042 result->toNull();
00043 } else if (x->value() <= 0.0) {
00044 result->toNull();
00045
00046 throw "22023";
00047 } else {
00048 result->value(log(x->value()));
00049 }
00050 }
00051
00052 void
00053 mathLn(
00054 RegisterRef<double>* result,
00055 RegisterRef<long long>* x)
00056 {
00057 assert(StandardTypeDescriptor::isExact(x->type()));
00058
00059 if (x->isNull()) {
00060 result->toNull();
00061 } else if (x->value() <= 0) {
00062 result->toNull();
00063
00064 throw "22023";
00065 } else {
00066 result->value(log(double(x->value())));
00067 }
00068 }
00069
00070 void
00071 mathLog10(
00072 RegisterRef<double>* result,
00073 RegisterRef<double>* x)
00074 {
00075 assert(StandardTypeDescriptor::isApprox(x->type()));
00076
00077 if (x->isNull()) {
00078 result->toNull();
00079 } else if (x->value() <= 0.0) {
00080 result->toNull();
00081
00082 throw "22023";
00083 } else {
00084 result->value(log10(x->value()));
00085 }
00086 }
00087
00088 void
00089 mathLog10(
00090 RegisterRef<double>* result,
00091 RegisterRef<long long>* x)
00092 {
00093 assert(StandardTypeDescriptor::isExact(x->type()));
00094
00095 if (x->isNull()) {
00096 result->toNull();
00097 } else if (x->value() <= 0) {
00098 result->toNull();
00099
00100 throw "22023";
00101 } else {
00102 result->value(log10(double(x->value())));
00103 }
00104 }
00105
00106 void
00107 mathAbs(
00108 RegisterRef<double>* result,
00109 RegisterRef<double>* x)
00110 {
00111 assert(StandardTypeDescriptor::isApprox(x->type()));
00112
00113 if (x->isNull()) {
00114 result->toNull();
00115 } else {
00116 result->value(fabs(x->value()));
00117 }
00118 }
00119
00120 void
00121 mathAbs(
00122 RegisterRef<long long>* result,
00123 RegisterRef<long long>* x)
00124 {
00125 assert(x->type() == STANDARD_TYPE_INT_64);
00126
00127 if (x->isNull()) {
00128 result->toNull();
00129 } else {
00130
00131
00132
00133 result->value(std::abs(x->value()));
00134 }
00135 }
00136
00137 void
00138 mathPow(
00139 RegisterRef<double>* result,
00140 RegisterRef<double>* x,
00141 RegisterRef<double>* y)
00142 {
00143 assert(StandardTypeDescriptor::isApprox(x->type()));
00144 assert(StandardTypeDescriptor::isApprox(y->type()));
00145
00146 if (x->isNull() || y->isNull()) {
00147 result->toNull();
00148 } else {
00149 double r = pow(x->value(), y->value());
00150 if ((x->value() == 0.0 && y->value() < 0.0) ||
00151 (x->value() < 0.0 && isnan(r)))
00152 {
00153
00154
00155
00156
00157
00158 result->toNull();
00159
00160 throw "22023";
00161
00162 } else {
00163 result->value(r);
00164 }
00165 }
00166 }
00167
00168 void
00169 ExtMathRegister(ExtendedInstructionTable* eit)
00170 {
00171 assert(eit != NULL);
00172
00173 vector<StandardTypeDescriptorOrdinal> params_2D;
00174 params_2D.push_back(STANDARD_TYPE_DOUBLE);
00175 params_2D.push_back(STANDARD_TYPE_DOUBLE);
00176
00177 vector<StandardTypeDescriptorOrdinal> params_DI;
00178 params_DI.push_back(STANDARD_TYPE_DOUBLE);
00179 params_DI.push_back(STANDARD_TYPE_INT_64);
00180
00181 vector<StandardTypeDescriptorOrdinal> params_DII;
00182 params_DII.push_back(STANDARD_TYPE_DOUBLE);
00183 params_DII.push_back(STANDARD_TYPE_INT_64);
00184 params_DII.push_back(STANDARD_TYPE_INT_64);
00185
00186 vector<StandardTypeDescriptorOrdinal> params_DID;
00187 params_DID.push_back(STANDARD_TYPE_DOUBLE);
00188 params_DID.push_back(STANDARD_TYPE_INT_64);
00189 params_DID.push_back(STANDARD_TYPE_DOUBLE);
00190
00191 vector<StandardTypeDescriptorOrdinal> params_DDI;
00192 params_DDI.push_back(STANDARD_TYPE_DOUBLE);
00193 params_DDI.push_back(STANDARD_TYPE_DOUBLE);
00194 params_DDI.push_back(STANDARD_TYPE_INT_64);
00195
00196
00197 vector<StandardTypeDescriptorOrdinal> params_3D(params_2D);
00198 params_3D.push_back(STANDARD_TYPE_DOUBLE);
00199
00200 vector<StandardTypeDescriptorOrdinal> params_2I;
00201 params_2I.push_back(STANDARD_TYPE_INT_64);
00202 params_2I.push_back(STANDARD_TYPE_INT_64);
00203
00204 vector<StandardTypeDescriptorOrdinal> params_3I(params_2I);
00205 params_3I.push_back(STANDARD_TYPE_INT_64);
00206
00207 eit->add(
00208 "LN", params_2D,
00209 (ExtendedInstruction2<double, double>*) NULL,
00210 &mathLn);
00211
00212 eit->add(
00213 "LN", params_DI,
00214 (ExtendedInstruction2<double, long long>*) NULL,
00215 &mathLn);
00216
00217 eit->add(
00218 "LOG10", params_2D,
00219 (ExtendedInstruction2<double, double>*) NULL,
00220 &mathLog10);
00221
00222 eit->add(
00223 "LOG10", params_DI,
00224 (ExtendedInstruction2<double, long long>*) NULL,
00225 &mathLog10);
00226
00227 eit->add(
00228 "ABS", params_2D,
00229 (ExtendedInstruction2<double, double>*) NULL,
00230 &mathAbs);
00231
00232 eit->add(
00233 "ABS", params_2I,
00234 (ExtendedInstruction2<long long, long long>*) NULL,
00235 &mathAbs);
00236
00237 eit->add(
00238 "POW", params_3D,
00239 (ExtendedInstruction3<double, double, double>*) NULL,
00240 &mathPow);
00241
00242 }
00243
00244
00245 FENNEL_END_NAMESPACE
00246
00247