なぜ0は偽ですか?

この質問はばかげているように聞こえるかもしれませんが、0falseおよびtrueに対するその他の[integer]値は、ほとんどのプログラミング言語ですか?

文字列の比較

質問は少し単純すぎるので、もう少し説明します。まず、プログラマーには明らかなように見えるかもしれませんが、プログラミング言語がないのはなぜですか。実際にはあるかもしれませんが、使用した言語はありません。ここで0trueに評価され、他のすべての[integer]値はfalseに評価されますか?その1つのコメントランダムに見えるかもしれませんが、それが良い考えだったかもしれないいくつかの例があります。まず、文字列の3者間比較の例を見てみましょう。Cのstrcmp:最初の言語としてCを試しているプログラマーは、次のコードを書きたくなるかもしれません。

strcmp0を返すため文字列が等しい場合にfalseと評価されますが、最初のプログラマーがやろうとしたことは惨めに失敗し、彼は一般的に最初はその理由を理解していません。代わりに、0trueと評価されていた場合、この関数は、同等性を比較するときに、最も単純な式(上記の式)で使用できたはずです。また、-11の適切なチェックは、必要な場合にのみ実行されます。ほとんどの場合、戻り値の型をbool(私たちの考えでは)と見なしていました。

さらに、新しい型を紹介しましょう。sign、値-101。これは非常に便利です。C++に宇宙船演算子があり、std::string(まあ、すでにcompare関数がありますが、宇宙船演算子の方が楽しいです)。宣言は現在次のようになります:

 sign operator<=>(const std::string& lhs, const std::string& rhs);  

0true、宇宙船のオペレーターは存在すらしませんでした。そのようにoperator==を宣言することもできました:

 sign operator==(const std::string& lhs, const std::string& rhs);  

このoperator==は一度に3者間比較を処理し、必要に応じてどの文字列が他の文字列よりも辞書的に優れているかを確認しながら、次の確認を実行するために使用できます。

 if (str1 == str2) { // Do something... }  

古いエラー処理

例外が発生したため、この部分は、そのようなことがない古い言語にのみ適用されます。存在します(たとえばC)。 Cの標準ライブラリ(およびPOSIXライブラリも)を見ると、成功した場合はmaaaaany関数が0を返し、それ以外の場合は整数を返すことが確実にわかります。悲しいことに、何人かの人々を見てきました。このようなことを行います:

 #define TRUE 0 // ... if (some_function() == TRUE) { // Here, TRUE would mean success... // Do something }  

プログラミングでは、多くの場合、次の推論パターンがあります。

 Do something Did it work? Yes -> That"s ok, one case to handle No -> Why? Many cases to handle  

繰り返しになりますが、唯一の中立値0yesに配置することは理にかなっています(これがCの方法です)関数は機能します)、他のすべての値はnoの多くのケースを解決するために存在できます。ただし、私が知っているすべてのプログラミング言語(一部の実験的なエソセリック言語を除く)では、そのyesif条件でfalseと評価されます。すべてのnoケースはtrueと評価されます。 「機能する」が1つのケースを表し、「機能しない」が多くの考えられる原因を表す場合が多くあります。そのように考えると、0trueに評価し、残りをfalseもっと理にかなっているでしょう。

結論

私の結論は本質的に私の最初の質問です:なぜ0falseおよびその他の値はtrueです。上記のいくつかの例と、おそらく私が思いもよらなかったいくつかの例を考慮に入れていますか?

フォローアップ:多くのアイデアと考えられる理由を含む多くの回答があるのを見るのはうれしいです私はあなたがそれについてどれほど情熱的であるように見えるかが大好きです。私はもともと退屈でこの質問をしましたが、あなたはとても情熱的だと思われるので、もう少し進んで 0と1のブール選択の背後にある理論的根拠について質問することにしました on Math.SE 🙂

