C语言 如何增加 int 的大小,以便我可以在其中存储 5 ^ 30 的值



我正在尝试编写一个程序,要求是将 5^30 的幂存储到 int 中,但是当我尝试这样做时,它会给出负数的输出。 双倍或长两倍运行良好

#include <stdio.h>
int PowerFive(){
int a, i, n=5, e=1;
for (i = 0; i<=30; i++)
{
a=e;
printf("%d, ", e);
e = e*n;
}
return 0;
}
int main()
{
PowerFive();
}

增加 int 的大小

编译器有时会提供int大小的控件,但通常将其固定为32,16,64,..位。 它必须至少为 16 岁。

存储值 5 ^ 30

530是 931322574615478515625,一个 70 位的数字。

C 没有为此指定足够宽的整数类型,尽管某些系统确实支持 128 位整数。

缺少 128 位整数,存储该整数值需要不同的方法。 存在各种任意宽度的库。

一个快速方法是使用字符串- 效率不高,但可以完成工作。

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *strmult(char *s, size_t size, unsigned char m) {
size_t len = strlen(s);
if (len >= size) {
return NULL;
}
int carry = 0;
for (size_t i = len; i-- > 0;) {
if (!isdigit((unsigned char ) s[i])) {
return NULL;
}
int sum = (s[i] - '0') * m + carry;
s[i] = sum % 10 + '0';
carry = sum / 10;
}
while (carry) {
if (len + 1 >= size) {
return NULL;
}
memmove(s + 1, s, len + 1);
s[0] = carry + '0';
carry /= 10;
}
return s;
}
int main(void) {
char s[100] = "1";
for (int i = 0; i < 30; i++) {
strmult(s, sizeof s, 5);
}
puts(s);
}

输出

931322574615478515625

你不能;int具有固定大小。

long可能大于int,但看起来您需要超过 64 位才能获得正确答案。 在这种情况下,最好的选择可能是使用__int128.

int的位数 ,longdouble, ...取决于实现/平台。

因此,在某些平台上,这可能不适用于long.

关于"它适用于double"的说明:一般来说,对于doublefloat,您可能会认为它有效,但答案可能是错误的:四舍五入到接近正确答案的值。

你必须实现你自己的big-int代码,它使用3(或更多)ints。

更新:关于如何快速获得5^30的快速说明,而无需专用的bigint包:

{m,g}awk 'BEGIN { CONVFMT=OFMT="%.250g"

print _ = int(__=(_+=(_^=_<_)+(_+=_))^(__+=__=++_+--_) * 
(_+=_^=!_)^-_^++_) int((__-int(__))*(--_+(_*=_+_))^_) }'
931322574615478515625

实际上,使用相同的技术,您可以利用浮点double-precision并执行非常特定类型的乘法/平方比专用bigint包快得多:

fgc; 
( time ( perl -le 'use bigint; my $__=5; $__**=537;
$__*=88777979; print int(($__)*($__))'        
) | gfactor ) | sanitize_gnu_factor
sleep .5
( time ( python3 -c '_=537; __=88777979; ___=2;____=5;
print(int(pow(pow(____,_)*__,___)))' 
) | gfactor ) | sanitize_gnu_factor
sleep .5
( time ( gawk -Mbe 'BEGIN { _=537; __=88777979; ___=2
____=5; print (____^_*__)^___ }'  
) | gfactor ) | sanitize_gnu_factor
sleep .5
( time ( mawk2 'BEGIN { CONVFMT=OFMT= "%."(-(_+=++_)-(_+=_)+_^_)"g"
print substr("",
(_=sprintf("%.*g",_^_++*_--,
(__=88777979)*__*_^-_^_-- * 
(--_)^(_++^_^--_-_*(___=(_^++_)^_+_^_+_^!_-_++)))

)~(___="^[+-]?[0]+[.][0]+"(__="")) ? sub(___,__,_) 
: gsub("[.]|^[+-]*[0]*|[Ee][+-]?[0-9]+$",__,_))_ }'
) | gfactor ) | sanitize_gnu_factor
389399298996824262817161994......640522278845310211181640625 } 767 dgts :
5^1,074
88,777,979^2

( perl -le ; )  0.03s user 0.00s system 95% cpu 0.034 total
gfactor  0.00s user 0.00s system 10% cpu 0.034 total
389399298996824262817161994......640522278845310211181640625 } 767 dgts :
5^1,074
88,777,979^2

( python3 -c ; )  0.02s user 0.01s system 86% cpu 0.035 total
gfactor  0.00s user 0.00s system 15% cpu 0.034 total
389399298996824262817161994......640522278845310211181640625 } 767 dgts :
5^1,074
88,777,979^2

( gawk -Mbe ; )  0.00s user 0.00s system 64% cpu 0.011 total
gfactor  0.00s user 0.00s system 39% cpu 0.011 total
( mawk2 ; )  0.00s user 0.00s system 59% cpu 0.005 total
gfactor  0.00s user 0.00s system 77% cpu 0.006 total
389399298996824262817161994......640522278845310211181640625 } 767 dgts :
5^1,074
88,777,979^2

  • 任务:( 5 ** 537 ) * 88777979的全精度平方,结果767 decimal digits长,大约2546.55817-bits

仅使用用户级脚本,IEEE 754双精度浮点数学,再加上一点点清理字符串操作,mawk2,一个根本没有内置bigint支持的应用程序,比所有这些都快:

  1. perl 5.34启用了 bigint 包,
  2. python 3.10.6内置的大
  3. 整数支持,以及
  4. gnu-gawk 5.1.1gnu-GMPbigint 包

====

==========================================================只要您的平台使用双精度浮点数学,您就可以免费获得integer powers of 5IEEE 754[-1023, 1074],因此您实际上不必"存储"它们本身:

jot - -100 100 13 | 
mawk '($++NF = +(__=$!____)<-(___=(_^=_<_)-+-++_+_)*!_
? sprintf("%.fe%.f", _^-__,+__)     
:+__<(___^_-_)                           
? ___^__ : substr(___="", _=sprintf("%.*f",__,
_^-__), sub("^[0.]+",___,_))_)_' CONVFMT='%.20g'
-100 1267650600228229401496703205376e-100
-87 154742504910672534362390528e-87
-74 18889465931478580854784e-74
-61 2305843009213693952e-61
-48 281474976710656e-48
-35 34359738368e-35
-22 4194304e-22
-9 512e-9
4 625
17 762939453125

30 931322574615478515625

43 1136868377216160297393798828125
56 1387778780781445675529539585113525390625
69 1694065894508600678136645001359283924102783203125
82 2067951531382569187178521730174907133914530277252197265625
95 2524354896707237777317531408904915934954260592348873615264892578125

相关内容

最新更新