Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.12.249] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
1. Как определить новый тип (__int128) как unsigned char из 16 байт?
2. Можно ли сделать новый тип (__int128) примерно как __int64? 3. Почему нигде нету нормальных библиотек на C для работы с большими числами?? |
Сообщ.
#2
,
|
|
|
1. Нельзя.
2. Нельзя. 3. Нет нормальных - напиши сам. Это не архисложная задача. |
Сообщ.
#3
,
|
|
|
Класс написать и операции переопределить.
Но с ним не все можно будет делать, что можно делать, например, с __int64 |
Сообщ.
#4
,
|
|
|
Вот тебе example (из исходников UnRAR'а, int64.cpp):
#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); } |
Сообщ.
#5
,
|
|
|
Спасибо за неработающий исходник. Но мне нужен работающий и желательно на C, а не CPP.
|
Сообщ.
#6
,
|
|
|
С С все гораздо сложнее. "Мягко" инегрировать такой тип тебе не удасться.
|
Сообщ.
#7
,
|
|
|
По-илему единственное, что здесь можно сделать - это определить струтуру с массивом и функциональными типами для арифметичеких операций.
|
Сообщ.
#8
,
|
|
|
Можно пример...
|
Сообщ.
#9
,
|
|
|
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]; } |
Сообщ.
#10
,
|
|
|
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 для работы с очень большими числами - там можно посмотреть. |
Сообщ.
#11
,
|
|
|
trainer
А как-нибудь operator + (...) , например, можно как-то присобачить? lunc забадался я устанавливать openssl!! так и не установил. |
Сообщ.
#12
,
|
|
|
Цитата 0xBAD, 13.02.04, 16:58 А как-нибудь operator + (...) , например, можно как-то присобачить? В С? Никак. Перегрузка операторов появилась только в С++. |
Сообщ.
#13
,
|
|
|
Не надо его устанавливать.
openssl-<version>/crypto/bn - лижат либы с реализацией BIGNUM. Я бы прям оттуда бы и выдрал, почистив то, что не нужно. А зачем именно реализация оператора +. Просто из интереса... |
Сообщ.
#14
,
|
|
|
Да, но там он требует всякие заголовочные файлы, пришлось копировать, редактировать... ооой...
Для удобства. Чтобы не пришлось заменять a = b + c на plus(a, b, c); Кстати, ниче если у меня основной файл c, а библиотека для больших чисел на cpp? |
Сообщ.
#15
,
|
|
|
Цитата Кстати, ниче если у меня основной файл c, а библиотека для больших чисел на cpp? Смотря каким компиллером собирать будешь. Сишный компиллер не потянет С++. |