コメント

  • strcmp()はtrueまたはfalse、3つの異なる値を返すため。そして、シェルを使い始めると驚くでしょう。0は真を意味し、それ以外は偽を意味します。
  • @ ott-:Unixシェルでは、0は成功を意味します。 -ゼロは失敗を意味します-” true “および false “。
  • @KeithThompson:Bash(およびその他のシェル)では、”成功”と”失敗”は実際には true “および” false “。たとえば、ステートメントif true ; then ... ; fiについて考えてみます。ここで、trueはゼロを返すコマンドであり、これはifを実行するには...
  • ハードウェアにはブール値はなく、2進数のみであり、ほとんどの過去のISAではゼロ以外の数値と見なされます。すべての条件付き分岐命令で” true “として(’フラグを使用している場合を除く)代わりに)。したがって、低水準言語は、必ず基礎となるハードウェアのプロパティに従う必要があります。
  • @MasonWheelerブール型を使用しても’は何も意味しません。たとえば、pythonはboolタイプを持っていますが、比較/ if条件などは任意の戻り値を持つことができます。

回答

0は両方ともfalseです共通の半環の要素はゼロです。それらは別個のデータ型ですが、同型代数的構造に属しているため、それらの間で変換することは直感的に理解できます。

  • 0は加算の単位元と乗算のゼロ。これは整数と有理数に当てはまりますが、IEEE-754浮動小数点数ではありません:0.0 * NaN = NaNおよび0.0 * Infinity = NaN

  • falseは、ブール値 xor (⊻)のIDであり、ブール値の場合はゼロです。および(∧)。ブール値が{0、1}(2を法とする整数のセット)として表される場合、⊻はキャリーなしの加算、∧は乗算と考えることができます。

  • ""[]は連結のIDですが、ゼロとして意味のある操作がいくつかあります。繰り返しは1つですが、繰り返しと連結は分散されないため、これらの操作は半環を形成しません。

このような暗黙的な変換は、小さなプログラムでは役立ちますが、大きなプログラムでは役立ちます。プログラムの推論をより困難にする可能性があります。言語設計における多くのトレードオフの1つにすぎません。

コメント

  • リストについてお話しいただきありがとうございます。 (BTW、nilは、CommonLispの空のリスト[]falseの両方の値です。 ;異なるデータ型のIDをマージする傾向はありますか?)falseを加法IDと見なし、trueを乗法IDと見なすのが自然であり、その逆ではない理由を説明する必要があります。 ‘をtrueANDのIDと見なし、

  • +1は、同様のIDを参照します。最後に、’ “コンベンションに要約しない答えは、それに対処します”。
  • +1は、これが実行され、長い間意味をなしてきた具体的で非常に古い数学の詳細を提供します
  • この回答は’ tは意味があります。 trueは、半環(ブールおよび/または)のIDおよびゼロでもあります。 falsetrueよりも0に近いと考える理由はありません。
  • @TonioElGringo: trueとfalseの違いは、XORとXNORの違いです。 AND / XORを使用して同形環を形成できます。trueは乗法単位元でfalseは加法単位元、またはORとXNORを使用します。falseは乗法単位元でtrueは加法単位元ですが、XNORは通常一般的なものとは見なされません。 XORの基本的な操作。

回答

数学が機能するため。

FALSE OR TRUE is TRUE, because 0 | 1 is 1. ... insert many other examples here. 

従来、Cプログラムには次のような条件があります

 if (someFunctionReturningANumber())  

ではなく

 if (someFunctionReturningANumber() != 0)  

ゼロがfalseに相当するという概念はよく理解されているからです。

コメント

  • 数学が理にかなっているため、言語はそのように設計されています。それが最初に来ました。
  • @Morwenn、それは19世紀とGeorgeBooleにさかのぼります。人々は、コンピューターが存在するよりも長い間、Falseを0として、Trueを!0として表現してきました。
  • ‘数学がなぜ計算されないのかわかりません’ ANDが+、ORが*になるようにすべての定義を変更するだけでは、逆に機能しません。
  • 正確に言うと、数学は両方の方法で機能し、この質問は、それが純粋に従来型であるということのようです。
  • @Robert It ‘ “投稿の数学的な基盤”。

回答

他の人が言っているように、数学が最初に来ました。これが、0がfalseであり、1がtrueである理由です。

どの数学について話しているのですか? ブール代数は、デジタルコンピュータが登場するずっと前の、1800年代半ばにさかのぼります。

