我做了一个代码来初始化字符向量,用随机数表示超过20.000位数的很大的数字。加法和乘法是正确的,但我的代码太慢(1分钟)。我知道我可以将char改为64 int,一次用19个数字进行操作,而不是一次用一个数字,但我不知道如何做到这一点,而不改变当前的输出是正确的。
谢谢你的帮忙
#include <stdio.h>
#include <stdlib.h>
unsigned int seed;
int newrandom() {
seed = (214013*seed+2531011);
return (seed>>13);
}
void LongNumInit( char *L, unsigned N )
{
for ( int i=0; i< N; i++ )
{
L[i] = newrandom() % 10;
}
}
void PrintNumber( char *L, unsigned N, char *Name )
{
printf("%s:", Name);
for ( int i=N; i>0; i-- )
{
printf("%d", L[i-1]);
}
printf("\n");
}
void ValueSet( char *L, unsigned N, char digit )
{
for ( int i=0; i< N; i++ )
{
L[i] = digit;
}
}
void CPNumber( char *Vin, char *Vout, unsigned N )
{
for ( int i=0; i< N; i++ )
{
Vout[i] = Vin[i];
}
}
char Add( char *Vin1, char *Vin2, char *Vout, unsigned N )
{
char CARRY = 0;
for ( int i=0; i< N; i++ )
{
char R = Vin1[i] + Vin2[i] + CARRY;
if ( R <= 9 )
{
Vout[i] = R; CARRY = 0;
}
else
{
Vout[i] = R-10; CARRY = 1;
}
}
return CARRY;
}
char DigitAddition( char *V, char digit, unsigned N )
{
int i=0;
char R = V[0] + digit;
if (R < 10)
{
V[0] = R; return 0;
}
V[0] = R-10;
char CARRY = 1;
i = 1;
while ( CARRY && i < N )
{
if ( V[i] < 9 )
{
V[i] = V[i] + 1; CARRY = 0;
}
else
{
V[i] = 0; i++;
}
}
return CARRY;
}
char AddInHorizontal( char *Vin, char *Vout, unsigned N )
{
char CARRY = 0;
ValueSet ( Vout, N, 0 );
for ( int i=0; i< N; i++ )
{
DigitAddition ( Vout, Vin[i], N );
}
return 0;
}
char MultiplyConst( char *V, unsigned N, char digit )
{
char CARRY = 0;
for ( int i=0; i< N; i++ )
{
char R = V[i] * digit + CARRY;
CARRY = R / 10;
R = R - CARRY*10;
V[i] = R;
}
return CARRY; // may be from 0 to 9
}
void Mult( char *Vin1, char *Vin2, char *VoutH, char *VoutL, unsigned N )
{
unsigned char *TEMP= (unsigned char*) malloc( 2*N*sizeof(unsigned char) );
unsigned char *RES = (unsigned char*) malloc( 2*N*sizeof(unsigned char) );
ValueSet ( RES, 2*N, 0 ); // Set RES to 0
for ( int i=0; i<N; i++ )
{
ValueSet ( TEMP, 2*N, 0 );
CPNumber ( Vin1, TEMP+i, N );
MultiplyConst( TEMP, 2*N, Vin2[i] );
Add ( TEMP, RES, RES, 2*N ); // TEMP + RES -> RES
}
CPNumber ( RES, VoutL, N );
CPNumber ( RES+N, VoutH, N );
}
int main (int argc, char **argv)
{
int i, sum1, sum2, sum3, N=20000;
seed = 12345;
if (argc>1) { N = atoi(argv[1]); }
if (argc>2) { Rep = atoi(argv[2]); }
unsigned char *V1= (unsigned char*) malloc( N*sizeof(unsigned char) );
unsigned char *V2= (unsigned char*) malloc( N*sizeof(unsigned char) );
unsigned char *V3= (unsigned char*) malloc( N*sizeof(unsigned char) );
unsigned char *V4= (unsigned char*) malloc( N*sizeof(unsigned char) );
LongNumInit ( V1, N );
LongNumInit ( V2, N );
LongNumInit ( V3, N );
Add ( V1, V2, V4, N );
Mult ( V3, V4, V2, V1, N );
AddInHorizontal ( V1, V2, N );
DigitAddition ( V3, V2[0], N );
PrintNumber( V1, 32, "V1" );
PrintNumber( V2, 32, "V2" );
PrintNumber( V3, 32, "V3" );
PrintNumber( V4, 32, "V4" );
free(V1);
free(V2);
free(V3);
free(V4);
return 0;
}
```发布于 2020-04-18 14:09:25
祝贺您的代码已经准备好进行检查了!下面是一些关于如何改进这一点的想法:
C和C++。在我看来,这看起来完全像C代码。如果是,请编辑标签。如果这需要同时用作C和C++代码,则需要指定应用哪些其他约束。snake_case编写。对于在共享数据类型上操作的函数模块,经常使用短前缀。由于您将对象称为"LongNum",我建议您将函数重命名为使用lnum_、lngn_或lnm_之类的前缀。char添加( char *Vin1,char *Vin2,char *Vout,unsigned N) {.}变为char lnum_add(char * ln1,char *ln2,char *lnout,unsigned N){.}malloc()或free()调用,而是应该调用lnum_new_random()和lnum_delete()。new和免费函数delete。N来指定数据类型的最大长度,不如构建一个struct来存储信息。首先,您可以用max_digits值和指向数字缓冲区开头的指针定义一个结构。更高级的版本将消除指针,并在max_digits值之后立即分配数字缓冲区。struct {无符号的max_digits;char *位;};通过这样做,您可以决定将对象作为指针传递还是以结构值的形式传递更有意义。因此,您需要一个您控制的命名类型,而不仅仅是让用户在一个char *指针周围传递:ty胡枝子结构LNUM;// if struct LNUM包含数字作为指针,typedef结构LNUM * LNUM;// if struct LNUM包括数组数字LNUM发送到流上,另一个函数用提供的基将一个LNUM写入字符串缓冲区。size_t lnum_formatted_length(LNUM );lnum_format_to_string(LNUM,char * buffer,size_t max_chars);N视为常量,不如动态计算N是否是错误的?乘法函数返回两个数字,"low“和"high",每个都是N大小。为什么不简单地返回一个具有由乘法函数确定的正确大小的数字呢?也许它需要更多的数字,也许它不需要。https://codereview.stackexchange.com/questions/240732
复制相似问题