Начало Новини Маркет Проекти Форум ИТ Работа Уроци Скриптове WiFi точки Още Вход


Изчисляване на степен.

От jpg / 07.02.2009 11:25
Размер на шрифта: A | A | A

Изчисляваме всякакви степени (в рамките на машинните битове и търпението на потребителя). За сега е
възможно само с целочислени параметри и степен в границите на 0...10000000. Програмата получава параметри
от командният ред: "evalpow[.exe] value power". Примерно, за да изчислим 6789-та степен на 12345 пишем
"evalpow 12345 6789". Ако искаме да видим цялото число ( защото резултатът от примера не се събира в буфера
на конзолата ), можем да го пренасочим към текстов файл: "evalpow 12345 6789 >result.txt".
CODE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <stdio.h>

#include <vector>

using namespace std;

unsigned short fastmul[0x10000][2];

void init_fastmul( void ) {
   
unsigned i, v;
   
   
for( i = 0; i < 0x10000; i++ ) {
       
v = ( i >> 8 ) * ( i & 0xFF );
       
fastmul[i][0] = v % 100;
       
fastmul[i][1] = v / 100;
    }
}

vector<unsigned char> bcd_create( unsigned v ) {
    vector<unsigned char> rv;
   
    do { rv.push_back( v % 100 ); v
/= 100; } while( v );
   
   
return rv;
}

vector<char> bcd_tos( const vector<unsigned char> v ) {
   
vector<char> r;
   
int i = (int)v.size(), j = 0;
   
   
r.resize( i + i + 1 );
   
   
if( v[i - 1] < 10 ) {
       
r[j++] = v[--i] + '0';
   
}
   
   
while( i-- ) {
       
r[j++] = v[i] / 10 + '0';
        r[j++] = v[i] % 10 + '0';
    }
   
    r[j++] = 0;
   
    return r;
}

vector<unsigned char> bcd_mul( const vector<unsigned char> a, const vector<unsigned char> b ) {
    unsigned i, j;
   
    const unsigned asize = (unsigned)a.size();
    const unsigned bsize = (unsigned)b.size();
    unsigned rsize = asize + bsize;
   
    vector<unsigned char> rv( (size_t)rsize, 0 );
   
    for( i = 0; i < asize; i++ ) if( a[i] ) {
        unsigned v, c;
        unsigned k = i, vi = (unsigned)a[i] << 8;
       
        c = 0;
       
        if( vi ) for( j = 0; j < bsize; j++, k++ ) {
            v = rv[k] + fastmul[vi + b[j]][0] + c;
            c = fastmul[vi + b[j]][1];
           
            if( v >= 100 ) {
                v -= 100, ++c;
               
                if( v >= 100 ) v -= 100, ++c;
            }
           
            rv[k] = v;
        }
       
        while( c ) {
            rv[k++] = c % 100;
            c
/= 100;
       
}
    }
   
   
for( i = rsize; i--; ) if( rv[i] ) break;
   
   
if( rsize > ++i ) rv.resize( i );
   
   
return rv;
}

vector<unsigned char> bcd_power( unsigned v, unsigned p ) {
   
vector<unsigned char> result, bv;
   
unsigned i;
   
   
bv = bcd_create( v );
   
result = bcd_create( 1 );
   
   
for( i = 1; p; i <<= 1 ) {
       
if( i & p ) {
           
result = bcd_mul( result, bv );
           
p -= i;
       
}
       
       
if( p ) bv = bcd_mul( bv, bv );
   
}
   
   
return result;
}

int main( int argn, const char **__argv ) {
   
int v, p, s;
   
   
if( argn != 3 ) return 0;
   
   
init_fastmul();
   
   
p = atoi( __argv[2] ); p = p < 0 ? -p : p;
   
v = atoi( __argv[1] );
   
s = ( p & 1 ) & ( v < 0 );
   
v = v < 0 ? -v : v;
   
   
if( p > 10000000 ) {
       
if( v < 2 ) printf( ( s ? "-%u": "%u" ), v );
       
else printf( "I haven`t time for that!" );
   
}else {
       
vector<char> result = bcd_tos( bcd_power( v, p ) );
       
printf( ( s ? "-%s": "%s" ), &result[0] );
   
}
   
   
return 0;
}

Статистика
Погледнат: пъти
Гласове: --
Оценка:
Действие
 



myTech.bg © 2004 - 2011 | Контакти | За реклама