[過去ログ] C言語なら俺に聞け 163 (1002レス)
上下前次1-新
このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
361: (ワッチョイ bf5f-FO3g) 2024/11/24(日)20:47 ID:Hl1pEu0p0(1/3) AAS
>> 358
試していただきありがとうございます.
FreeBSD clang version 18.1.6 (外部リンク[git]:github.com llvmorg-18.1.6-0-g1118c2e05e67)
Target: x86_64-unknown-freebsd14.1
と,gccは共に jの値がおかしいのです.
試しに,
unsigned long j = 1 << 31;
を
unsigned int j = 1 << 31;
にすると同じ値になる.
これはコンパイラのBUGかなぁ.
362: 警備員[Lv.1][新芽] (ワッチョイ 9fe5-fjqo) 2024/11/24(日)22:17 ID:/KMFo2rr0(1/3) AAS
よく分からないけど
unsigned long i = 1 << 31;
unsigned long j = 1 << 31;
を
unsigned long i = 1L << 31;
unsigned long j = 1L << 31;
とするとうまくいく? clang
どちらでも同じ結果になりそうだけど
見当違いだったらごめんなさい
363: 警備員[Lv.1][新芽] (ワッチョイ 9fe5-fjqo) 2024/11/24(日)22:25 ID:/KMFo2rr0(2/3) AAS
gcc -S
でアセンブラ出してみてみたけど、
いや、アセンブラよくわからないんだけど、
修正前の iと jは初期化時にいずれも符号拡張されて大きな値になっていて
その後なぜか iの方は下32ビットで、jの方は64ビットで計算されているようで、正しいのはむしろ jのように見えたがごめんなさい
本当にアセンブラ分からないので多分間違ってます…
364: (ワッチョイ 9f61-vAaR) 2024/11/24(日)22:26 ID:zY64cYUd0(1) AAS
gcc, clang
sizeof(int) == 32
sizeof(unsigned long) == 64
での出力
18446744071562067968,18446744071562067968,18446744071562067968
1073741824,9223372035781033984,1073741824
536870912,4611686017890516992,536870912
省略
8,68719476728,8
4,34359738364,4
2,17179869182,2
1,8589934591,1
これはこれで正しいと思うが
365: 警備員[Lv.2][新芽] (ワッチョイ 9fe5-fjqo) 2024/11/24(日)22:45 ID:/KMFo2rr0(3/3) AAS
あ、iは unsigned (int)でキャストしてるのか
366: (ワッチョイ bf5f-FO3g) 2024/11/24(日)23:09 ID:Hl1pEu0p0(2/3) AAS
わかりやすく,intのものとcastかけたのにしてみました.
これだとやはり,pの値だけ変でした.
元々は,binaryで数を8bit 16bit 32bitで表示する関数が,8,16が普通で32だけ変なので気がついたのでした.なんでintだと符合拡張されなくてlongだとされるかが謎.
#include <stdio.h>
int main() {
int s=31;
unsigned long i = 1 << 31;
unsigned int j = 1 << 31;
unsigned long p = 1 << 31;
unsigned long k;
while(i) {
k = 1 << s;
printf("%lu,%u,%lu,%lu¥n",i,j,k,p);
i = (unsigned)i>>1;
j >>= 1;
p >>= 1;
s--;
}
return 0;
}
367(1): (ワッチョイ bf5f-FO3g) 2024/11/24(日)23:16 ID:Hl1pEu0p0(3/3) AAS
unsigned long p = 1 << 31;
を
unsigned long p = 1L << 31;
にしたら同じ値になりました.
ううむ,なぜ
unsigned int j = 1 << 31;
だとうまくいって,longだと1Lにしないとうまくいかんのだ.
368: 警備員[Lv.4][新芽] (ワッチョイ b72e-fjqo) 2024/11/24(日)23:36 ID:BVpPJ8iH0(1/3) AAS
右辺が 1<<31だと
左辺が intだと0x80000000がそのまま、
longだと 0xffffffff80000000に拡張されて転記されるからでは
369: 警備員[Lv.4][新芽] (ワッチョイ b72e-fjqo) 2024/11/24(日)23:49 ID:BVpPJ8iH0(2/3) AAS
unsigned long i = (unsigned long) 1 << 31;
とすれば iは 0x80000000になるかと
370: 警備員[Lv.4][新芽] (ワッチョイ b72e-fjqo) 2024/11/24(日)23:50 ID:BVpPJ8iH0(3/3) AAS
1lとするのと同じだけど
371: はちみつ餃子◆8X2XSCHEME (ワッチョイ f732-hCSs) 2024/11/25(月)02:42 ID:EAdMpn4b0(1/2) AAS
>>367
言語仕様的に解釈すると……
シフト演算子の結果の型は左オペランドを整数拡張した後の型と同じになる。
整数リテラルは int の範囲で表せる限り int なので 1 は int 。
int は整数拡張の必要がないので 1<<31 の結果の型も int 。
そして結果の型が signed かつ結果の値が結果の型で表現可能な範囲にないときの動作は未定義なので
2147483648 が int (おそらく質問者の環境では 32 ビット) の最大値である 2147483647 を越えていて未定義の挙動となる。
不定とか処理系定義ではなく未定義と明記されてる。
つまり言語仕様上は何が起きても良いということ。
372(1): (ワッチョイ ffd6-G09H) 2024/11/25(月)07:22 ID:NtppUMW10(1/2) AAS
6.3.1.3のこれじゃないの
Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or
subtracting one more than the maximum value that can be represented in the new type
until the value is in the range of the new type.
373(1): (ワッチョイ bf5f-FO3g) 2024/11/25(月)08:27 ID:qsrJNZhH0(1) AAS
6.3.1.3
符号付き整数型及び符号無し整数型 整数型の値を̲Bool型以外の他の整数型に変換する場合,
その値が新しい型で表現可能なとき,値は変化しない。
新しい型で表現できない場合,新しい型が符号無し整数型であれば,新しい型で表現しうる最大の数に
1加えた数を加えること又は減じることを,新しい型の範囲に入るまで繰り返すことによって得られる値
に変換する(49)。
なるほど,1がintで<<31すると負の最大値となって,unsignedとして表せないからか.
皆様,ありがとうございました.
374: はちみつ餃子◆8X2XSCHEME (ワッチョイ f732-hCSs) 2024/11/25(月)09:22 ID:EAdMpn4b0(2/2) AAS
>>372-373
いいえ。
シフト演算の段階で既に未定義を踏んでいるので型変換は関係ないです。
6.5.7 をご覧ください。
375: (ワッチョイ 9fc2-ZGYG) 2024/11/25(月)09:32 ID:SsaYg1Am0(1) AAS
科学 + ンニュース 5ch
保守派もリベラル派も「自分の政治的信念に合致したニュース」を信じやすいという研究結果 [すらいむ★]
2chスレ:scienceplus
コメントも含めて読むと
陰謀論が収まら無い理由が判明する
376: (ワッチョイ ffd6-G09H) 2024/11/25(月)09:46 ID:NtppUMW10(2/2) AAS
なるほど、32bitのみでやるときも1u<<31にしないといけないのか
377: (ササクッテロ Spcb-8bf6) 2024/11/25(月)10:29 ID:G+C3M6QHp(1) AAS
なぜ浮動小数型をシフトしようとした?
378: (ワッチョイ bfdf-FO3g) 2024/11/25(月)13:39 ID:YjGMGS1I0(1) AAS
>> 374 なるほど,そっちで既に未定義だったか.
6.5.7
ビット単位のシフト演算子
構文規則
シフト式:
加減式
シフト式 << 加減式
シフト式 >> 加減式
制約 各オペランドは,整数型をもたなければならない。
意味規則 整数拡張を各オペランドに適用する。結果の型は,左オペランドを拡張した後の型とする。右オペランドの値が負であるか,又は拡張した左オペランドの幅以上の場合,その動作は,未定義とする。
E1<<E2の結果は,E1をE2ビット分左にシフトした値とする。空いたビットには0を詰める。E1が符号無し整数型をもつ場合,結果の値は,E1×2E2の,結果の型で表現可能な最大値より1大きい値を法と
する剰余とする。E1が符号付き整数型と非負の値をもち,E1×2E2が結果の型で表現可能である場合,それが結果の値となる。それ以外の場合,その動作は未定義とする。
E1>>E2の結果は,E1をE2ビット分右にシフトした値とする。E1が符号無し整数型をもつ場合,又はE1が符号付き整数型と非負の値をもつ場合,結果の値は,E1/2E2の商の整数部分とする。E1が符号付き整数型と負の値をもつ場合,結果の値は処理系定義とする。
379: (JP 0Hdf-6m00) 2024/11/26(火)22:12 ID:JxXv+doZH(1) AAS
VS CodeでEchoAPIを使うと、ツールを切り替えずにAPIテストをシームレスに管理できるようになったよ!
380: (ワッチョイ d761-7ouQ) 2024/11/29(金)15:48 ID:QX01Nly20(1) AAS
以下のサンプルプログラムが理解できず困っています。
該当プログラムは、コマンドラインから読み込んだBMPの色データを矩形として並べていくというものの一部を抜粋しています。
以下のfor文は
カラーテーブルの数を取得する→
ブラシを設定する→
先頭の構造体メンバからiCount先の構造体メンバを指定→
iCountにインクリメント
という流れだと考えられると思うのですが、1に対し1カラービット分左シフトとなっている部分がどういったロジックによって数の取得が実現されているのかわかりません。
質問は2点あり、どのようにしてテーブル数を取得しているのか、コードの理解は正しいのかについてお答えしていただければと思います。
サンプルコード
#include <windows.h>
BITMAPFILEHEADER bmpFileHeader;
BITMAPCOREHEADER bmpCoreHeader;
RGBTRIPLE *prtColor;
for ( ; iCount < (1 << bmpCoreHeader.bcBitCount) ; iCount++) {
SelectObject(hdc , CreateSolidBrush(
RGB( (prtColor + iCount)->rgbtRed ,
(prtColor + iCount)->rgbtGreen ,
(prtColor + iCount)->rgbtBlue
))
381(1): (スプッッ Sd3f-G09H) 2024/11/29(金)16:12 ID:YWo8X0edd(1) AAS
bcBitCountはピクセルあたりビット数で1,4,8,24だそう
nビットで表せる値は2^n通りで、これは左シフト1<<nで計算できる
382(1): (ワッチョイ ff76-J7R8) 2024/11/29(金)23:08 ID:5pZynS2U0(1) AAS
# 質問されていない部分だけど…
iCountと比較する値はループ内で変動しないよね?
だったら毎回計算せずにループ前で計算して別変数に記憶しておくほうがよくないかい?
383: (ワッチョイ ffd6-G09H) 2024/11/30(土)00:28 ID:b6kb1MmL0(1) AAS
今時のコンパイラは十分賢いので気にすることない
384: (ワッチョイ ff63-cdGy) 2024/11/30(土)00:37 ID:VtvuoLT+0(1/5) AAS
ユーザーの犯したバグも直してくれるとありがたいなあ
385(1): (ワッチョイ ff76-J7R8) 2024/11/30(土)00:47 ID:k7UOR52k0(1/8) AAS
シフトでも掛算でもどっちでもいいけど
質問者のように読んで悩むのは問題
コメント書いておけ
ループ内毎回計算か最適化でループ外に出したかは
コンパイル後の逆アセンブルとかで確認するの?
だったら間違いないようにループ外に出す方が良い癖にもなると思うのだが
386(1): (ワッチョイ bf79-q0Tp) 2024/11/30(土)09:43 ID:54hbVEvk0(1/5) AAS
380の知能では最適化したつもりが新たなバグを埋め込む事になるかもしれん
自身の身の丈に合ったコードにしとけ
未来の自分が賢くなってる事を信じて
387(1): (アウアウエー Sadf-wjfe) 2024/11/30(土)09:49 ID:l0dFcapba(1) AAS
#include <windows.h>
BITMAPFILEHEADER bmpFileHeader;
BITMAPCOREHEADER bmpCoreHeader;
RGBTRIPLE *prtColor;
↑
この間に何も描かれてないのは投稿者が勝手に削除したの?元から無いの?
↓
for ( ; iCount < (1 << bmpCoreHeader.bcBitCount) ; iCount++) {
SelectObject(hdc , CreateSolidBrush(
RGB( (prtColor + iCount)->rgbtRed ,
(prtColor + iCount)->rgbtGreen ,
(prtColor + iCount)->rgbtBlue
))
388: (ワッチョイ ff76-J7R8) 2024/11/30(土)11:23 ID:k7UOR52k0(2/8) AAS
なんでこんなに読めないのか理由がわかった
変数名や字下げや「,」前のブランクなど
論理そのもの以前にコーディングの美しさが全然無い
389: (ワッチョイ ff63-cdGy) 2024/11/30(土)11:53 ID:VtvuoLT+0(2/5) AAS
この掲示板書き込むと、スペースやタブは消されちゃうんだよな。
だから綺麗に整形した状態でソース載せたいなら、
全角スペース使うしかない。
あるいはソース公開出来るサイトにアップロードして、
そのリンクを張るなりする。
そういうサイトは、>>1 に書いてある。
390: (ワッチョイ bfd9-6oxW) 2024/11/30(土)12:18 ID:tlb45efI0(1) AAS
美しさとか言い出したら自転車置き場の議論なるからやめとけ
上下前次1-新書関写板覧索設栞歴
あと 612 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ
ぬこの手 ぬこTOP 0.027s