この規則は、ブール代数よりも古い命題論理から生まれたと言うこともできます。これは、プログラマーが知っていて愛している多くの論理結果の形式化です(false || xx、はxなどと同じです。

基本的には、2つの要素を持つセットの算術について話します。バイナリで数えることを考えてください。ブール代数は、この概念の起源であり、その理論的基盤です。Cのような言語の規則は、単純なアプリケーションです。

コメント

  • できます。 、確かに。ただし、”標準”の方法を維持すると、一般的な演算(0 + 1 = 1、0 +ではない)にうまく適合します。 1 = 0)。
  • はい。ただし、定義を逆にした場合は、おそらくANDを+で、ORを*で記述します。
  • 計算は’最初に来る。Mathは、0と1がフィールドを形成することを認識しました。このフィールドでは、ANDは乗算に似ており、ORは加算に似ています。
  • @ Kaz:しかし、ORとANDを使用した{0、1}はフィールドを形成しません。
  • true = 1という回答やコメントが増えるのは少し気になります。 ‘は正確ではありません。これは、true != 0がまったく同じではないためです。 if(something == true) { ... }のような比較を避ける必要がある理由の1つ(1つだけではありません)。

回答

これは、電子機器からの「継承」とブール代数に関係していると思いました。

  • 0 = offnegativenofalse
  • 1 = onpositiveyestrue

strcmp は、文字列が等しい場合に0を返します。これは、実際には2つの文字列間の「距離」を計算するためです。 0もたまたま偽と見なされるのは偶然です。

成功したときに0 を返すのは理にかなっていますこの場合の0は、エラーなしを意味するために使用され、その他の数値はエラーコードになるためです。成功コードは1つしかないため、成功のために他の番号を使用しても意味がありませんが、複数のエラーコードを使用できます。 「動作しましたか?」を使用します。 ifステートメント式で0 = yesと言う方が理にかなっていますが、式はより正確に「何か問題が発生しましたか?」です。そして、0 = noが非常に理にかなっていることがわかります。 false/trueについて考えることは、実際にはno error code/error codeであるため、ここではあまり意味がありません。

コメント

  • ハハ、あなたはリターンエラーの質問を明示的に述べた最初の人です。私はそれを自分のやり方で解釈し、他の方法で尋ねることもできることをすでに知っていましたが、’あなたが最初にそれを明示的に表現しました(多くの回答とコメントの中から)。実際、私は’どちらの方法も意味がないとは言いませんが、どちらも異なる方法で意味があります:)
  • 実際には’ d say 0 for success/no errorは、他の整数がエラーコードを表す場合に意味がある唯一のものです。 0falseを表す場合もありますが、それ以外の場合は’は重要ではありません。 ‘ここでは真か偽かについてはまったく話していません;)
  • 同じ考えを持っていたので、私はアップしました
  • あなたのポイントstrcmp()距離の計算は非常に優れています。 strdiff()と呼ばれていた場合、if (!strdiff())は非常に論理的です。
  • “エレクトロニクス[…]ここで0 = […] false、1 = […] true “-エレクトロニクスでも、これはコンベンションであり、’だけではありません。これを正論理と呼びますが、正の電圧が偽を示し、負の電圧が真を示す負の論理を使用することもできます。次に、’ ANDに使用する回路はORになり、ORはANDになります。 De Morgan ‘の法則により、すべてが同等になります。 ‘便宜上、負の論理で実装された電子回路の一部を見つけることがあります。その時点で、その部分の信号の名前がその上にバーで示されます。

回答

この記事で説明されているように 、値falseおよびtrueを整数0および1と混同しないでください。ただし、ガロア体の要素で識別できます。 (有限体)2つの要素(ここを参照)。

フィールドは、特定の公理を満たす2つの演算のセットです。

実数もフィールド(有限ではない)であり、その恒等式は0と1であるため、記号0と1は、フィールドの加法単位元と乗法単位元を表すために従来から使用されています。

加法単位元はフィールドの要素0であり、すべてのxについて:

x + 0 = 0 + x = x 

および加法単位元は体の要素1であり、すべてのxについて:

x * 1 = 1 * x = x 

2つの要素の有限体には、これら2つの要素、つまり加法単位元0(またはfalse)、および乗法単位元1(またはtrue)。このフィールドの2つの演算は、論理XOR(+)と論理AND(*)です。

