DoubConv.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 // $Id:$
00003 // -----------------------------------------------------------------------
00004 //                             HEP Random
00005 //                          --- DoubConv ---
00006 //                      class implementation file
00007 // -----------------------------------------------------------------------
00008 
00009 #include "CLHEP/Random/DoubConv.h"
00010 
00011 #include <sstream>
00012 #include <iomanip>
00013 
00014 namespace CLHEP {
00015 
00016 bool DoubConv::byte_order_known = false;
00017 int  DoubConv::byte_order[8];
00018 
00019 void DoubConv::fill_byte_order () {
00020   double x = 1.0;
00021   int t30 = 1 << 30;
00022   int t22 = 1 << 22;
00023   x *= t30;
00024   x *= t22;
00025   double y = 1;
00026   double z = 1;
00027   x *= z;
00028   for (int k=0; k<6; k++) {
00029     x += y*z;
00030     y += 1;
00031     z *= 256;
00032   }
00033   // x, in IEEE format, would now be 0x4330060504030201
00034   union DB8 {
00035     unsigned char b[8];
00036     double d;
00037   };
00038   DB8 xb;
00039   xb.d = x;
00040   int n;
00041   static const int UNSET = -1; 
00042   for (n=0; n<8; n++) {
00043     byte_order[n] = UNSET;
00044   }
00045   int order;
00046   for (n=0; n<8; n++) {
00047     switch ( xb.b[n] ) {
00048       case 0x43:
00049         order = 0;
00050         break;
00051       case 0x30:
00052         order = 1;
00053         break;
00054       case 0x06:
00055         order = 2;
00056         break;
00057       case 0x05:
00058         order = 3;
00059         break;
00060       case 0x04:
00061         order = 4;
00062         break;
00063       case 0x03:
00064         order = 5;
00065         break;
00066       case 0x02:
00067         order = 6;
00068         break;
00069       case 0x01:
00070         order = 7;
00071         break;
00072       default:
00073         throw DoubConvException(
00074                 "Cannot determine byte-ordering of doubles on this system");
00075     } 
00076     if (byte_order[n] != UNSET) {
00077         throw DoubConvException(
00078                 "Confusion in byte-ordering of doubles on this system");
00079     }    
00080     byte_order[n] = order;
00081     byte_order_known = true;
00082   }
00083   return;
00084 }
00085 
00086 std::string DoubConv::d2x(double d) {
00087   if ( !byte_order_known ) fill_byte_order ();
00088   DB8 db;
00089   db.d = d;
00090   std::ostringstream ss;
00091   for (int i=0; i<8; ++i) {
00092     int k = byte_order[i];
00093     ss << std::hex << std::setw(2) << std::setfill('0') << (int)db.b[k];
00094   }
00095   return ss.str();
00096 }
00097 
00098 std::vector<unsigned long> DoubConv::dto2longs(double d) {
00099   std::vector<unsigned long> v(2);
00100   if ( !byte_order_known ) fill_byte_order ();
00101   DB8 db;
00102   db.d = d;
00103   v[0] =   ((static_cast<unsigned long>(db.b[byte_order[0]])) << 24)
00104          | ((static_cast<unsigned long>(db.b[byte_order[1]])) << 16)
00105          | ((static_cast<unsigned long>(db.b[byte_order[2]])) <<  8)
00106          | ((static_cast<unsigned long>(db.b[byte_order[3]]))      );
00107   v[1] =   ((static_cast<unsigned long>(db.b[byte_order[4]])) << 24)
00108          | ((static_cast<unsigned long>(db.b[byte_order[5]])) << 16)
00109          | ((static_cast<unsigned long>(db.b[byte_order[6]])) <<  8)
00110          | ((static_cast<unsigned long>(db.b[byte_order[7]]))      );
00111   return v; 
00112 }
00113 
00114 double DoubConv::longs2double (const std::vector<unsigned long> & v) {
00115   DB8 db;
00116   unsigned char bytes[8];
00117   if ( !byte_order_known ) fill_byte_order ();
00118   bytes[0] = static_cast<unsigned char>((v[0] >> 24) & 0xFF);
00119   bytes[1] = static_cast<unsigned char>((v[0] >> 16) & 0xFF);
00120   bytes[2] = static_cast<unsigned char>((v[0] >>  8) & 0xFF);
00121   bytes[3] = static_cast<unsigned char>((v[0]      ) & 0xFF);
00122   bytes[4] = static_cast<unsigned char>((v[1] >> 24) & 0xFF);
00123   bytes[5] = static_cast<unsigned char>((v[1] >> 16) & 0xFF);
00124   bytes[6] = static_cast<unsigned char>((v[1] >>  8) & 0xFF);
00125   bytes[7] = static_cast<unsigned char>((v[1]      ) & 0xFF);
00126   for (int i=0; i<8; ++i) {
00127     db.b[byte_order[i]] =  bytes[i];
00128   }  
00129   return db.d;
00130 }
00131 
00132 } // end namespace CLHEP

Generated on Mon May 27 17:47:34 2013 for Geant4 by  doxygen 1.4.7