На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> __int128
    1. Как определить новый тип (__int128) как unsigned char из 16 байт?
    2. Можно ли сделать новый тип (__int128) примерно как __int64?
    3. Почему нигде нету нормальных библиотек на C для работы с большими числами??
      1. Нельзя.
      2. Нельзя.
      3. Нет нормальных - напиши сам. Это не архисложная задача.
        Класс написать и операции переопределить.
        Но с ним не все можно будет делать, что можно делать, например, с __int64
        Сообщение отредактировано: lunc -
          Вот тебе example (из исходников UnRAR'а, int64.cpp):

          ExpandedWrap disabled
            #ifndef NATIVE_INT64
             
            Int64::Int64()
            {
            }
             
             
            Int64::Int64(uint n)
            {
              HighPart=0;
              LowPart=n;
            }
             
             
            Int64::Int64(uint HighPart,uint LowPart)
            {
              Int64::HighPart=HighPart;
              Int64::LowPart=LowPart;
            }
             
             
            /*
            Int64 Int64::operator = (Int64 n)
            {
              HighPart=n.HighPart;
              LowPart=n.LowPart;
              return(*this);
            }
            */
             
             
            Int64 Int64::operator << (int n)
            {
              Int64 res=*this;
              while (n--)
              {
                res.HighPart<<=1;
                if (res.LowPart & 0x80000000)
                  res.HighPart|=1;
                res.LowPart<<=1;
              }
              return(res);
            }
             
             
            Int64 Int64::operator >> (int n)
            {
              Int64 res=*this;
              while (n--)
              {
                res.LowPart>>=1;
                if (res.HighPart & 1)
                  res.LowPart|=0x80000000;
                res.HighPart>>=1;
              }
              return(res);
            }
             
             
            Int64 operator / (Int64 n1,Int64 n2)
            {
              if (n1.HighPart==0 && n2.HighPart==0)
                return(Int64(0,n1.LowPart/n2.LowPart));
              int ShiftCount=0;
              while (n1>n2)
              {
                n2=n2<<1;
                if (++ShiftCount>64)
                  return(0);
              }
              Int64 res=0;
              while (ShiftCount-- >= 0)
              {
                res=res<<1;
                if (n1>=n2)
                {
                  n1-=n2;
                  ++res;
                }
                n2=n2>>1;
              }
              return(res);
            }
             
             
            Int64 operator * (Int64 n1,Int64 n2)
            {
              if (n1<0x10000 && n2<0x10000)
                return(Int64(0,n1.LowPart*n2.LowPart));
              Int64 res=0;
              for (int I=0;I<64;I++)
              {
                if (n2.LowPart & 1)
                  res+=n1;
                n1=n1<<1;
                n2=n2>>1;
              }
              return(res);
            }
             
             
            Int64 operator % (Int64 n1,Int64 n2)
            {
              if (n1.HighPart==0 && n2.HighPart==0)
                return(Int64(0,n1.LowPart%n2.LowPart));
              return(n1-n1/n2*n2);
            }
             
             
            Int64 operator + (Int64 n1,Int64 n2)
            {
              n1.LowPart+=n2.LowPart;
              if (n1.LowPart<n2.LowPart)
                n1.HighPart++;
              n1.HighPart+=n2.HighPart;
              return(n1);
            }
             
             
            Int64 operator - (Int64 n1,Int64 n2)
            {
              if (n1.LowPart<n2.LowPart)
                n1.HighPart--;
              n1.LowPart-=n2.LowPart;
              n1.HighPart-=n2.HighPart;
              return(n1);
            }
             
             
            Int64 operator += (Int64 &n1,Int64 n2)
            {
              n1=n1+n2;
              return(n1);
            }
             
             
            Int64 operator -= (Int64 &n1,Int64 n2)
            {
              n1=n1-n2;
              return(n1);
            }
             
             
            Int64 operator *= (Int64 &n1,Int64 n2)
            {
              n1=n1*n2;
              return(n1);
            }
             
             
            Int64 operator /= (Int64 &n1,Int64 n2)
            {
              n1=n1/n2;
              return(n1);
            }
             
             
            Int64 operator | (Int64 n1,Int64 n2)
            {
              n1.LowPart|=n2.LowPart;
              n1.HighPart|=n2.HighPart;
              return(n1);
            }
             
             
            /*
            inline void operator -= (Int64 &n1,unsigned int n2)
            {
              if (n1.LowPart<n2)
                n1.HighPart--;
              n1.LowPart-=n2;
            }
             
             
            inline void operator ++ (Int64 &n)
            {
              if (++n.LowPart == 0)
                ++n.HighPart;
            }
             
             
            inline void operator -- (Int64 &n)
            {
              if (n.LowPart-- == 0)
                n.HighPart--;
            }
            */
             
            bool operator == (Int64 n1,Int64 n2)
            {
              return(n1.LowPart==n2.LowPart && n1.HighPart==n2.HighPart);
            }
             
             
            bool operator > (Int64 n1,Int64 n2)
            {
              return((int)n1.HighPart>(int)n2.HighPart || n1.HighPart==n2.HighPart && n1.LowPart>n2.LowPart);
            }
             
             
            bool operator < (Int64 n1,Int64 n2)
            {
              return((int)n1.HighPart<(int)n2.HighPart || n1.HighPart==n2.HighPart && n1.LowPart<n2.LowPart);
            }
             
             
            bool operator != (Int64 n1,Int64 n2)
            {
              return(n1.LowPart!=n2.LowPart || n1.HighPart!=n2.HighPart);
            }
             
             
            bool operator >= (Int64 n1,Int64 n2)
            {
              return(n1>n2 || n1==n2);
            }
             
             
            bool operator <= (Int64 n1,Int64 n2)
            {
              return(n1<n2 || n1==n2);
            }
             
             
            void Int64::Set(uint HighPart,uint LowPart)
            {
              Int64::HighPart=HighPart;
              Int64::LowPart=LowPart;
            }
            #endif
             
            void itoa(Int64 n,char *Str)
            {
              if (n<=0xffffffff)
              {
                sprintf(Str,"%u",int64to32(n));
                return;
              }
             
              char NumStr[50];
              int Pos=0;
             
              do
              {
                NumStr[Pos++]=int64to32(n%10)+'0';
                n=n/10;
              } while (n!=0);
             
              for (int I=0;I<Pos;I++)
                Str[I]=NumStr[Pos-I-1];
              Str[Pos]=0;
            }
             
             
            Int64 atoil(char *Str)
            {
              Int64 n=0;
              while (*Str>='0' && *Str<='9')
              {
                n=n*10+*Str-'0';
                Str++;
              }
              return(n);
            }
            Спасибо за неработающий исходник. Но мне нужен работающий и желательно на C, а не CPP.
              С С все гораздо сложнее. "Мягко" инегрировать такой тип тебе не удасться.
                По-илему единственное, что здесь можно сделать - это определить струтуру с массивом и функциональными типами для арифметичеких операций.
                  Можно пример...
                    ExpandedWrap disabled
                      typedef union {
                         struct {
                            unsigned Lowest;
                            unsigned Low;
                            unsigned High;
                            unsigned Highest;
                         } Named;
                         unsigned AsArray[4];
                      } Int128;
                      void I128_And(Int128 * op1, Int128 * op2, Int128 * result) {
                         unsigned i;
                         for( i=0 ; i < 4 ; i++ ) result->AsArray[i] = op1->AsArray[i]&op2->AsArray[i];
                      }
                      void I128_Or(Int128 * op1, Int128 * op2, Int128 * result) {
                         unsigned i;
                         for( i=0 ; i < 4 ; i++ ) result->AsArray[i] = op1->AsArray[i]|op2->AsArray[i];
                      }
                      void I128_Xor(Int128 * op1, Int128 * op2, Int128 * result) {
                         unsigned i;
                         for( i=0 ; i < 4 ; i++ ) result->AsArray[i] = op1->AsArray[i]^op2->AsArray[i];
                      }
                      void I128_Not(Int128 * op, Int128 * result) {
                         unsigned i;
                         for( i=0 ; i < 4 ; i++ ) result->AsArray[i] = ~op->AsArray[i];
                      }
                    Ну и так далее.
                      typedef struct __int128 NUM;

                      typedef struct __int128_meth {
                      int (plus*) (NUM *num1, NUM *num2);
                      /* ..... */
                      }


                      typedef struct __int128 {
                      unsigned char *n;
                      int neg; // if negative
                      int top; // index of last used n+1
                      int dmax; // size of n

                      const __int128_meth *meth;
                      }

                      Вроде так...
                      Вообще в OpenSSL (www.openssl.org) реализован тип BIGNUM для работы с очень большими числами - там можно посмотреть.
                        trainer
                        А как-нибудь operator + (...) , например, можно как-то присобачить?

                        lunc
                        забадался я устанавливать openssl!! так и не установил.
                          Цитата
                          0xBAD, 13.02.04, 16:58
                          А как-нибудь operator + (...) , например, можно как-то присобачить?

                          В С? Никак. Перегрузка операторов появилась только в С++.
                            Не надо его устанавливать.
                            openssl-<version>/crypto/bn - лижат либы с реализацией BIGNUM. Я бы прям оттуда бы и выдрал, почистив то, что не нужно.

                            А зачем именно реализация оператора +. Просто из интереса...
                              Да, но там он требует всякие заголовочные файлы, пришлось копировать, редактировать... ооой...

                              Для удобства. Чтобы не пришлось заменять a = b + c на plus(a, b, c);

                              Кстати, ниче если у меня основной файл c, а библиотека для больших чисел на cpp?
                                Цитата

                                Кстати, ниче если у меня основной файл c, а библиотека для больших чисел на cpp?


                                Смотря каким компиллером собирать будешь. Сишный компиллер не потянет С++.
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0364 ]   [ 15 queries used ]   [ Generated: 21.05.24, 16:08 GMT ]