C言語なら俺に聞け(入門篇) Part 34at TECH
C言語なら俺に聞け(入門篇) Part 34 - 暇つぶし2ch436:デフォルトの名無しさん
08/08/19 19:36:17
誰か、いまだにエンディアンについてよくわかってない俺に図解!マンガでわかるエンディアンを頼む

437:デフォルトの名無しさん
08/08/19 19:42:35
>>436
数字があるとするじゃん。
一番上の位から読む?(ビッグエンディアン)
それとも一番下の位から読む?(リトルエンディアン)
って話。

438:デフォルトの名無しさん
08/08/19 19:44:20
>>437
いやそれは違う・・・

メモリ上に複数バイトで構成される数字を格納した際の
格納のされ方の違いだよ。



439:デフォルトの名無しさん
08/08/19 19:50:02
エンディアン糞フカナイ

440:デフォルトの名無しさん
08/08/19 20:45:12
>>439
汚ぇなぁ、おい。

>>435
>431

>>416
unix系なら、gettimeofday()がそこそこ使える。こいつは実時間だ。
既に指摘の通り、clock()はCPU時間だから要注意だ。

441:デフォルトの名無しさん
08/08/19 21:00:10
>>423
比較する関数を作ればいいだけなんじゃないの?
エンディアンを意識してどうこうするよりよほど楽だと思うんだけど

442:デフォルトの名無しさん
08/08/19 21:06:39
>>423
こんなんとか
int cmp(int a[4], int b[4]){
int i, ret;

for(i=0;i<4;i++){
ret=a[i]-b[i];
if(ret) break;
}
return ret;
}

443:デフォルトの名無しさん
08/08/19 21:38:42
いつのことだったか、ガリバーという人が訪ねたある国の人々が、
卵を大きい方の端から割る派閥(ビッグエンディアン)と、
卵を小さい方の端から割る派閥(リトルエンディアン)とに分かれて
争っていたんだそうな(とある国の政治家の風刺でもあるんだが)。
それにちなんで、MSBから先に格納するのをビッグエンディアン、
LSBから先に格納するのをリトルエンディアンと呼ぶんじゃよ。


444:デフォルトの名無しさん
08/08/19 21:46:40
扱う数値の範囲によっては>>442だとオーバーフローして逆の符号を返す可能性もある

445:デフォルトの名無しさん
08/08/19 21:48:34
計算結果がオーバーフローorアンダーフローしてるかどうかを調べることってできる?

446:デフォルトの名無しさん
08/08/19 21:50:30
>>445
標準Cの範囲内では無理じゃないかな?

447:デフォルトの名無しさん
08/08/19 22:11:52
>>440
ちょw
条件後付

448:440
08/08/19 22:38:10
>>447
私に言うな。

449:デフォルトの名無しさん
08/08/19 22:53:17
ふつうに計算じゃなくてビット演算組み合わせればオーバーフローもチェックできるんじゃね?って思った

450:デフォルトの名無しさん
08/08/19 23:01:45
>>445,446,449
できるよ。
符号付きとなしとで微妙に変わるけど、加減算なら二つの数値の
最上位ビット見ればいい。
乗除算もちょっと手間かかるけどできなくはない。


451:デフォルトの名無しさん
08/08/19 23:09:23
具体的にどうやんの
加算でもいいから教えてくだちい

452:デフォルトの名無しさん
08/08/19 23:16:07
符号付での二つでの足し算で言うと
負と負なら答えは負なので最上位ビットは普通はずっと1、 オーバー フローすると0になる
負と正ならそもそもオーバーフローしない
正と正ならオーバーフローすると最上位は1になる

そんな感じ

453:デフォルトの名無しさん
08/08/19 23:17:01
桁あふれか

加算なら結果からもう一回引いてみればいいんじゃね?
元の数字に復元できれば桁あふれ無し。
元の数字にもどら無ければ桁あふれあり

454:デフォルトの名無しさん
08/08/19 23:26:06
オーバーフローした結果から引いたらアンダーフローして元に戻ると思うよ
・・・アンダーフローって意味違うような気がした

455:デフォルトの名無しさん
08/08/19 23:27:45
半分のビット数ごとに分けて計算する

456:デフォルトの名無しさん
08/08/19 23:31:35
>>453
お戯れを。

457:デフォルトの名無しさん
08/08/19 23:33:35
logで計算する

458:デフォルトの名無しさん
08/08/19 23:38:17
logで足し算できるものなら教えて欲しい。

459:デフォルトの名無しさん
08/08/19 23:39:47
指でも折って数えるんだ
足りなくなったら隣の人の借りろ
マイナスなど知らん

