[英]C: f>0 vs Perl: $f>0?
此C代碼顯示斐波納契數:
#include <stdio.h>
int main(){
for (long long int t, i=1, p=1, f=2; f>0 ; i++, t=f, f+=p, p=t)
printf("%lli: %lli\n", i, f);
}
如預期的那樣,它無需硬編碼迭代次數即可停止。
Perl中的代碼正在嘗試使用相同的技術:
my $t;
my $p=1;
my $f=2;
for ($i=1; $f>0; $t=$f, $f+=$p, $p=$t, $i++){
printf("%i: %i\n", $i, $f);
if ($i>50){exit;}
}
但是它並沒有像預期的那樣停止,在額外檢查開始時,該值從45而不是51溢出。
44: 1836311903
45: -1323752223
46: -1
47: -1
48: -1
49: -1
50: -1
51: -1
Perl有何不同之處導致此?
Perl使用任意類型,根據需要在無符號和有符號整數以及浮點數之間切換。 但是,printf強制將任意類型轉換為整數。 嘗試改用%s:
my $t;
my $p=1;
my $f=2;
for ($i=1; $f>0; $t=$f, $f+=$p, $p=$t, $i++){
printf("%i: %s\n", $i, $f);
if ($i>50){exit;}
}
實際上,較大的負數以無符號整數的形式存儲在perl中; -1太大的浮點數將被截斷為最大無符號整數,但隨后被%i視為有符號。
您的C帶符號整數代碼從大量溢出到一個負數並停止。 Perl對浮點pt數學的使用使它能夠以降低的精度進行更多的迭代,而且我認為當數字真的很大時,它將不會結束。
由於不良的編程習慣,您的c
代碼實際上正在退出。 您所依賴的f
是long long int
,其上限為9.22337204×10 ^ 18。 當您遍歷第91次迭代時, f
變為1.22001604×10 ^ 19,它溢出並變為負數。
Perl代碼會繼續愉快地運行,但是,您應該注意到,最終您將打印出一個-1
s序列,這應該是您的代碼不正確的線索。
如果您對整數大小沒有任何限制,則您的c
代碼將永遠繼續運行,這可能不是您想要的。 對於斐波那契數列之類的無限序列,您希望具有暫停條件。
Perl代碼可能默認為浮點運算。 這似乎表明了這一點 。 嘗試拋出一個use integer;
在那里。
您在Perl中使用32位整數,在C中使用較大的整數。32位不足以存儲這些數字。 您可以按照建議的方式重建Perl以使用64位整數,或者讓Perl使用浮點指針數字(無損失的53位整數)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.