注。演算を反転すると(XORは乗算、ANDは加算)、乗算は加算よりも分散的ではなく、フィールドはもうありません。このような場合、2つの要素を0と1(任意の順序)と呼ぶ理由はありません。 XORの代わりに演算ORを選択できないことにも注意してください。OR/ ANDを加算/乗算としてどのように解釈しても、結果の構造はフィールドではありません(フィールド公理で必要とされるすべての逆元が存在するわけではありません)。

C関数について:

  • 多くの関数は、エラーコードである整数を返します。 0はエラーがないことを意味します。
  • 直感的に、関数strcmpは2つの文字列の差を計算します。 0は、2つの文字列に違いがないこと、つまり2つの文字列が等しいことを意味します。

上記の直感的な説明は、戻り値の解釈を覚えておくのに役立ちますが、さらに簡単です。ライブラリのドキュメントを確認してください。

コメント

  • +1は、これらを任意に交換すると、計算が機能しなくなることを示しています。
  • 反転:2つの要素と演算*および+を持つフィールドが与えられると、Trueは0で、Falseは1で識別されます。ORは*で識別され、XORは+で識別されます。
  • 両方がこれらの識別は同じフィールドで行われ、どちらもブールロジックのルールと一致しています。残念ながら、メモは正しくありません:)
  • True = 0であり、XORが+であると仮定した場合、TrueはXORのIDである必要があります。しかし、それはTrue XOR True = Falseだからではありません。 Trueで操作XORを再定義して、True XOR True = Trueにならない限り。そしてもちろん、名前を変更したばかりなので、構築は機能します(どの数学的構造でも、いつでも名前の順列を作成して同型構造を取得できます)。一方、True、False、およびXORに通常の意味を持たせる場合、True XOR True = FalseおよびTrueを加法単位元にすることはできません。つまり、Trueを0にすることはできません。
  • @Giorgio:最後のコメントのコメントに従って構造を修正しました…

回答

代替システムも許容できる設計上の決定である可能性があることを考慮する必要があります。

シェル:0の終了ステータスはtrue、ゼロ以外はfalse

0を処理するシェルの例trueとしての終了ステータスはすでに言及されています。

 $ ( exit 0 ) && echo "0 is true" || echo "0 is false" 0 is true $ ( exit 1 ) && echo "1 is true" || echo "1 is false" 1 is false  

その理由は成功する方法は1つありますが、失敗する方法はたくさんあるため、「エラーなし」を意味する特別な値として0を使用するのが実用的です。

ルビー:0は他の数値と同じです

「通常の」プログラミング言語の中には、Rubyなど、0を真の値として扱ういくつかの異常値があります。

$ irb irb(main):001:0> 0 ? "0 is true" : "0 is false" => "0 is true" 

Rationalale は、falsenilのみがfalseである必要があるということです。多くのRuby初心者にとって、それは「落とし穴」です。ただし、場合によっては、0が他の数値と同じように扱われると便利です。

irb(main):002:0> (pos = "axe" =~ /x/) ? "Found x at position #{pos}" : "x not found" => "Found x at position 1" irb(main):003:0> (pos = "xyz" =~ /x/) ? "Found x at position #{pos}" : "x not found" => "Found x at position 0" irb(main):004:0> (pos = "abc" =~ /x/) ? "Found x at position #{pos}" : "x not found" => "x not found" 

ただし、 、このようなシステムは、ブール値を数値とは別の型として区別できる言語でのみ機能します。コンピューティングの初期の頃、アセンブリ言語や生の機械語を扱うプログラマーには、そのような贅沢はありませんでした。 0を「空白」状態として扱い、コードが何かが起こったことを検出したときにフラグとしてビットを1に設定するのはおそらく自然なことです。ひいては、ゼロは偽として扱われ、ゼロ以外の値は真として扱われるようになるという慣習が発展しました。ただし、そのようにする必要はありません。

Java:数値をブール値として扱うことはできません

Javaでは、truefalseのみがブール値です。数値はブール値ではなく、ブール値にキャストすることもできません( Java言語仕様、秒4.2.2 ):

整数型と型booleanの間にキャストはありません。 。

このルールは、質問を完全に回避します。すべてのブール式は、コードで明示的に記述する必要があります。