460:デフォルトの名無しさん
08/08/19 23:44:17
>>445
そもそも、どんなデータなんだよ。
そのオーバーフローやアンダーフローを気にしなくてはいけないデータというのは。

461:デフォルトの名無しさん
08/08/19 23:51:07
int add(int a, int b, int *p_is_overflow){
int chk_type, result, is_over_flow=0;

chk_type=(a<0)*2+(b<0);
result=a+b;
switch(chk_type){
case 0: if(result>0) is_over_flow=1; break; // a, b ともに 0 以上なので解も 0 以上になるべき
case 3: if(result<0) is_over_flow=1; break; // a, b ともに 0 未満なので解も 0 未満になるべき
}
if(p_is_over_flow) *p_is_over_flow=is_over_flow;

return result;
}

462:デフォルトの名無しさん
08/08/19 23:52:00
>>461 case の 0 と 3 間違えた

463:デフォルトの名無しさん
08/08/20 01:01:39
>>460
ちょっとした計算を代わりにやってもらうのプログラムなんですが
計算過程を式としては理解しているのですが、
計算途中の値がどの程度の大きさになっているのは知りません
知らないうちにオーバーフローしてるんじゃないかと少し不安なんです
もちろん値が狂ったら答えも大抵はおかしくなるでしょうからそうそう困ることはないのですが

464:デフォルトの名無しさん
08/08/20 01:04:47
出た答えが正常かおかしいかは判断できるのか?
方程式の解とかで元の式に代入して検算とかできるのなら困らないけど

465:デフォルトの名無しさん
08/08/20 01:37:58
>>461 の修正版
int add(int a, int b, int *p_is_overflow){
int chk_type, result, is_overflow=0;

chk_type=(a<0)*2+(b<0);
result=a+b;
switch(chk_type){
case 0: if(result<0) is_overflow=1; break; // a, b ともに 0 以上なので解も 0 以上になるべき
case 3: if(result>=0) is_overflow=1; break; // a, b ともに 0 未満なので解も 0 未満になるべき
}
if(p_is_overflow) *p_is_overflow=is_overflow;

return result;
}

掛け算は a*b/b==a をチェックすればいい

整数同士の除算は一つの例外を除いてオーバーフローしない (0div はあるけど)

466:デフォルトの名無しさん
08/08/20 01:57:37
その例外は・・・?


467:デフォルトの名無しさん
08/08/20 02:00:18
ヒント・大抵正の最大値より負の最少値のほうが絶対値が大きい

468:デフォルトの名無しさん
08/08/20 02:02:27
>>466
読みたくば●を買え

C言語なら俺に聞け(入門篇) Part 12
スレリンク(tech板:951-952番)

469:デフォルトの名無しさん
08/08/20 02:04:57
951 名前:デフォルトの名無しさん[sage] 投稿日:2007/05/15(火) 14:28:25
これでダメな場合って lop==0 の時以外にあるかな?
result=lop*rop;
if(result/lop!=rop) オーバーフロー

952 名前:デフォルトの名無しさん[sage] 投稿日:2007/05/15(火) 14:54:12
>>951
っ lop=-1 rop=INT_MIN

470:402
08/08/20 09:34:26
>>440
ありがとうございます。
今作っている物は1秒ごとの判断で良かったので最終的にtime()関数を使うことにしました。
gettymeofday();も今度試してみます。

471:デフォルトの名無しさん
08/08/20 10:39:41
このプログラムなら正常に動くんですが、main関数内のnibai関数を
scanf("%d",&a);
nibai(a);
printf("二倍した数値は%d\n",a);
と書くと2倍してくれないんですが、何故でしょうか?
-----------------------------------------------------------
#include<stdio.h>
int nibai(int x);
int main(void){
int a;
printf("数値を入力してください:");
scanf("%d",&a);
printf("二倍した数値は%d\n",nibai(a));

return 0;}
int nibai(int x){
int wk;
wk=x*2;

return wk;}

472:デフォルトの名無しさん
08/08/20 10:59:39
a = nibai(a);

473:デフォルトの名無しさん
08/08/20 11:00:37
あーなるほど!!
ありがとうございます。

474:ym
08/08/20 13:43:00
受け渡された文字列が'0000'~'2359'の時刻範囲内かをチェックする
プログラムを教えてください。お願いします。
チェック内容は以下の通りです。
1. 受け渡された文字列が全て数値であること。
2. 受け渡された文字列の先頭2文字が'00'~'23'の範囲であること。
3. 受け渡された文字列の3文字目~4文字目が'00'~'59'の範囲であること。
正常終了時:return 0
異常終了時:return -1(時刻範囲外)


