Fennel: /home/pub/open/dev/fennel/calculator/ExtMath.cpp Source File (original) (raw)

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
00029 #include <math.h> 00030 00031 FENNEL_BEGIN_NAMESPACE 00032 00033 00034 void 00035 mathLn( 00036 RegisterRef* result, 00037 RegisterRef* 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* result, 00055 RegisterRef* 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* result, 00073 RegisterRef* 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* result, 00091 RegisterRef* 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* result, 00109 RegisterRef* 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* result, 00123 RegisterRef* 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* result, 00140 RegisterRef* x, 00141 RegisterRef* 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 params_2D; 00174 params_2D.push_back(STANDARD_TYPE_DOUBLE); 00175 params_2D.push_back(STANDARD_TYPE_DOUBLE); 00176 00177 vector params_DI; 00178 params_DI.push_back(STANDARD_TYPE_DOUBLE); 00179 params_DI.push_back(STANDARD_TYPE_INT_64); 00180 00181 vector 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 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 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 params_3D(params_2D); 00198 params_3D.push_back(STANDARD_TYPE_DOUBLE); 00199 00200 vector params_2I; 00201 params_2I.push_back(STANDARD_TYPE_INT_64); 00202 params_2I.push_back(STANDARD_TYPE_INT_64); 00203 00204 vector 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