コメント

  • RebolとRed はどちらも、0値のINTEGER!値をtrueとして扱い、個別のNONE!タイプを持ちます。 (値が1つだけの場合、NONE)LOGIC!falseに加えて条件付きfalseとして扱われます。’ 0をfalseとして扱うJavaScriptコードを作成しようとすると、大きなフラストレーションが見つかりました。増分動的に型付けされた言語の食用に不格好な決定。 nullまたは0になる可能性のあるものをテストしたい場合は、if (thing === 0)と書く必要がありますが、それはクールではありません。
  • @HostileFork私は’わかりません。動的言語では、0が(他のすべての整数と同様に)trueであることは理にかなっています。 PythonでNoneをキャッチしようとしたときに、たまたま0をキャッチしましたが、それを見つけるのが非常に難しい場合があります。
  • ルビーは外れ値ではありません。 RubyはこれをLispから取得します(Rubyは密かに” MatzLisp “と呼ばれています)。 Lispはコンピュータサイエンスの主流言語です。 ‘はテキストの一部であるため、ゼロはPOSIXシェルの真の値でもあります:if [ 0 ] ; then echo this executes ; fi。 falseデータ値は空の文字列であり、テスト可能なfalsehoodはコマンドの終了ステータスの失敗であり、非ゼロで表されます。

回答

一般的なケースに対処する前に、反例について話し合うことができます。

文字列の比較

実際には、同じことが多くの種類の比較にも当てはまります。このような比較では、2つのオブジェクト間の距離が計算されます。オブジェクトが等しい場合、距離は最小になります。したがって、「比較が成功した」場合、値は0です。ただし、実際には、strcmpの戻り値はブール値ではなく、距離であり、 if (strcmp(...)) do_when_equal() else do_when_not_equal()を実行している認識していないプログラマーをトラップするもの。

C ++では、strcmpを再設計してDistanceオブジェクト。operator bool()をオーバーライドして、0の場合にtrueを返します(ただし、別の一連の問題に悩まされることになります)。または、プレーンCには、文字列が等しい場合は1を返し、そうでない場合は0を返すstreq関数があります。

API呼び出し/プログラム終了コード

ここでは、何かがうまくいかなかった理由を気にします。これは、エラーの決定を後押しするからです。物事が成功したとき、あなたは特に何も知りたくありません-あなたの意図は実現されます。したがって、戻り値はこの情報を伝えなければなりません。これはブール値ではなく、エラーコードです。 特別なエラー値0は、「エラーなし」を意味します。残りの範囲は、対処する必要のあるローカルで意味のあるエラーを表します(1を含む、多くの場合「不特定のエラー」を意味します)。

一般的なケース

これにより、ブール値がTrueおよびFalse一般的にそれぞれ1と0で表されますか?

主観的な「この方法で気分が良くなる」という議論に加えて、私が考えることができるいくつかの理由(主観的なものも)があります:

  • 電気回路のアナロジー。電流は1秒間オン、0秒間オフになります。別の組み合わせではなく、(1、Yes、True、On)と(0、No、False、Off)を一緒にするのが好きです

  • メモリの初期化。一連の変数(int、float、boolなど)をmemset(0)するときは、それらの値を最も保守的な仮定に一致させたいと思います。例えば。私の合計は最初は0、述語はFalseなどです。

おそらく、これらすべての理由は私の教育に関係しています-もし私が0をTrueに関連付けるように教えられていたら最初は、逆の方向に進みます。

コメント

  • 実際には、0を真として扱うプログラミング言語が少なくとも1つあります。 UNIXシェル。
  • 実際の問題に対処するための+1:Morwenn ‘の質問のほとんどは’ tではありません。 boolについてです。
  • @ dan04そうです。投稿全体は、多くのプログラミング言語でintからboolへのキャストを選択した理由に関するものです。比較とエラージェスチャに関するものは、現在行われている’とは別の方法でキャストすることが理にかなっている場所の例にすぎません。

回答

高レベルの観点から、あなたは3つのまったく異なるデータ型について話している:

  1. ブール。ブール代数の数学的規則では、falseに0を使用し、

なので、その規則に従うのは理にかなっています。この方法も直感的に理にかなっていると思います。

  • 比較の結果。 3つの値:<=>(いずれも

    )。それらの場合、それぞれ-1、0、1の値(または、より一般的には、負の値、0、正の値)を使用するのが理にかなっています。

    同等性をチェックしたい場合a一般的な比較を実行する関数しかない場合は、strcmp(str1, str2) == 0のようなものを使用して明示的にする必要があると思います。この状況で!を使用すると、非ブール値がブール値であるかのように扱われるため、混乱を招きます。

    また、比較と平等は同じである必要はありません。たとえば、生年月日で注文した場合、Compare(me, myTwin)0を返す必要があります。 、ただし、Equals(me, myTwin)falseを返す必要があります。

  • 関数の成功または失敗、おそらくその成功または失敗の詳細も含まれます。Windowsについて話している場合、このタイプは HRESULT およびゼロ以外の値は、必ずしも失敗を示すわけではありません。実際、負の値は、失敗および非負の成功を示します。成功値は、多くの場合S_OK = 0ですが、たとえばS_FALSE = 1やその他の値にすることもできます。

  • 混乱は事実に起因しますその3つは論理的にまったく異なるデータ型は、実際にはCおよびその他のいくつかの言語では単一のデータ型(整数)として表され、条件で整数を使用できます。しかし、条件でいくつかの非ブール型を使用するようにブール値を再定義することは意味がないと思います。

    また、Cの条件でよく使用される別の型を検討してください:ポインター。そこでは、NULLポインタ(0として表される)をfalse。したがって、提案に従うと、ポインターの操作も難しくなります(ただし、個人的には、ポインターをブール値として扱うのではなく、明示的にNULLと比較することをお勧めします)。

    回答

    ほとんどのCPUには分岐に使用できるゼロフラグがあるため、ゼロはfalseになる可能性があります。比較操作を節約できます。

    理由を見てみましょう。

    オーディエンスはおそらくアセンブリを読まないため、一部の擬似コード

    c-ソースの単純なループがwibbleを10回呼び出す

     for (int foo =10; foo>0; foo-- ) /* down count loop is shorter */ { wibble(); }  

    そのためのいくつかのふりアセンブリ

    0x1000 ld a 0x0a "foo=10 0x1002 call 0x1234 "call wibble() 0x1005 dec a "foo-- 0x1006 jrnz -0x06 "jump back to 0x1000 if not zero 0x1008 

    c-別の単純なソースループはwibbleを10回呼び出します

     for (int foo =0; foo<10; foo-- ) /* up count loop is longer */ { wibble(); }  

    この場合のアセンブリのふりをします

    0x1000 ld a 0x00 "foo=0 0x1002 call 0x1234 "call wibble() 0x1005 dec a "foo-- 0x1006 cmp 0x0a "compare foo to 10 ( like a subtract but we throw the result away) 0x1008 jrns -0x08 "jump back to 0x1000 if compare was negative 0x100a 

    もう少しcソース

     int foo=10; if ( foo ) wibble()  

    およびアセンブリ

    0x1000 ld a 0x10 0x1002 jz 0x3 0x1004 call 0x1234 0x1007 

    それがどれだけ短いかを確認しますか?

    もう少しcソース

     int foo=10; if ( foo==0 ) wibble()  

    およびアセンブリ(比較なしで== 0を置き換えることができるわずかにスマートなコンパイラを想定します) )

    0x1000 ld a 0x10 0x1002 jz 0x3 0x1004 call 0x1234 0x1007 

    ここで、true = 1の規則を試してみましょう

    もう少しcsource #define TRUE 1 int foo = TRUE; if (foo == TRUE) wibble()

    およびアセンブリ

    0x1000 ld a 0x1 0x1002 cmp a 0x01 0x1004 jz 0x3 0x1006 call 0x1234 0x1009 

    true以外の場合がどれだけ短いかを確認しますか?

    本当に初期のCPUには、アキュムレータに小さなフラグのセットが付加されていました。

    a> bまたはa = bが一般に比較命令を受け取るかどうかを確認するには、

    • Bがそうでない場合ZERO-この場合、ZEROフラグが設定されます。単純な論理NORまたはアキュムレータのすべてのビットとして実装されます。
    • または「符号ビット」、つまりアキュムレータの最上位ビットのみを使用するNEGATIVE 2の補数演算を使用している場合。 (ほとんどの場合、そうします)

    これを言い換えましょう。一部の古いCPUでは、ゼロに等しいアキュムレータ、またはゼロ未満のアキュムレータに対して比較命令を使用する必要はありませんでした。

    ここで、ゼロが偽である理由がわかりますか?

    これは擬似コードであり、実際の命令セットはこのようには見えないことに注意してください。アセンブリを知っている場合は、ここで非常に単純化しています。コンパイラの設計について何か知っているなら、この答えを読む必要はありませんでした。ループ展開や分岐予測について何でも知っている人なら、上級クラスは203号室の廊下にいます。

    コメント

    • if (foo)if (foo != 0)は同じコードを生成する必要があります。次に、’は、’使用しているアセンブリ言語が実際に明示的であることを示しています。ブールオペランドとそれらのテスト。たとえば、jzjump if zeroを意味します。つまり、if (a == 0) goto target; 。そして、数量は直接テストされていません。条件は、特別なマシンワードに格納されているブールフラグに変換されます。’は実際には
    • いいえ、古いCPU ‘はそのようには機能しませんでした。T jz / jnzは、比較命令を実行せずに実行できます。これが私の投稿全体のポイントでした。
    • 比較手順については何も書きませんでした。
    • ‘比較手順については何も書きませんでした。
    • jz命令はあるが、jnzがないプロセッサを引用しますか? (またはその他の非対称の条件付き命令のセット)

    回答

    それを示唆する回答はたくさんあります1とtrueの間の対応は、いくつかの数学的特性によって必要になります。そのようなプロパティを見つけることができず、純粋に歴史的な慣習であることを示唆しています。

    2つの要素を持つフィールドがある場合、加算と乗算の2つの演算があります。このフィールドにブール演算を2つの方法でマッピングできます。 :

    従来、Trueは1で、Falseは0で識別されます。ANDは*で、XORは+で識別されます。したがって、ORは加算を飽和させます。

    ただし、同じように簡単にできます。 Trueを0で識別し、Falseを1で識別します。次に、ORを*で識別し、XNORを+で識別します。したがって、ANDは加算を飽和させます。

    コメント

    • Ifウィキペディアのリンクをたどっていれば、ブール代数の概念が2つの要素のガロア体の概念に関連して閉じていることがわかりました( en.wikipedia.org/wiki / GF%282%29 )。実際の数値は、IDが0と1のフィールドでもあるため、記号0と1は、それぞれ加法と乗法のIDを表すために従来から使用されています。
    • @NeilGジョルジオはそれを単なる慣習以上のもの’と言おうとしていると思います。ブール代数の0と1は、基本的にGF(2)の0と1と同じであり、加算と乗算に関して実数の0と1とほぼ同じように動作します。
    • @svick:いいえ、単純に乗算と飽和加算の名前をORとANDに変更してから、0がTrue、1がFalseになるようにラベルを反転できるためです。ジョルジオは、それはコンピュータサイエンスの慣習として採用されたブール論理の慣習であると言っています。
    • @Neil G:いいえ、フィールドには分配性が必要なため、+と*および0と1を反転することはできません。加算よりも乗算の数( en.wikipedia.org/wiki/Field_%28mathematics%29 を参照)。ただし、+:= ANDおよび*:= XORを設定した場合、T XOR(T AND F)= T XOR F = Tを取得しますが、(T XOR T)AND(T XOR F)= F AND T = Fです。したがって、演算とIDを反転すると、フィールドがなくなります。もう。したがって、0と1を適切なフィールドのIDとして定義するIMOは、偽と真をかなり忠実に捉えているようです。
    • @giorgio:何が起こっているのかを明確にするために、回答を編集しました。

    回答

    不思議なことに、ゼロが常に偽であるとは限りません。

    特に、UnixとPosixの規則EXIT_SUCCESSを0として定義します(EXIT_FAILUREを1として定義します)。実際には、標準の C規則です!

    Posixシェルと出口の場合(2) syscalls、0は「成功」を意味し、これは直感的に偽よりも真です。

    特に、シェルのifはprocess return EXIT_SUCCESS(つまり、0)は、その「then」ブランチに従います!

    スキーム内(ただし、CommonLispまたは MELT )0とnil(つまり、Schemeの())はtrueです。これは、false値が#f

    同意します、私はつまらないです!

    回答

    Cは、同じデータでビット単位の演算と論理演算を切り替える必要がある領域であるハードウェアに近い低水準プログラミングに使用されます。テストを実行するためだけに数値式をブール値に変換する必要があると、混乱します。コード。

    次のように書くことができます:

     if (modemctrl & MCTRL_CD) { /* carrier detect is on */ }  

    ではなく

     if ((modemctrl & MCTRL_CD) != 0) { /* carrier detect is on */ }  

    1つの孤立した例では、それほど悪くはありませんが、そうしなければならないのは面倒です。

    同様に、逆の操作です。比較などのブール演算の結果に、0または1を生成するだけで便利です。modemctrlかどうかに基づいて、ある単語の3番目のビットを設定するとします。キャリア検出ビットがあります:

     flags |= ((modemctrl & MCTRL_CD) != 0) << 2;  

    ここに

    、バイワイズ&式の結果を0またはただし、結果は単なる整数であるため、ブール値をさらに整数に変換するために煩わしいキャストを追加する必要はありません。

    最新のCには

    タイプでも、このようなコードの有効性は維持されます。これは、「良いことであり、そうでない場合に発生する後方互換性を伴う大規模な破損のためです。

    Cが滑らかな別の例:2つのブール条件を4方向スイッチとしてテストする:

    これをCプログラマーから奪うことはできません!

    最後に、Cは時々サービスを提供します一種の高レベルのアセンブリ言語として。アセンブリ言語では、ブール型もありません。ブール値は、メモリ位置またはレジスタ内のビットまたはゼロ対ゼロ以外の値です。整数ゼロ、ブールゼロ、およびアドレスゼロはすべて、アセンブリ言語の命令セット(およびおそらく浮動小数点ゼロ)で同じ方法でテストされます。 Cとアセンブリ言語の類似性は、たとえば、Cが別の言語(ブール値を強く型付けした言語でも!)をコンパイルするためのターゲット言語として使用される場合に役立ちます。

    回答

    ブール値または真理値には2つの値しかありません。正誤問題。

    これらは ではなく、整数として表現する必要がありますが、ビット(0および1 。

    0または1以外の整数が偽ではないと言うのは、紛らわしいステートメントです。真理値は整数ではなく真理値を扱います。

    真理値の見通しから、-1または2は、すべての真理値とそれに関連付けられたブール論理を壊します。

    • 0 AND -1 == ?!
    • 0 OR 2 == ?!

    ほとんどの言語には通常、booleanがあります。整数などの数値タイプにキャストすると、falseが0の整数値としてキャストされることが明らかになるタイプ。

    コメント

    • 0 AND -1 ==キャスト先のブール値。 ‘が私の質問です。なぜ、それらをTRUEまたはFALSEにキャストするのですか。私は決して言いませんでした-多分私はそうしましたが、それは意図されていませんでした-整数が真か偽か、ブール値にキャストされたときにどちらに評価されるのかについて尋ねました。

    回答

    最終的には、一部のAPIが壊れているため、コア言語を壊すことについて話していることになります。 Crappy APIは新しいものではなく、言語を壊して修正することはできません。0が偽で1が真であるというのは数学的な事実であり、これを尊重しない言語は根本的に壊れています。3者間比較は次のとおりです。ニッチであり、その結果が3つの可能な結果を返すため、暗黙的にboolに変換されるビジネスはありません。古いCAPIは単にひどいエラー処理を備えており、ひどいインターフェースを持たないために必要な言語機能がCにないため、問題もあります。

    暗黙的でない言語については言っていないことに注意してください。整数->ブール変換。

    コメント

    • ” 0が偽であるのは数学的な事実です。 1は真です”えーと
    • ” 0が偽であるという数学的な事実の参照を引用できますかそして1は本当です”?あなたの答えは危険なほど暴言のように聞こえます。
    • ‘は数学的な事実ではありませんが、’ 19世紀以来の数学的慣習。
    • ブール代数は有限体で表され、0と1は加算と乗算に似た演算の単位元です。これらの操作は、それぞれORとANDです。実際、ブール代数は、並置がANDを示し、+記号がORを示す通常の代数とほとんど同じように記述されます。たとえば、abc + a'b'c(a and b and c) or (a and (not b) and (not c))を意味します。

    コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です