我正在尝试编写一个程序,要求是将 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
的位数 ,long
,double
, ...取决于实现/平台。
因此,在某些平台上,这可能不适用于long
.
关于"它适用于double
"的说明:一般来说,对于double
或float
,您可能会认为它有效,但答案可能是错误的:四舍五入到接近正确答案的值。
你必须实现你自己的big-int代码,它使用3(或更多)int
s。
更新:关于如何快速获得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
支持的应用程序,比所有这些都快:
perl 5.34
启用了 bigint 包,- 整数支持,以及
gnu-gawk 5.1.1
与gnu-GMP
bigint 包
python 3.10.6
内置的大====
==========================================================只要您的平台使用双精度浮点数学,您就可以免费获得integer powers of 5
IEEE 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