475:デフォルトの名無しさん
08/08/20 13:45:10
教えて欲しいのではなく宿題を丸投げしたいだけなら
宿題スレへ行ってください。


476:デフォルトの名無しさん
08/08/20 13:48:49
なんか最近範囲内チェックの質問多いな。全部同じやつか?

477:ym
08/08/20 13:57:04
char hh[3];
char mm[3];
int h;
int m;
hh[0]=pstime[0];
hh[1]=pstime[1];
hh[2]='\0';
mm[0]=pstime[2];
mm[1]=pstime[3];
mm[2]='\0';
h=atoi(hh);
m=atoi(mm);
if((h >= 0 && h <= 23)&& (m >= 0 && m <= 59)){
return RET_OK;
}else{
return RET_NG;
}
}
int main(void)
{
char str[256];
int chk;

gets(str);
chk = N60901D04(str);
printf("\nreturn=%d\n",chk);
}
受け渡された文字列が'0000'~'2359'の時刻範囲内かをチェックするプログラムなんですけど、コンパイルをしたら、
アルファベット4文字を入力してもreturn 0(正常)で判定されてしまったん
ですけど、プログラムの中のどこが悪かったのか、教えてください。お願いします。


478:デフォルトの名無しさん
08/08/20 13:59:57
たぶん、数字以外で数値に変更できなかったから0になって0時0分は有効だから、じゃない?
isdigit とかで先にチェックするとか。

479:デフォルトの名無しさん
08/08/20 14:00:28
>>474
int main(int argc, char *argv[])
{
  char *p;
  int n;

  for(p=argv[1] ; *p ; p++)
    switch(*p)
    {
      case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': break;
      default: return -1;
    }

  switch(argv[1][0])
  {
    case '0': case '1': break;
    case '2':
      switch(argv[1][1])
      {
        case '0': case '1': case '2': case '3': break;
      }
    default: return -1;
  }

  switch(argv[1][2])
  {
    case '0': case '1': case '2': case '3': case '4': case '5': break;
    default: return -1;
  }

  return 0;
}

480:デフォルトの名無しさん
08/08/20 14:01:42
>>477
atoiで変換は失敗すると0を返すからじゃね

481:デフォルトの名無しさん
08/08/20 14:02:11
あ、n消し忘れた

482:デフォルトの名無しさん
08/08/20 14:03:47
>>479
4桁目のチェックが抜けてないか?

483:デフォルトの名無しさん
08/08/20 14:05:20
>>482
必要あるか?

484:デフォルトの名無しさん
08/08/20 14:05:42
>>482
あーそうだね

  switch(argv[1][2])
  {
    case '0': case '1': case '2': case '3': case '4': case '5': if(argv[1][3]) break;
    default: return -1;
  }

こうか

485:デフォルトの名無しさん
08/08/20 14:07:05
>>483
ある
[3]が\0のときも無視して通してしまう

486:デフォルトの名無しさん
08/08/20 14:09:08
2桁目も

  switch(argv[1][0])
  {
    case '0': case '1': if(argv[1][1]) break;

だな

487:デフォルトの名無しさん
08/08/20 14:22:21
int check_time(const char *hhss)
{
    int i, hour, second;
    if (strlen(hhss) != 4) return -1;
    for (i = 0; i < 4; i++) if (!isdigit(hhss[i])) return -1;
   
    hour = (hhss[0] - '0') * 10 + (hhss[1] - '0');
    second = (hhss[2] - '0') * 10 + (hhss[3] - '0');
   
    return (0 <= hour && hour < 24 && 0 <= second && second < 60) ? 0 : -1;
}

488:デフォルトの名無しさん
08/08/20 14:29:42
教えてください

int型の2次元配列の先頭のポインターだけをもらってくる関数があります。
配列のサイズはわかっているんですが関数内で見る際にはどう記述すればいいでしょうか?

これを関数内でいじりたい
unsigned int hoge2div[100][200];

関数を呼ぶ前に連絡用構造体の所定のエリアに2次元配列のポインターを格納してます。
(unsigned int* )hoge->ptr = hoge2div;


関数内の定義(ここを直したい。)
unsigned int* 2div = (unsigned int* )2div->ptr;

489:デフォルトの名無しさん
08/08/20 14:30:40
>関数を呼ぶ前に連絡用構造体の所定のエリアに2次元配列のポインターを格納してます。
>(unsigned int* )hoge->ptr = hoge2div;
こっちが正解です
hoge->ptr = hoge2div;

490:デフォルトの名無しさん
08/08/20 14:36:52
unsigned int (*p)[DIV1_SIZE]=(unsigned int (*)[DIV1_SIZE])hoge->ptr;


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch