00001 extern "C"
00002 {
00003 #include "scs.h"
00004 }
00005 #include <stdlib.h>
00006 #include <stdio.h>
00007 #include <math.h>
00008 #include <iostream.h>
00009
00010 #ifndef SCS_WRAPPER_CPP
00011 #define SCS_WRAPPER_CPP 1
00012
00013 extern "C" int scs_cmp_mant(scs_ptr , scs_ptr);
00014
00015 class Scs{
00016 private:
00017 scs scsnb;
00018
00019 public:
00020
00021 Scs(){}
00022 Scs(double &d){scs_set_d(&scsnb, d);}
00023 Scs(int &i){scs_set_si(&scsnb, i);}
00024 Scs(const Scs& nb);
00025 ~Scs(){};
00026
00027
00028 void scs_set_sign (int i) {this->scsnb.sign = i;}
00029 void scs_set_index(int i) {this->scsnb.index = i;}
00030 void scs_set_excep(double d) {this->scsnb.exception.d = d;}
00031 void scs_set_words(unsigned int word[SCS_NB_WORDS]){for(int i=0; i<SCS_NB_WORDS; i++) this->scsnb.h_word[i] = word[i];}
00032
00033
00034 operator double();
00035 operator int();
00036
00037
00038
00039 Scs operator-() const;
00040 friend Scs fabs(const Scs &a);
00041
00042
00043 Scs &operator=(const Scs &nb1);
00044 Scs &operator=(const double nb1);
00045 Scs &operator=(const int i){scs_set_si(&scsnb, i);}
00046
00047
00048 friend Scs operator+(Scs &nb1,Scs &nb2);
00049 friend Scs operator+(Scs &nb1, const double &nb2);
00050 friend Scs operator+(const double &nb1,Scs &nb2);
00051 void operator+=(Scs &nb);
00052 void operator+=(const double nb);
00053
00054
00055 friend Scs operator-(Scs &nb1,Scs &nb2);
00056 friend Scs operator-(Scs &nb1, const double &nb2);
00057 friend Scs operator-(const double &nb1,Scs &nb2);
00058 void operator-=(Scs &nb);
00059 void operator-=(const double nb);
00060
00061
00062 friend Scs operator*(Scs &nb1,Scs &nb2);
00063 friend Scs operator*(Scs &nb1, const double &nb2);
00064 friend Scs operator*(const double &nb1,Scs &nb2);
00065 friend Scs operator*(Scs &nb1, const int &nb2);
00066 friend Scs operator*(const int &nb1,Scs &nb2);
00067 void operator*=(Scs &nb);
00068 void operator*=(const double nb);
00069 void operator*=(const int nb);
00070
00071
00072 friend Scs operator/(Scs &nb1,Scs &nb2);
00073 friend Scs operator/(Scs &nb1, const double &nb2);
00074 friend Scs operator/(const double &nb1,Scs &nb2);
00075 void operator/=(Scs &nb);
00076 void operator/=(const double nb);
00077
00078
00079 friend bool operator==(Scs &nb1,Scs &nb2);
00080 friend bool operator!=(Scs &nb1,Scs &nb2);
00081 friend bool operator<=(Scs &nb1,Scs &nb2);
00082 friend bool operator>=(Scs &nb1,Scs &nb2);
00083 friend bool operator<(Scs &nb1,Scs &nb2);
00084 friend bool operator>(Scs &nb1,Scs &nb2);
00085
00086
00087 Scs rand(void);
00088
00089
00090 friend ostream& operator<<(ostream &s, const Scs &a);
00091 friend istream& operator>>(istream &s, Scs &a);
00092
00093 };
00094
00095
00096
00097
00098
00099
00100
00101 Scs::Scs(const Scs& nb){
00102 unsigned int i;
00103
00104 for(i=0; i<SCS_NB_WORDS; i++)
00105 this->scsnb.h_word[i] = nb.scsnb.h_word[i];
00106
00107 this->scsnb.exception.d = nb.scsnb.exception.d;
00108 this->scsnb.index = nb.scsnb.index;
00109 this->scsnb.sign = nb.scsnb.sign;
00110 }
00111
00112
00113
00114
00115 inline Scs::operator double() {
00116 double d;
00117 scs_get_d(&d, &(this->scsnb));
00118 return d;
00119 }
00120 inline Scs::operator int() {
00121 double d;
00122 scs_get_d(&d, &(this->scsnb));
00123 return ((int)d);
00124 }
00125
00126
00127
00128
00129
00130
00131 inline Scs &Scs::operator=(const Scs& nb){
00132 unsigned int i;
00133
00134 for(i=0; i<SCS_NB_WORDS; i++)
00135 scsnb.h_word[i] = nb.scsnb.h_word[i];
00136
00137 scsnb.exception.d = nb.scsnb.exception.d;
00138 scsnb.index = nb.scsnb.index;
00139 scsnb.sign = nb.scsnb.sign;
00140
00141 return *this;
00142 }
00143 inline Scs &Scs::operator=(const double nb){
00144 scs_set_d(&(this->scsnb), nb);
00145 return *this;
00146 }
00147 inline Scs fabs(const Scs &a){
00148 Scs res(a);
00149 res.scsnb.sign = 1;
00150 return res;
00151 }
00152
00153
00154
00155
00156
00157 inline Scs operator+(Scs &nb1,Scs &nb2){
00158 Scs res; scs_add(&(res.scsnb), &(nb1.scsnb), &(nb2.scsnb));
00159 return res;
00160 }
00161 inline Scs operator+(Scs &nb1,const double &nb2){
00162 Scs res, op;
00163 scs_set_d(&(op.scsnb), nb2);
00164 scs_add(&(res.scsnb), &(nb1.scsnb), &(op.scsnb));
00165 return res;
00166 }
00167 inline Scs operator+(const double &nb1, Scs &nb2){
00168 Scs res, op;
00169 scs_set_d(&(op.scsnb), nb1);
00170 scs_add(&(res.scsnb), &(nb2.scsnb), &(op.scsnb));
00171 return res;
00172 }
00173 void inline Scs::operator+=(Scs &nb) {
00174 scs_add(&(this->scsnb), &(this->scsnb), &(nb.scsnb));
00175 }
00176 void inline Scs::operator+=(const double nb) {
00177 Scs op;
00178 scs_set_d(&(op.scsnb), nb);
00179 scs_add(&(this->scsnb), &(this->scsnb), &(op.scsnb));
00180 }
00181
00182
00183
00184
00185
00186
00187
00188 inline Scs operator-(Scs &nb1,Scs &nb2){
00189 Scs res; scs_sub(&(res.scsnb), &(nb1.scsnb), &(nb2.scsnb));
00190 return res;
00191 }
00192 inline Scs operator-(Scs &nb1,const double &nb2){
00193 Scs res, op;
00194 scs_set_d(&(op.scsnb), nb2);
00195 scs_sub(&(res.scsnb), &(nb1.scsnb), &(op.scsnb));
00196 return res;
00197 }
00198 inline Scs operator-(const double &nb1, Scs &nb2){
00199 Scs res, op;
00200 scs_set_d(&(op.scsnb), nb1);
00201 scs_sub(&(res.scsnb), &(nb2.scsnb), &(op.scsnb));
00202 return res;
00203 }
00204 void inline Scs::operator-=(Scs &nb) {
00205 scs_sub(&(this->scsnb), &(this->scsnb), &(nb.scsnb));
00206 }
00207 void inline Scs::operator-=(const double nb) {
00208 Scs op;
00209 scs_set_d(&(op.scsnb), nb);
00210 scs_sub(&(this->scsnb), &(this->scsnb), &(op.scsnb));
00211 }
00212
00213
00214
00215
00216
00217
00218 inline Scs operator*(Scs &nb1,Scs &nb2){
00219 Scs res; scs_mul(&(res.scsnb), &(nb1.scsnb), &(nb2.scsnb));
00220 return res;
00221 }
00222 inline Scs operator*(Scs &nb1,const double &nb2){
00223 Scs res, op;
00224 scs_set_d(&(op.scsnb), nb2);
00225 scs_mul(&(res.scsnb), &(nb1.scsnb), &(op.scsnb));
00226 return res;
00227 }
00228 inline Scs operator*(const double &nb1, Scs &nb2){
00229 Scs res, op;
00230 scs_set_d(&(op.scsnb), nb1);
00231 scs_mul(&(res.scsnb), &(nb2.scsnb), &(op.scsnb));
00232 return res;
00233 }
00234 inline Scs operator*(Scs &nb1, const int &nb2){
00235 Scs res;
00236 scs_set(&(res.scsnb), &(nb1.scsnb));
00237 scs_mul_ui(&(res.scsnb), nb2);
00238 return res;
00239 }
00240 inline Scs operator*(const int &nb1, Scs &nb2){
00241 Scs res;
00242 scs_set(&(res.scsnb), &(nb2.scsnb));
00243 scs_mul_ui(&(res.scsnb), nb1);
00244 return res;
00245 }
00246 void inline Scs::operator*=(Scs &nb) {
00247 scs_mul(&(this->scsnb), &(this->scsnb), &(nb.scsnb));
00248 }
00249 void inline Scs::operator*=(const double nb) {
00250 Scs op;
00251 scs_set_d(&(op.scsnb), nb);
00252 scs_mul(&(this->scsnb), &(this->scsnb), &(op.scsnb));
00253 }
00254 void inline Scs::operator*=(const int nb) {
00255 scs_mul_ui(&(this->scsnb), nb);
00256 }
00257
00258
00259
00260
00261
00262
00263 inline Scs operator/(Scs &nb1,Scs &nb2){
00264 Scs res; scs_div(&(res.scsnb), &(nb1.scsnb), &(nb2.scsnb));
00265 return res;
00266 }
00267 inline Scs operator/(Scs &nb1, const double &nb2){
00268 Scs res, op;
00269 scs_set_d(&(op.scsnb), nb2);
00270 scs_div(&(res.scsnb), &(nb1.scsnb), &(op.scsnb));
00271 return res;
00272 }
00273 inline Scs operator/(const double &nb1, Scs &nb2){
00274 Scs res, op;
00275 scs_set_d(&(op.scsnb), nb1);
00276 scs_div(&(res.scsnb), &(nb2.scsnb), &(op.scsnb));
00277 return res;
00278 }
00279 void inline Scs::operator/=(Scs &nb) {
00280 scs_div(&(this->scsnb), &(this->scsnb), &(nb.scsnb));
00281 }
00282 void inline Scs::operator/=(const double nb) {
00283 Scs op;
00284 scs_set_d(&(op.scsnb), nb);
00285 scs_div(&(this->scsnb), &(this->scsnb), &(op.scsnb));
00286 }
00287
00288
00289
00290
00291
00292
00293 inline bool operator==(Scs &nb1, Scs &nb2){
00294 unsigned int i;
00295 bool b=1;
00296
00297 for(i=0; i<SCS_NB_WORDS; i++)
00298 if (nb1.scsnb.h_word[i] == nb2.scsnb.h_word[i]) b=0;
00299
00300 return ((nb1.scsnb.exception.d == nb2.scsnb.exception.d)&&
00301 (nb1.scsnb.index == nb2.scsnb.index)&&
00302 (nb1.scsnb.sign == nb2.scsnb.sign)&& b);
00303 }
00304 inline bool operator!=(Scs &nb1, Scs &nb2){
00305 return !(nb1==nb2);
00306 }
00307 inline bool operator<=(Scs &nb1, Scs &nb2){
00308 return ((nb1.scsnb.exception.d <= nb2.scsnb.exception.d)&&
00309 (nb1.scsnb.sign <= nb2.scsnb.sign)&&
00310 ((nb1.scsnb.index < nb2.scsnb.index)||
00311 ((nb1.scsnb.index == nb2.scsnb.index)&&
00312 (scs_cmp_mant(&(nb1.scsnb), &(nb2.scsnb))<=0))));
00313 }
00314 inline bool operator>=(Scs &nb1, Scs &nb2){
00315 return ((nb1.scsnb.exception.d >= nb2.scsnb.exception.d)&&
00316 (nb1.scsnb.sign >= nb2.scsnb.sign)&&
00317 ((nb1.scsnb.index > nb2.scsnb.index)||
00318 ((nb1.scsnb.index == nb2.scsnb.index)&&
00319 (scs_cmp_mant(&(nb1.scsnb), &(nb2.scsnb))>=0))));
00320 }
00321 inline bool operator<(Scs &nb1, Scs &nb2){
00322 return ((nb1.scsnb.exception.d <= nb2.scsnb.exception.d)&&
00323 (nb1.scsnb.sign <= nb2.scsnb.sign)&&
00324 ((nb1.scsnb.index < nb2.scsnb.index)||
00325 ((nb1.scsnb.index == nb2.scsnb.index)&&
00326 (scs_cmp_mant(&(nb1.scsnb), &(nb2.scsnb))<0))));
00327 }
00328 inline bool operator>(Scs &nb1, Scs &nb2){
00329 return ((nb1.scsnb.exception.d >= nb2.scsnb.exception.d)&&
00330 (nb1.scsnb.sign >= nb2.scsnb.sign)&&
00331 ((nb1.scsnb.index > nb2.scsnb.index)||
00332 ((nb1.scsnb.index == nb2.scsnb.index)&&
00333 (scs_cmp_mant(&(nb1.scsnb), &(nb2.scsnb))>0))));
00334 }
00335
00336
00337
00338
00339
00340
00341
00342 inline Scs Scs::rand(void){
00343 scs_rand(&(this->scsnb), 200);
00344 return *this;
00345 }
00346
00347
00348
00349
00350
00351
00352
00353 ostream &operator<<(ostream &os, const Scs &a){
00354 Scs aa, p, zer;
00355 double d;
00356 char buffer[10];
00357 int e, exposant;
00358 bool bb;
00359
00360 if (a.scsnb.exception.d != 1.){
00361 os << (double)a.scsnb.exception.d;
00362 }else {
00363 if (a.scsnb.sign == -1)
00364 os << '-';
00365
00366 aa = fabs(a);
00367
00368
00369 d = ((a.scsnb.index)*SCS_NB_BITS)/4;
00370 e = 4*(int)floor(d);
00371
00372 p = 1;
00373 p.scsnb.index = (int)floor(((double)e)/SCS_NB_BITS);
00374 p.scsnb.h_word[0] = 1 << e - p.scsnb.index*SCS_NB_BITS;
00375 exposant = (int)floor(d);
00376 p /= 16;
00377 exposant--;
00378 while(p <= aa){
00379 p *= 16;
00380 exposant++;
00381 }
00382 p /= 16;
00383 exposant--;
00384
00385
00386 aa = aa / p;
00387 sprintf(buffer,"%x", aa.scsnb.h_word[0]);
00388 os << buffer << ".";
00389 aa.scsnb.h_word[0] = 0;
00390 aa *= 16;
00391
00392 bb = 1;
00393 while(bb){
00394 sprintf(buffer,"%x", aa.scsnb.h_word[0]);
00395 os << buffer;
00396 aa.scsnb.h_word[0] = 0;
00397 aa *= 16;
00398
00399 bb = 0;
00400 for(int i=0; i<SCS_NB_WORDS; i++)
00401 if (aa.scsnb.h_word[i] != 0) bb=1;
00402 }
00403
00404
00405 os << " x16^(" << exposant <<")";
00406 }
00407
00408 return os;
00409 }
00410
00411
00412
00413
00414
00415 istream& operator>>(istream &is, Scs &a){
00416 char c;
00417 int nd = 0;
00418 int point = -1;
00419 int ex;
00420 bool done = false;
00421 Scs r;
00422
00423 r = 0;
00424
00425
00426 do{
00427 is>>c;
00428 }while (c == ' ');
00429
00430
00431 while (!done && (c != '\0')) {
00432 if (c >= '0' && c <= '9') {
00433 int d = c - '0';
00434 r *= 10.0;
00435 r += d;
00436 nd++;
00437 } else {
00438 switch (c) {
00439 case '.':
00440 point = nd;
00441 break;
00442 case '-':
00443 case '+':
00444 if (nd > 0){
00445 a = 0;
00446 done = true;
00447 point = -1;
00448 ex = 0;
00449 }
00450 a.scsnb.sign = (c == '-') ? -1 : 1;
00451 break;
00452 case 'E':
00453 case 'e':
00454 is >> ex;
00455 done = true;
00456 break;
00457 default:
00458 a = 0;
00459 done = true;
00460 point = -1;
00461 ex = 0;
00462 }
00463 }
00464 is>>c;
00465 }
00466
00467 if (point >= 0)
00468 ex -= (nd - point);
00469
00470
00471 if (ex != 0) {
00472 if (ex > 0)
00473 for(int i=0; i<ex; i++)
00474 r *= 10;
00475 if (ex < 0){
00476 Scs inv_ten, ten;
00477 ten = 10;
00478 scs_inv(&(inv_ten.scsnb), &(ten.scsnb) );
00479 for(int i=0; i>ex; i--)
00480 r *= inv_ten;
00481 }
00482 }
00483 }
00484 #endif
00485
00486