トップ «前の日記(2016-04-23(Sat)) 最新 次の日記(2016-04-25(Mon))» 編集

屑俺日記

僕の備忘録(PC、UN*X、ネットワーク関連が中心)なんです。
自分の書いたところは適当(な時とか)に書き換えますので御了承を。


2016-04-24(Sun) すでに (1+ date)

RasPIのFreeBSDでも

日付が変わる前に 書いたところをFreeBSD+ccで追試。

$ uname -a
FreeBSD rpi-b 10.3-PRERELEASE FreeBSD 10.3-PRERELEASE
 #0 r294913: Wed Jan 27 20:59:13 UTC 2016
 root@releng1.nyi.freebsd.org:/usr/obj/arm.armv6/usr/src/sys/RPI-B  arm
 
$ cc --version
FreeBSD clang version 3.4.1 (tags/RELEASE_34/dot1-final 208032) 20140512
Target: armv6--freebsd10.3-gnueabi
Thread model: posi

計算結果が2^31より大きいと正確な値が出ないのは同じ。
入力値は349494まで受け入れた。

$ ./rec 349494
943660621
 
$ ./rec 349495
Segmentation fault (core dumped)

これは何度実行しても変らなかった。

あと、うんと煩そうな警告オプションを付けたときの コンパイル時の警告も。

$ cc -W -pedantic -o rec rec.c
rec.c:12:14: warning: unused parameter 'argc' [-Wunused-parameter]
int main(int argc, char **argv)
             ^
1 warning generated

Raspbianでも

同じものを 懲りずに追試。

$ uname -a
Linux RaspberryPI2 4.4.7-v7+ #878 SMP 
Tue Apr 19 19:03:45 BST 2016 armv7l GNU/Linux
 
$ gcc --version
gcc (Raspbian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying
conditions.  There is NO warranty; not even for
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

基本的な動作特性は同じ。
入力値が524126で間違った同じ答えを出力し、 それを越えると必ずSegmentation Fault。

念には念を入れ

普通の順列計算も確認。

#include<stdio.h>
#include<stdlib.h>
int seq();
 
int seq(int n)
{
  int z = 0;
  for(int y = 0; y <= n; y++)
    z = z + y;
  return z;
}
 
int main(int argc, char **argv)
{
  int arg_num = atoi(argv[1]);
  printf("%d\n", seq(arg_num));
  return 0;
}
$ ./ordinal_seq 10
55
$ ./ordinal_seq 65535
2147450880
$ ./ordinal_seq 65536
-2147450880
 
$ ./ordinal_seq `echo 2^31|bc`
0

セグメント違反の代りに毎回0を返す。
入力値が2^31-1だと、かなりの時間がかかる模様で ちょっと追試しかねた。

65535は2^16-1だった。

桁溢れはしないけど

#include<stdio.h>
#include<stdlib.h>
 
int rec();
 
int rec(int n){
  if (n == 0)
    return 0;
  else
    return  1 + rec(n - 1);
}
 
int main(int argc , char **argv)
{
  int rec_num =  atoi(argv[1]);
  printf("%d\n", rec(rec_num));
  return 0;
}
$ ./rec3 100
100
 
$ ./rec3 261900
261900
 
$ ./rec3 261900
Segmentation fault
 
$ for x in `seq 100`
>  do ./rec3 261900
>  done | grep -c 261
57

再帰の深さ自体は処理系や動作環境に依存する模様。
Raspbian(gcc4.9.2)では 524129まで同じ値を返していたが、 それを越えると必ずSegmentation Faultになった。
ともかく、こちらでは「時々変る」ことはなさげ。

もう少し簡略に

再帰が深すぎると、時々おかしくなることの 追試がやりやすいように。

#include<stdio.h>
 
int main() {
  int rec(int n){
    if (n == 0)
      return 0;
    else
      return  1 + rec(n - 1);
  }
 
  printf("%d\n", rec(261900));
  return 0;
}

リンクはご自由にどうぞ。でもURLや内容が変った場合はあしからず。

index.htmlは ここから。