00001
00002
00005 #include "cdstd.h"
00006
00007 #if defined(__HP_aCC)
00008
00009 extern "C" unsigned long fegettrapenable();
00010 extern "C" void fesettrapenable(unsigned long);
00011 #endif
00012
00013 #if defined(__ia64) && defined(__INTEL_COMPILER)
00014 extern "C" unsigned long fpgetmask();
00015 extern "C" void fpsetmask(unsigned long);
00016 #endif
00017
00018 #if defined(__sun) || defined(__sgi)
00019 #include <ieeefp.h>
00020 #if defined(HAVE_SUNMATH) || defined(FLUSH_DENORM_TO_ZERO)
00021 #include <sunmath.h>
00022 #endif
00023 #endif
00024
00025 #if defined(__alpha) && defined(__linux) && defined(__GNUC__)
00026 #define __USE_GNU
00027 #include <fenv.h>
00028 #endif
00029
00030 #if defined(__unix) || defined(__APPLE__)
00031 #include <unistd.h>
00032 #endif
00033
00034 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
00035 #include <sys/types.h>
00036 #include <sys/sysctl.h>
00037 #endif
00038
00039
00040
00041 #include "cddefines.h"
00042 #include "cpu.h"
00043 #include "path.h"
00044 #include "trace.h"
00045
00046 STATIC NORETURN void AbortErrorMessage( const char* fname, vector<string>& PathList, access_scheme scheme );
00047
00048
00049
00050 t_cpu_i *t_cpu::m_i;
00051 static int cpu_count = 0;
00052 t_cpu::t_cpu()
00053 {
00054 if (0 == cpu_count++)
00055 {
00056 m_i = new t_cpu_i;
00057 }
00058 }
00059 t_cpu::~t_cpu()
00060 {
00061 if (0 == --cpu_count)
00062 {
00063 delete m_i;
00064 }
00065 }
00066
00067
00068 t_cpu_i::t_cpu_i()
00069 {
00070 DEBUG_ENTRY( "t_cpu_i()" );
00071
00072
00073 set_signal_handlers();
00074
00075 p_exit_status.resize( ES_TOP, "--undefined--" );
00076 p_exit_status[ES_SUCCESS] = "ok";
00077 p_exit_status[ES_FAILURE] = "early termination";
00078 p_exit_status[ES_WARNINGS] = "warnings";
00079 p_exit_status[ES_BOTCHES] = "botched monitors";
00080 p_exit_status[ES_CLOUDY_ABORT] = "cloudy abort";
00081 p_exit_status[ES_BAD_ASSERT] = "failed assert";
00082 p_exit_status[ES_BAD_ALLOC] = "failed memory alloc";
00083 p_exit_status[ES_OUT_OF_RANGE] = "array bound exceeded";
00084 p_exit_status[ES_USER_INTERRUPT] = "user interrupt";
00085 p_exit_status[ES_TERMINATION_REQUEST] = "process killed";
00086 p_exit_status[ES_ILLEGAL_INSTRUCTION] = "illegal instruction";
00087 p_exit_status[ES_FP_EXCEPTION] = "fp exception";
00088 p_exit_status[ES_SEGFAULT] = "segmentation fault";
00089 p_exit_status[ES_BUS_ERROR] = "bus error";
00090 p_exit_status[ES_UNKNOWN_SIGNAL] = "unknown signal";
00091 p_exit_status[ES_UNKNOWN_EXCEPTION] = "unknown exception";
00092
00093
00094 endian.c[0] = 0x12;
00095 endian.c[1] = 0x34;
00096 endian.c[2] = 0x56;
00097 endian.c[3] = 0x78;
00098
00099
00100
00101 if( sizeof(sys_float) == 4 )
00102 {
00103 # ifdef __mips
00104
00105 Float_SNaN_Value = 0xffffffff;
00106 # else
00107 if( big_endian() || little_endian() )
00108 {
00109
00110 Float_SNaN_Value = 0xffbfffff;
00111 }
00112 else
00113 {
00114
00115 Float_SNaN_Value = -1;
00116 }
00117 # endif
00118 }
00119 else
00120 {
00121
00122 Float_SNaN_Value = -1;
00123 }
00124
00125 # ifdef HAVE_INT64
00126
00127 if( sizeof(double) == 8 )
00128 {
00129 # ifdef __mips
00130
00131 Double_SNaN_Value = 0xffffffffffffffff;
00132 # else
00133
00134 Double_SNaN_Value = 0xfff7ffffffbfffff;
00135 # endif
00136 }
00137 else
00138 {
00139
00140 Double_SNaN_Value = -1;
00141 }
00142
00143 # else
00144
00145 if( sizeof(double) == 8 )
00146 {
00147 # ifdef __mips
00148
00149 Double_SNaN_Value[0] = 0xffffffff;
00150 Double_SNaN_Value[1] = 0xffffffff;
00151 # else
00152 if( big_endian() )
00153 {
00154
00155 Double_SNaN_Value[0] = 0xfff7ffff;
00156 Double_SNaN_Value[1] = 0xffbfffff;
00157 }
00158 else if( little_endian() )
00159 {
00160
00161 Double_SNaN_Value[0] = 0xffbfffff;
00162 Double_SNaN_Value[1] = 0xfff7ffff;
00163 }
00164 else
00165 {
00166
00167 Double_SNaN_Value[0] = -1;
00168 Double_SNaN_Value[1] = -1;
00169 }
00170 # endif
00171 }
00172 else
00173 {
00174
00175 Double_SNaN_Value[0] = -1;
00176 Double_SNaN_Value[1] = -1;
00177 }
00178
00179 # endif
00180
00181
00182 enable_traps();
00183
00184 ioStdin = stdin;
00185 ioQQQ = stdout;
00186 ioPrnErr = stderr;
00187 lgPrnErr = false;
00188
00189 test_float = FLT_MIN;
00190 test_double = DBL_MIN;
00191
00192
00193 p_lgAssertAbort = false;
00194
00195 const char *str;
00196
00197
00198 # if defined(_SC_NPROCESSORS_ONLN)
00199 n_avail_CPU = sysconf(_SC_NPROCESSORS_ONLN);
00200 # elif defined(_SC_NPROC_ONLN)
00201 n_avail_CPU = sysconf(_SC_NPROC_ONLN);
00202 # elif defined(_SC_CRAY_NCPU)
00203 n_avail_CPU = sysconf(_SC_CRAY_NCPU);
00204 # elif defined(_WIN32)
00205 str = getenv( "NUMBER_OF_PROCESSORS" );
00206 if( str != NULL )
00207 {
00208 int found = sscanf( str, "%ld", &n_avail_CPU );
00209 if( found != 1 )
00210 n_avail_CPU = 1;
00211 }
00212 else
00213 {
00214 n_avail_CPU = 1;
00215 }
00216 # elif defined(HW_AVAILCPU)
00217 int mib[2];
00218 size_t len = sizeof(n_avail_CPU);
00219 mib[0] = CTL_HW;
00220 mib[1] = HW_AVAILCPU;
00221 sysctl(mib, 2, &n_avail_CPU, &len, NULL, 0);
00222 if( n_avail_CPU < 1 )
00223 {
00224 mib[1] = HW_NCPU;
00225 sysctl(mib, 2, &n_avail_CPU, &len, NULL, 0);
00226 if( n_avail_CPU < 1 )
00227 n_avail_CPU = 1;
00228 }
00229 # else
00230
00231 n_avail_CPU = 1;
00232 # endif
00233
00234 # ifdef MPI_ENABLED
00235 p_lgMPI = true;
00236 # else
00237 p_lgMPI = false;
00238 # endif
00239
00240 p_lgMPISingleRankMode = false;
00241 n_rank = 0;
00242
00243 # ifdef _WIN32
00244 str = getenv( "COMPUTERNAME" );
00245 # else
00246 str = getenv( "HOSTNAME" );
00247 # endif
00248
00249 if( str != NULL )
00250 strncpy( HostName, str, STDLEN );
00251 else
00252 strncpy( HostName, "unknown", STDLEN );
00253 HostName[STDLEN-1] = '\0';
00254
00255
00256 const char *path = getenv( "CLOUDY_DATA_PATH" );
00257
00258
00259 string chSearchPathRaw = ( path != NULL ) ? string( path ) : string( CLOUDY_DATA_PATH );
00260
00261 # ifdef _WIN32
00262 string separator( ";" );
00263 p_chDirSeparator = '\\';
00264 # else
00265 string separator( ":" );
00266 p_chDirSeparator = '/';
00267 # endif
00268
00269 chSearchPath.push_back( "" );
00270 Split( chSearchPathRaw, separator, chSearchPath, SPM_RELAX );
00271 chSearchPath.push_back( "" );
00272
00273 for( vector<string>::size_type i=0; i < chSearchPath.size(); ++i )
00274 {
00275 if( chSearchPath[i].length() > 0 )
00276 {
00277
00278 char chEnd = *chSearchPath[i].rbegin();
00279
00280
00281 if( chEnd != p_chDirSeparator )
00282 chSearchPath[i] += p_chDirSeparator;
00283 }
00284 }
00285
00286 nFileDone = 0;
00287 }
00288
00289 void t_cpu_i::enable_traps() const
00290 {
00291
00292
00293
00294
00295
00296
00297
00298 # if defined(_MSC_VER)
00299 volatile unsigned int NewMask;
00300
00301
00302
00303
00304 NewMask = _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_INVALID;
00305
00306 NewMask = ~NewMask;
00307 _controlfp( NewMask , _MCW_EM );
00308
00309
00310
00311
00312 # elif defined(__GNUC__) && ( defined(__i386) || defined(__amd64) )
00313 volatile unsigned int Old_Mask, New_Mask;
00314 # if defined(__SSE__) || defined(__SSE2__)
00315 volatile unsigned int SSE_Mask;
00316 # endif
00317
00318 # define _FPU_MASK_IM 0x01
00319 # define _FPU_MASK_DM 0x02
00320 # define _FPU_MASK_ZM 0x04
00321 # define _FPU_MASK_OM 0x08
00322 # define _FPU_MASK_UM 0x10
00323 # define _FPU_MASK_PM 0x20
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 volatile unsigned int UnMask = ~((unsigned int)( _FPU_MASK_ZM | _FPU_MASK_IM | _FPU_MASK_OM ));
00334
00335 __asm__ volatile("fnstcw %0" : "=m" (*&Old_Mask));
00336
00337 New_Mask = Old_Mask & UnMask;
00338
00339 __asm__ volatile("fldcw %0" : : "m" (*&New_Mask));
00340
00341 # if defined(__SSE__) || defined(__SSE2__)
00342
00343 # if defined(FLUSH_DENORM_TO_ZERO)
00344
00345
00346 SSE_Mask = 0x9900;
00347 # else
00348
00349 SSE_Mask = 0x1900;
00350 # endif
00351
00352
00353
00354 __asm__ volatile( "ldmxcsr %0" : : "m" (*&SSE_Mask) );
00355
00356 # endif
00357
00358
00359 # elif defined(__ia64)
00360
00361 # define FPSR_TRAP_VD (1 << 0)
00362 # define FPSR_TRAP_DD (1 << 1)
00363 # define FPSR_TRAP_ZD (1 << 2)
00364 # define FPSR_TRAP_OD (1 << 3)
00365 # define FPSR_TRAP_UD (1 << 4)
00366 # define FPSR_TRAP_ID (1 << 5)
00367
00368 # define FPSR_SF0_FTZ (1 << 6)
00369
00370 # if defined(__GNUC_EXCL__)
00371
00372 # define _IA64_REG_AR_FPSR 40
00373
00374 # define ia64_getreg( regnum ) __asm__ volatile( "mov %0=ar%1" : "=r" (fpsr) : "i"(regnum) )
00375 # define ia64_setreg( regnum, val ) __asm__ volatile( "mov ar%0=%1" :: "i" (regnum), "r"(val): "memory" )
00376 # define ia64_serialize __asm__ volatile( "srlz.i" );
00377
00378 volatile unsigned long fpsr, flags = FPSR_TRAP_VD | FPSR_TRAP_ZD | FPSR_TRAP_OD;
00379
00380 ia64_getreg( _IA64_REG_AR_FPSR );
00381 fpsr &= ~flags;
00382 # if defined(FLUSH_DENORM_TO_ZERO)
00383 fpsr |= FPSR_SF0_FTZ;
00384 # endif
00385 ia64_setreg( _IA64_REG_AR_FPSR, fpsr );
00386
00387 ia64_serialize;
00388
00389 # elif defined(__INTEL_COMPILER)
00390
00391 unsigned long fpsr = fpgetmask();
00392 fpsr |= FPSR_TRAP_VD | FPSR_TRAP_ZD | FPSR_TRAP_OD;
00393 fpsetmask( fpsr );
00394 # elif defined(__HP_aCC)
00395
00396 unsigned long fpsr = fegettrapenable();
00397 fpsr |= FPSR_TRAP_VD | FPSR_TRAP_ZD | FPSR_TRAP_OD;
00398 fesettrapenable( fpsr );
00399 # endif
00400
00401
00402 # elif defined(__sun) || defined(__sgi)
00403
00404 fp_except mask;
00405
00406
00407 # if defined(HAVE_SUNMATH) || defined(FLUSH_DENORM_TO_ZERO)
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 nonstandard_arithmetic();
00445 # endif
00446
00447
00448 mask = fpgetmask();
00449 mask = mask | FP_X_INV | FP_X_OFL | FP_X_DZ;
00450 fpsetmask(mask);
00451
00452 # elif defined(__alpha) && defined(__linux) && defined(__GNUC__)
00453
00454
00455
00456
00457 # ifdef FE_NONIEEE_ENV
00458
00459
00460
00461 fesetenv(FE_NONIEEE_ENV);
00462 # endif
00463
00464 # endif
00465 return;
00466 }
00467
00468 void t_cpu_i::set_signal_handlers()
00469 {
00470 DEBUG_ENTRY( "set_signal_handlers()" );
00471
00472 #ifdef CATCH_SIGNAL
00473 # ifdef __unix
00474 p_action.sa_handler = &signal_handler;
00475 sigemptyset( &p_action.sa_mask );
00476 p_action.sa_flags = SA_NODEFER;
00477
00478 p_default.sa_handler = SIG_DFL;
00479 sigemptyset( &p_default.sa_mask );
00480 p_default.sa_flags = SA_NODEFER;
00481
00482 for( int sig=1; sig <= 31; sig++ )
00483 {
00484
00485 if( sigaction( sig, NULL, NULL ) == 0 )
00486
00487 if( sig != SIGSTOP && sig != SIGCONT )
00488 sigaction( sig, action(), NULL );
00489 }
00490 # endif
00491
00492 # ifdef _MSC_VER
00493 signal( SIGABRT, &signal_handler );
00494 signal( SIGFPE, &signal_handler );
00495 signal( SIGILL, &signal_handler );
00496 signal( SIGINT, &signal_handler );
00497 signal( SIGSEGV, &signal_handler );
00498 signal( SIGTERM, &signal_handler );
00499 # endif
00500 #endif
00501 }
00502
00503 void t_cpu_i::signal_handler(int sig)
00504 {
00505
00506 cpu.i().enable_traps();
00507 # ifdef _MSC_VER
00508
00509 signal( sig, &signal_handler );
00510 # endif
00511 throw bad_signal( sig );
00512 }
00513
00514
00515 void t_cpu_i::printDataPath() const
00516 {
00517 fprintf(ioQQQ, "The path is:\n");
00518 for( vector<string>::size_type i=1; i < chSearchPath.size()-1; ++i )
00519 fprintf( ioQQQ, " ==%s==\n", chSearchPath[i].c_str() );
00520 }
00521
00522
00523 void t_cpu_i::getPathList( const char* fname, vector<string>& PathList, access_scheme scheme ) const
00524 {
00525 DEBUG_ENTRY( "getPathList()" );
00526
00527 vector<string>::size_type begin, end;
00528
00529 switch( scheme )
00530 {
00531 case AS_DATA_ONLY:
00532 case AS_DATA_ONLY_TRY:
00533 case AS_DATA_OPTIONAL:
00534 begin = 1;
00535 end = cpu.i().chSearchPath.size()-1;
00536 break;
00537 case AS_DATA_LOCAL:
00538 case AS_DATA_LOCAL_TRY:
00539 begin = 1;
00540 end = cpu.i().chSearchPath.size();
00541 break;
00542 case AS_LOCAL_DATA:
00543 case AS_LOCAL_DATA_TRY:
00544 begin = 0;
00545 end = cpu.i().chSearchPath.size()-1;
00546 break;
00547 case AS_LOCAL_ONLY:
00548 case AS_LOCAL_ONLY_TRY:
00549 begin = 0;
00550 end = 1;
00551 break;
00552 default:
00553 TotalInsanity();
00554 }
00555
00556 PathList.clear();
00557 string FileName( fname );
00558 for( vector<string>::size_type i=begin; i < end; ++i )
00559 PathList.push_back( cpu.i().chSearchPath[i] + FileName );
00560 }
00561
00562 STATIC NORETURN void AbortErrorMessage( const char* fname, vector<string>& PathList, access_scheme scheme )
00563 {
00564 DEBUG_ENTRY( "AbortErrorMessage()" );
00565
00566 if( scheme == AS_DATA_OPTIONAL )
00567
00568 fprintf( ioQQQ, "\nI could not open the data file %s\n\n", fname );
00569 else
00570 fprintf( ioQQQ, "\nPROBLEM DISASTER I could not open the data file %s\n\n", fname );
00571 if( cpu.i().firstOpen() || scheme == AS_DATA_ONLY )
00572 {
00573
00574
00575 fprintf( ioQQQ, "Although there may be other reasons you have received this error,\n");
00576 fprintf( ioQQQ, "the most likely are that the path has not been properly set\n");
00577 fprintf( ioQQQ, "or that the path points to an old version of the data.\n\n");
00578 fprintf( ioQQQ, "Please have a look at the file path.h in the source directory\n");
00579 fprintf( ioQQQ, "to check how the variable CLOUDY_DATA_PATH is set - \n");
00580 fprintf( ioQQQ, "it should give the location of the data files I need.\n");
00581 fprintf( ioQQQ, "These are the files in the data download from the web site.\n\n");
00582 fprintf( ioQQQ, "Recompile the code with the correct data path set in path.h\n");
00583 fprintf( ioQQQ, "or use the shell command \nexport CLOUDY_DATA_PATH=\"/path/to/data\"\n to set the\n");
00584 fprintf( ioQQQ, "path from a bash command prompt.\n\n");
00585 cpu.i().printDataPath();
00586 }
00587 else
00588 {
00589
00590
00591
00592 fprintf( ioQQQ, "These are all the paths I tried:\n" );
00593 for( vector<string>::const_iterator ptr=PathList.begin(); ptr != PathList.end(); ++ptr )
00594 fprintf( ioQQQ, " ==%s==\n", ptr->c_str() );
00595
00596 if( scheme != AS_DATA_OPTIONAL )
00597 {
00598 fprintf( ioQQQ, "\nAlthough there may be other reasons you have received this error,\n");
00599 fprintf( ioQQQ, "the most likely are that you mistyped the file name, or that you\n");
00600 fprintf( ioQQQ, "are running Cloudy in the wrong directory. If you are running a\n");
00601 fprintf( ioQQQ, "COMPILE command, this needs to be done in the data directory.\n\n");
00602 fprintf( ioQQQ, "Otherwise, please have a look at the file path.h in the source\n");
00603 fprintf( ioQQQ, "directory to check how the variable CLOUDY_DATA_PATH is set - \n");
00604 fprintf( ioQQQ, "it should give the location of the data files I need.\n");
00605 fprintf( ioQQQ, "These are the files in the data download from the web site.\n\n");
00606 fprintf( ioQQQ, "Recompile the code with the correct data path set in path.h\n");
00607 fprintf( ioQQQ, "or use the shell command \nexport CLOUDY_DATA_PATH=\"/path/to/data\"\n to set the\n");
00608 fprintf( ioQQQ, "path from a bash command prompt.\n\n");
00609 }
00610 }
00611 fprintf(ioQQQ, "Sorry.\n\n\n");
00612 cdEXIT(EXIT_FAILURE);
00613 }
00614
00615 FILE* open_data( const char* fname, const char* mode, access_scheme scheme )
00616 {
00617 DEBUG_ENTRY( "open_data()" );
00618
00619 bool lgAbort = ( scheme == AS_DATA_ONLY || scheme == AS_DATA_OPTIONAL || scheme == AS_DATA_LOCAL ||
00620 scheme == AS_LOCAL_DATA || scheme == AS_LOCAL_ONLY );
00621
00622 vector<string> PathList;
00623 cpu.i().getPathList( fname, PathList, scheme );
00624
00625 FILE* handle = NULL;
00626 vector<string>::const_iterator ptr;
00627 for( ptr=PathList.begin(); ptr != PathList.end() && handle == NULL; ++ptr )
00628 {
00629 handle = fopen( ptr->c_str(), mode );
00630 if( trace.lgTrace )
00631 fprintf( ioQQQ, " open_data trying %s mode %s handle %p\n", ptr->c_str(), mode, handle );
00632 }
00633
00634 if( handle == NULL && lgAbort )
00635 AbortErrorMessage( fname, PathList, scheme );
00636
00637 ++cpu.i().nFileDone;
00638
00639 return handle;
00640 }
00641
00642 void open_data( fstream& stream, const char* fname, ios_base::openmode mode, access_scheme scheme )
00643 {
00644 DEBUG_ENTRY( "open_data()" );
00645
00646 bool lgAbort = ( scheme == AS_DATA_ONLY || scheme == AS_DATA_OPTIONAL || scheme == AS_DATA_LOCAL ||
00647 scheme == AS_LOCAL_DATA || scheme == AS_LOCAL_ONLY );
00648
00649 vector<string> PathList;
00650 cpu.i().getPathList( fname, PathList, scheme );
00651
00652 ASSERT( !stream.is_open() );
00653 vector<string>::const_iterator ptr;
00654 for( ptr=PathList.begin(); ptr != PathList.end() && !stream.is_open(); ++ptr )
00655 {
00656 stream.open( ptr->c_str(), mode );
00657 if( trace.lgTrace )
00658 fprintf( ioQQQ, " open_data trying %s succes? %c\n", ptr->c_str(), TorF(stream.is_open()) );
00659 }
00660
00661 if( !stream.is_open() && lgAbort )
00662 AbortErrorMessage( fname, PathList, scheme );
00663
00664 ++cpu.i().nFileDone;
00665 }
00666
00672 void set_NaN(sys_float &x)
00673 {
00674 if( sizeof(sys_float) == 4 )
00675 *reinterpret_cast<int32*>(&x) = cpu.i().Float_SNaN_Value;
00676 else
00677 x = -FLT_MAX;
00678 }
00679
00680 void set_NaN(sys_float x[],
00681 long n)
00682 {
00683 long i;
00684
00685 if( sizeof(sys_float) == 4 )
00686 {
00687 int32 *y = reinterpret_cast<int32*>(x);
00688 for( i=0; i < n; i++ )
00689 *y++ = cpu.i().Float_SNaN_Value;
00690 }
00691 else
00692 {
00693 for( i=0; i < n; i++ )
00694 x[i] = -FLT_MAX;
00695 }
00696 }
00697
00698 void set_NaN(double &x)
00699 {
00700 if( sizeof(double) == 8 )
00701 {
00702 # ifdef HAVE_INT64
00703 *reinterpret_cast<int64*>(&x) = cpu.i().Double_SNaN_Value;
00704 # else
00705 int32 *y = reinterpret_cast<int32*>(&x);
00706 *y++ = cpu.i().Double_SNaN_Value[0];
00707 *y = cpu.i().Double_SNaN_Value[1];
00708 # endif
00709 }
00710 else
00711 x = -DBL_MAX;
00712 }
00713
00714
00715 void set_NaN(double x[],
00716 long n)
00717 {
00718 long i;
00719
00720 if( sizeof(double) == 8 )
00721 {
00722 # ifdef HAVE_INT64
00723 int64 *y = reinterpret_cast<int64*>(x);
00724 for( i=0; i < n; i++ )
00725 *y++ = cpu.i().Double_SNaN_Value;
00726 # else
00727 int32 *y = reinterpret_cast<int32*>(x);
00728 for( i=0; i < n; i++ )
00729 {
00730 *y++ = cpu.i().Double_SNaN_Value[0];
00731 *y++ = cpu.i().Double_SNaN_Value[1];
00732 }
00733 # endif
00734 }
00735 else
00736 {
00737 for( i=0; i < n; i++ )
00738 x[i] = -DBL_MAX;
00739 }
00740 }
00741
00743 bool MyIsnan(const sys_float &x)
00744 {
00745 if( sizeof(sys_float) == 4 && FLT_MAX_EXP-FLT_MIN_EXP+3 == 256 )
00746 {
00747 const int32 *p = reinterpret_cast<const int32*>(&x);
00748 int32 r = *p & 0x7f800000; r ^= 0x7f800000;
00749 int32 s = *p & 0x007fffff;
00750 return ( r == 0 && s != 0 );
00751 }
00752 else
00753
00754 return false;
00755 }
00756
00758 bool MyIsnan(const double &x)
00759 {
00760 if( sizeof(double) == 8 && DBL_MAX_EXP-DBL_MIN_EXP+3 == 2048 )
00761 {
00762 # ifdef HAVE_INT64
00763 const int64 *p = reinterpret_cast<const int64*>(&x);
00764 int64 r = *p & 0x7ff0000000000000; r ^= 0x7ff0000000000000;
00765 int64 s = *p & 0x000fffffffffffff;
00766 return ( r == 0 && s != 0 );
00767 # else
00768 const int32 *p = reinterpret_cast<const int32*>(&x);
00769 if( cpu.i().little_endian() )
00770 {
00771 int32 r = p[1] & 0x7ff00000; r ^= 0x7ff00000;
00772 int32 s = p[1] & 0x000fffff; s |= p[0];
00773 return ( r == 0 && s != 0 );
00774 }
00775 else if( cpu.i().big_endian() )
00776 {
00777 int32 r = p[0] & 0x7ff00000; r ^= 0x7ff00000;
00778 int32 s = p[0] & 0x000fffff; s |= p[1];
00779 return ( r == 0 && s != 0 );
00780 }
00781 else
00782
00783 return false;
00784 # endif
00785 }
00786 else
00787
00788 return false;
00789 }