0이 거짓 인 이유는 무엇입니까?

이 질문은 어리석게 들릴 수 있지만 0falsetrue에 대한 다른 [integer] 값이 대부분의 프로그래밍 언어입니까?

문자열 비교

질문이 너무 간단합니다. 조금 더 설명하겠습니다. 우선 어떤 프로그래머에게도 분명해 보일 수 있지만 왜 “프로그래밍 언어가 없을까요?-실제로는있을 수 있지만 제가 사용한 것은 없을 수 있습니다.-여기서 0true로 평가되고 다른 모든 [integer] 값은 false로 평가됩니까? 무작위로 보일 수 있지만 좋은 생각 일 수있는 몇 가지 예가 있습니다. 우선 문자열 3 방향 비교의 예를 들어 보겠습니다. C “의 strcmp 예 : C를 모국어로 사용하는 프로그래머라면 누구나 다음 코드를 작성하고 싶을 수 있습니다.

strcmp0를 반환하므로 문자열이 같을 때 false로 평가됩니다. 초보 프로그래머가 시도한 작업은 비참하게 실패하고 일반적으로 처음에는 그 이유를 이해하지 못합니다. 대신 0true로 평가 되었으면이 함수는 동일성을 비교할 때 가장 간단한 표현식 (위의 표현식)으로 사용될 수 있습니다. -11에 대한 적절한 검사는 필요할 때만 수행되었을 것입니다. 대부분의 경우 반환 유형을 bool (내 말은)로 간주했을 것입니다.

게다가 새로운 유형을 소개하겠습니다. sign, -1, 01. 매우 편리 할 수 있습니다. 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로 평가됩니다. “작동 함”이 하나의 경우를 나타내는 반면 “작동하지 않음”이 많은 가능한 원인을 나타내는 경우가 많습니다. 그렇게 생각하면 0true로 평가되고 나머지는 false이 (가) 훨씬 더 합리적이었을 것입니다.

결론

내 결론은 본질적으로 저의 원래 질문입니다. 0false 및 기타 값은 true입니다. 위의 몇 가지 예와 내가 생각하지 못한 몇 가지 예를 고려하면됩니다.

후속 조치 : 많은 아이디어와 가능한 많은 이유가있는 많은 답변이 있다는 것을 알게되어 기쁩니다. 당신이 그것에 대해 얼마나 열정적인지 사랑합니다.원래는 지루함에서이 질문을했지만, 당신이 너무 열정적이기 때문에 조금 더 나아가서 0과 1에 대한 부울 선택의 근거

를 묻기로했습니다. a> on Math.SE 🙂

댓글

  • strcmp()는 true 또는 false, 3 개의 다른 값을 반환합니다. 그리고 0은 참을 의미하고 다른 것은 거짓을 의미하는 쉘 사용을 시작하면 놀랄 것입니다.
  • @ ott– : 유닉스 쉘에서 0은 성공 을 의미하고 -zero는 실패 를 의미하며 ” true ” 및 false “.
  • @KeithThompson : Bash (및 기타 셸)에서 ” 성공 ” 및 ” 실패 “는 실제로 true ” 및 ” false “. 예를 들어 if true ; then ... ; fi 문을 생각해보십시오. 여기서 true는 0을 반환하는 명령이며 if to run ....
  • 하드웨어에는 부울이없고 이진수 만 있으며 대부분의 이전 ISA에서는 0이 아닌 숫자로 간주됩니다. 모든 조건부 분기 명령에서 ” true “로 (플래그를 사용하지 않는 한 ‘ 대신). 따라서 하위 수준 언어는 반드시 기본 하드웨어 속성을 따라야합니다.
  • @MasonWheeler 부울 유형을 갖는 것은 ‘ 아무 것도 의미하지 않습니다. 예를 들어 python은 bool 유형이 있습니다 하지만 비교 / if 조건 등은 모든 반환 값을 가질 수 있습니다.

답변

0는 둘 다이므로 false입니다. 공통 세미나 에는 요소가 없습니다. 서로 다른 데이터 유형이지만 동형 대수 구조에 속하기 때문에 변환하는 것이 직관적입니다.

  • 0는 덧셈의 신원, 곱셈의 경우 0. 이는 정수 및 합리적 경우에 해당되지만 IEEE-754 부동 소수점 숫자는 아닙니다 : 0.0 * NaN = NaN0.0 * Infinity = NaN .

  • false는 Boolean xor (⊻)의 ID이고 Boolean 의 경우 0입니다. 그리고 (∧). 부울이 {0, 1} (모듈로 2의 정수 집합)으로 표시되면 ⊻는 캐리가없는 더하기로, ∧는 곱하기로 생각할 수 있습니다.

  • ""[]는 연결을위한 ID이지만 0으로 이해되는 몇 가지 작업이 있습니다. 반복은 하나이지만 반복과 연결은 분배되지 않으므로 이러한 연산은 반원형을 형성하지 않습니다.

이러한 암시 적 변환은 작은 프로그램에서는 유용하지만 큰 경우에는 프로그램을 추론하기 더 어렵게 만들 수 있습니다. 언어 디자인의 많은 장단점 중 하나 일뿐입니다.

댓글

  • 목록에 대해 언급 한 것이 좋습니다. (BTW, nil는 Common Lisp의 빈 목록 []false 값입니다. ; 다른 데이터 유형의 신원을 병합하는 경향이 있습니까?) 거짓을 추가 신원으로 간주하고 참을 곱셈 신원으로 간주하는 것이 자연스러운 이유를 설명해야합니다. ‘ trueAND의 ID로 간주하�

    ?

  • 유사한 ID를 나타내는 +1. 마지막으로 ‘ ” 컨벤션으로 요약되는 것이 아니라 “.
  • 이 방식을 따르고 오랫동안 이해해 온 구체적이고 매우 오래된 수학에 대한 세부 정보를 제공하는 +1
  • 이 답변은 ‘ 말이 안됩니다. true는 세미 링 (부울 및 / 또는)의 ID 및 0이기도합니다. falsetrue보다 0에 더 가깝다고 생각할 이유가 없습니다.
  • @TonioElGringo : 참과 거짓의 차이는 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() != 0)  

0이 거짓에 해당한다는 개념은 잘 이해되고 있기 때문입니다.

설명

  • 수학이 의미가 있기 때문에 언어가 그렇게 설계되었습니다. 그게 먼저 왔어요.
  • @Morwenn, 19 세기와 George Boole로 거슬러 올라갑니다. 사람들은 컴퓨터보다 오랫동안 False를 0으로, True를! 0으로 표현해 왔습니다.
  • 수학이 ‘ 왜 수학이되지 않는지 모르겠습니다. ‘ AND가 +이고 OR이 *가되도록 모든 정의를 변경하면 다른 방식으로 작동하지 않습니다.
  • 정확히 : 수학은 두 가지 방식으로 작동하고 이 질문은 순전히 관습적인 것 같습니다.
  • @Robert It ‘ ” 수학적 토대 ”

답변

다른 사람들이 말했듯이 수학이 우선입니다. 이것이 0이 false이고 1이 true 인 이유입니다.

어떤 수학에 대해 이야기하고 있습니까? 부울 대수 는 디지털 컴퓨터가 등장하기 훨씬 전인 1800 년대 중반부터 시작되었습니다.

이 규칙은 부울 대수보다 훨씬 오래된 명제 논리 에서 나왔다고 말할 수도 있습니다. 이것은 프로그래머가 알고 사랑하는 많은 논리적 결과의 형식화입니다 (false || xx, 는 x와 같음).

기본적으로 우리는 두 개의 요소가있는 집합에 대한 산술에 대해 이야기하고 있습니다. 이진수로 계산하는 것을 고려하십시오. 부울 대수는이 개념의 기원이며 이론적 토대입니다. C와 같은 언어의 규칙은 단순한 응용 프로그램입니다.

댓글

  • 하지만 ” 표준 ” 방식을 유지하면 일반 산술 (0 + 1 = 1이 아닌 0 + 1 = 0).
  • 예,하지만 정의를 반대로 바꾸면 + 및 OR로 *를 사용하여 AND를 작성할 수 있습니다.
  • 수학은 ‘ 먼저 오지 않습니다. 수학은 0과 1이 필드를 형성한다는 것을 인식했습니다. AND는 곱셈과 같고 OR는 더하기와 같습니다.
  • @ Kaz :하지만 OR 및 AND가 포함 된 {0, 1}은 필드를 형성하지 않습니다.
  • 더 많은 답변과 댓글에 true = 1가 표시된다는 점이 조금 귀찮습니다. ‘는 정확히 일치하지 않습니다. true != 0는 정확히 동일하지 않기 때문입니다. if(something == true) { ... }와 같은 비교를 피해야하는 유일한 이유는 아닙니다.

Answer

전자 제품의 “상속”및 부울 대수와 관련이 있다고 생각했습니다.

  • 0 = off, negative, no, false
  • 1 = on, positive, yes, true

strcmp 는 문자열이 동일 할 때 0을 반환합니다. 실제로 수행하는 작업은 두 문자열 사이의 “거리”를 계산하는 것이므로 구현과 관련이 있습니다. 0도 거짓으로 간주된다는 것은 우연의 일치 일뿐입니다.

성공시 0 을 반환하는 것은 의미가 있습니다. 이 경우 0은 오류 없음 을 의미하는 데 사용되며 다른 숫자는 오류 코드가됩니다. 성공을 위해 다른 숫자를 사용하면 성공 코드가 하나 뿐인 반면 여러 오류 코드가있을 수 있기 때문에 의미가 떨어집니다. “작동 했습니까?”를 사용합니다. if 문 식으로 0 = yes라고 말하면 더 의미가 있지만 식은 더 정확합니다. “무엇이 잘못 되었나요?” 그러면 0 = 아니요가 많은 의미가 있음을 알 수 있습니다. false/true는 실제로 no error code/error code이므로 여기서는 실제로 의미가 없습니다.

댓글

  • 하하, 반환 오류 질문을 명시 적으로 설명한 첫 번째 사람입니다. 나는 이미 내 방식으로 해석했고 다른 방식으로도 요청할 수 있다는 것을 알고 있었지만 ‘ 많은 답변과 댓글 중에서 가장 먼저 명시 적으로 표현했습니다.사실, 저는 ‘ 하나 또는 다른 방법이 말이 안된다고 말하고 싶지 않지만 둘 다 다른 방법으로 말이된다고 말하고 싶습니다. 🙂
  • 사실 나는 ‘ d는 success/no error에 대한 0가 다른 정수가 오류 코드를 나타낼 때 의미가있는 유일한 것입니다. . 0는 다른 경우에 false를 나타내기도하므로 ‘별로 중요하지 않습니다. 우리는 ‘ 여기서 진실이나 거짓에 대해 전혀 이야기하지 않습니다.)
  • 같은 생각을 가지고 있었기 때문에
  • strcmp() 거리를 계산하는 것은 아주 좋습니다. strdiff()라고 불렸다면 if (!strdiff())는 매우 논리적입니다.
  • ” electronics […] 여기서 0 = […] false, 1 = […] true “-전자 제품에서도 이것은 컨벤션 , 그리고 ‘ 유일한 것이 아닙니다. 이를 양의 논리라고 부르지 만 양의 전압이 거짓을 나타내고 음이 참을 나타내는 음의 논리를 사용할 수도 있습니다. 그러면 AND에 사용하는 ‘ 회로가 OR이되고 OR가 AND가되는 식으로 계속됩니다. De Morgan ‘의 법으로 인해 모든 것이 동등하게됩니다. 때때로, ‘ 편의를 위해 부 논리로 구현 된 전자 회로의 일부를 찾을 수 있습니다.이 부분에서 신호 이름은 그 위에 막대로 표시됩니다.

li>

답변

이 도움말 에 설명 됨 , falsetrue 값은 정수 0 및 1과 혼동해서는 안되지만 Galois 필드의 요소로 식별 될 수 있습니다. (유한 필드) 두 요소 ( 여기 참조).

필드는 특정 공리를 충족하는 두 개의 연산이있는 집합입니다.

기호 0과 1은 일반적으로 필드의 덧셈 및 곱셈 ID를 나타내는 데 사용됩니다. 실수도 ID가 0과 1 인 필드 (유한이 아님)이기 때문입니다.

추가 ID는 필드의 요소 0이며, 모든 x :

x + 0 = 0 + x = x 

및 곱셈 식별은 필드의 요소 1이며 모든 x에 대해 다음과 같습니다.

x * 1 = 1 * x = x 

두 요소의 유한 필드에는이 두 요소 만 있습니다. 덧셈 ID 0 (또는 false) 및 곱셈 ID 1 (또는 true). 이 필드의 두 가지 연산은 논리적 XOR (+) 및 논리적 AND (*)입니다.

참고. 연산을 뒤집 으면 (XOR은 곱셈이고 AND는 더하기) 곱셈은 더하기보다 분배되지 않으며 더 이상 필드가 없습니다. 이 경우 두 요소 0과 1 (순서에 관계없이)을 호출 할 이유가 없습니다. 또한 XOR 대신 OR 연산을 선택할 수 없습니다. OR / AND를 덧셈 / 곱셈으로 어떻게 해석하든 결과 구조는 필드가 아닙니다 (필드 공리에서 요구하는대로 모든 역 요소가 존재하는 것은 아닙니다).

C 함수 관련 :

  • 많은 함수가 오류 코드 인 정수를 반환합니다. 0은 오류 없음을 의미합니다.
  • 직관적으로 함수 strcmp는 두 문자열 간의 차이를 계산합니다. 0은 두 문자열간에 차이가 없음을 의미합니다. 즉, 두 문자열이 동일합니다.

위의 직관적 인 설명은 반환 값의 해석을 기억하는 데 도움이 될 수 있지만 훨씬 더 쉽습니다. 라이브러리 문서를 확인하십시오.

댓글

  • 이것을 임의로 바꾸면 더 이상 수학이 작동하지 않음을 보여주는 +1입니다.
  • Flipped : 두 개의 요소와 연산 * 및 +가있는 필드가 주어지면 True는 0으로, False는 1로 식별합니다. OR는 *로, XOR은 +로 식별합니다.
  • 둘 다 이러한 식별은 동일한 필드에서 수행되며 둘 다 부울 논리 규칙과 일치합니다. 안타깝게도 메모가 잘못되었습니다. 🙂
  • True = 0이고 XOR이 +라고 가정하면 True는 XOR의 ID 여야합니다. 그러나 True XOR True = False 때문이 아닙니다. True XOR True = True가되도록 True에서 XOR 연산을 재정의하지 않는 한. 물론 이름을 변경했기 때문에 구성이 작동합니다 (수학적 구조에서 항상 성공적으로 이름 순열을 만들고 동형 구조를 얻을 수 있음). 반면에 True, False 및 XOR이 일반적인 의미를 갖도록하면 True XOR True = False 및 True는 추가 ID가 될 수 없습니다. 즉 True는 0이 될 수 없습니다.
  • @Giorgio : 마지막 댓글의 댓글에 따라 구성을 수정했습니다…

답변

대체 시스템도 허용 가능한 설계 결정일 수 있음을 고려해야합니다.

쉘 : 0 종료 상태는 참, 0이 아닌 것은 거짓입니다.

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  

그 이유는 성공하는 방법은 하나 있지만 실패하는 방법은 여러 가지가 있으므로 “오류 없음”을 의미하는 특수 값으로 0을 사용하는 것은 실용적입니다.

Ruby : 0은 다른 숫자와 동일합니다.

“일반적인”프로그래밍 언어 중에는 Ruby와 같이 0을 실제 값으로 취급하는 이상 값이 있습니다.

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

이유 falsenil 만 거짓이어야한다는 것입니다. 많은 루비 초보자들에게는 “문제가 있습니다. 그러나 어떤 경우에는 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로 설정하는 것은 당연한 일입니다. 확장에 의해, 관례는 0은 거짓으로 취급되고 0이 아닌 값은 참으로 취급되도록 개발되었습니다. 그러나 반드시 그렇게 할 필요는 없습니다.

자바 : 숫자는 부울로 처리 할 수 없습니다.

자바에서는 truefalse는 유일한 부울 값입니다. 숫자는 부울이 아니며 부울로 변환 할 수도 없습니다 ( Java 언어 사양, Sec 4.2.2 ) :

정분 유형과 유형 boolean간에 캐스트가 없습니다. .

이 규칙은 질문을 완전히 피할뿐입니다. 모든 부울 표현식은 코드에 명시 적으로 작성되어야합니다.

댓글 h3>

  • Rebol 및 Red 는 모두 0 값 INTEGER! 값을 true로 취급하고 별도의 NONE! 유형을 갖습니다. (단 하나의 값, NONE) LOGIC! false 외에 조건부 false로 처리됩니다. ‘ 0을 false로 처리하는 JavaScript 코드를 작성하는 데 상당한 좌절감을 느꼈습니다. incr 동적으로 입력 된 언어에 대한 식용으로 투박한 결정. null 또는 0이 될 수있는 것을 테스트하고 싶다면 if (thing === 0)를 작성해야합니다. 이것은 멋지지 않습니다.
  • @HostileFork I don ‘ 모릅니다. 동적 언어에서 0true (다른 모든 정수)라는 것이 이치에 맞습니다. Python에서 None를 잡으려고 할 때 가끔 0를 잡는 경우가 있는데, 때때로 발견하기가 매우 어려울 수 있습니다.
  • Ruby는 이상 치가 아닙니다. Ruby는이를 Lisp에서 가져옵니다 (Ruby는 비밀리에 ” MatzLisp “라고도 함). Lisp는 컴퓨터 과학의 주류 언어입니다. 0은 POSIX 셸에서 ‘ 텍스트 if [ 0 ] ; then echo this executes ; fi이기 때문에 참 값이기도합니다. 거짓 데이터 값은 빈 문자열이며 테스트 가능한 거짓은 명령의 실패한 종료 상태이며 0이 아닌 -0으로 표시됩니다.

답변

일반 사례를 다루기 전에 반대 사례를 논의 할 수 있습니다.

문자열 비교

실제로 많은 종류의 비교에 대해서도 동일합니다. 이러한 비교는 두 개체 간의 거리 를 계산합니다. 물체가 같으면 거리가 최소화됩니다. 따라서 “비교가 성공하면”값은 0입니다. 그러나 실제로 strcmp의 반환 값은 부울이 아니고 거리이며 알지 못하는 프로그래머가 if (strcmp(...)) do_when_equal() else do_when_not_equal()를 수행하는 것을 가두는 것입니다.

C ++에서 strcmp를 다시 설계하여 iv id = 0 일 때 true를 반환하도록 operator bool()를 재정의하는 “7d4150f723”>

객체입니다 (하지만 다른 문제 세트에 물릴 것입니다). 또는 일반 C에서는 문자열이 같을 때 1을 반환하고 그렇지 않으면 0을 반환하는streq함수가 있습니다.

API 호출 / 프로그램 종료 코드

여기서 문제가 발생한 이유를 살펴 보겠습니다. 이로 인해 오류 결정이 내려지기 때문입니다. 일이 성공하면 특별히 어떤 것도 알고 싶지 않습니다. 의도가 실현됩니다. 따라서 반환 값은이 정보를 전달해야합니다.부울이 아니라 오류 코드입니다. 특수 오류 값 0은 “오류 없음”을 의미합니다. 나머지 범위는 처리해야하는 로컬에서 의미있는 오류를 나타냅니다 (종종 “지정되지 않은 오류”를 의미하는 1 포함).

일반 사례

이렇게하면 부울 값이 TrueFalse

음, 주관적인 “이쪽이 기분이 좋아집니다”라는 주장 외에도 다음과 같은 몇 가지 이유 (주관적)를 생각할 수 있습니다.

p>

  • 전기 회로 비유. 전류는 1 초 동안 ON, 0 초 동안 OFF입니다. 나는 다른 믹스보다 (1, Yes, True, On)과 (0, No, False, Off)를 함께 갖는 것을 좋아합니다

  • 메모리 초기화. 여러 변수 (int, float, bool)를 memset(0) 할 때 가장 보수적 인 가정과 일치하는 값을 원합니다. 예 : 내 합계는 처음에 0이고 술어는 False 등입니다.

아마도이 모든 이유가 교육과 관련이있을 수 있습니다. 처음에는 다른 방향으로 갈 것입니다.

코멘트

  • 실제로 0을 참으로 취급하는 프로그래밍 언어가 하나 이상 있습니다. 유닉스 셸입니다.
  • 실제 문제를 해결하기위한 +1 : Morwenn ‘의 질문 대부분은 ‘ t입니다. bool에 대한 것입니다.
  • @ dan04 그렇습니다. 전체 게시물은 여러 프로그래밍 언어에서 int에서 bool로 캐스트를 선택한 이유에 대한 것입니다. 비교 및 오류 동작 항목은 현재 수행 된 방식과 ‘가 타당한 방식이 아닌 다른 방식으로 캐스팅하는 경우의 예일뿐입니다.

답변

높은 수준의 관점에서 “당신은 완전히 다른 세 가지 데이터 유형에 대해 이야기하고 있습니다.

  1. 부울입니다. 부울 대수 의 수학적 규칙은 false에 0을 사용하고

    , 따라서 그 규칙을 따르는 것이 합리적입니다.이 방법도 직관적으로 더 합리적이라고 생각합니다.

  2. 비교 결과입니다. 세 가지 값 : <, => (둘 다 true). 각각 -1, 0 및 1의 값을 사용하는 것이 합리적입니다 (또는 일반적으로 음수 값, 0 및 양수 값).

    동등성을 확인하려면 일반적인 비교를 수행하는 함수 만 있으면 strcmp(str1, str2) == 0와 같은 것을 사용하여 명시 적으로 만들어야한다고 생각합니다. 이 상황에서 !를 사용하면 부울이 아닌 값을 부울 인 것처럼 취급하기 때문에 혼란 스럽습니다.

    또한 그 비교와 평등이 같을 필요는 없습니다. 예를 들어 생년월일로 사람들을 주문하는 경우 Compare(me, myTwin)0를 반환해야합니다. 이지만 Equals(me, myTwin)false를 반환해야합니다.

  3. 함수의 성공 또는 실패 , 성공 또는 실패에 대한 세부 정보도 함께 제공됩니다. “Windows에 대해 이야기하는 경우이 유형은 HRESULT 및 0이 아닌 값이 반드시 실패를 나타내는 것은 아닙니다. 실제로 음수 값은 실패와 음이 아닌 성공을 나타냅니다. 성공 값은 매우 자주 S_OK = 0이지만 예를 들어 S_FALSE = 1 또는 기타 값일 수도 있습니다.

혼란은 사실에서 비롯됩니다. 논리적으로 그 세 완전히 다른 데이터 유형은 실제로 C 및 일부 다른 언어에서 단일 데이터 유형 (정수)으로 표시되며 조건에서 정수를 사용할 수 있습니다. 하지만 조건에서 부울이 아닌 유형을 더 간단하게 사용하기 위해 부울을 재정의하는 것은 의미가 없다고 생각합니다.

또한 C의 조건에서 자주 사용되는 다른 유형 인 포인터를 고려해보십시오. . 여기서 NULL-포인터 (0로 표시됨)를 false. 따라서 제안을 따르면 포인터 작업이 더 어려워집니다. (개인적으로는 포인터를 부울로 취급하는 대신 명시 적으로 NULL와 비교하는 것을 선호합니다.)

Answer

대부분의 CPU에는 분기에 사용할 수있는 ZERO 플래그가 있기 때문에 0은 거짓 일 수 있습니다. 비교 작업을 저장합니다.

이유를 보겠습니다.

청중이 어셈블리를 읽지 않을 가능성이있는 일부 의사 코드

c- 소스 단순 루프 호출이 10 번 Wibble

 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의 규칙을 시도해 보겠습니다.

좀 더 c 소스 #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 

0이 아닌 true 인 케이스가 얼마나 짧은 지 확인하세요.

정말 초기 CPU에는 누산기에 작은 플래그 세트가 연결되어있었습니다.

a> b 또는 a = b가 일반적으로 비교 명령을 받는지 확인합니다.

  • B가 그렇지 않은 경우 ZERO-이 경우 ZERO 플래그는 단순 논리 NOR 또는 누산기의 모든 비트로 구현됩니다.
  • 또는 누산기의 최상위 비트 인 “부호 비트”만 사용하는 NEGATIVE 2의 보수 산술을 사용하는 경우. (대부분 우리)

다시 말하겠습니다. 일부 구형 CPU에서는 누산기가 0이거나 0보다 작은 누산기에 대해 비교 명령을 사용할 필요가 없었습니다.

이제 0이 거짓 일 수있는 이유를 알 수 있습니까?

이것은 가짜 코드이며 실제 명령어 세트가 이와 같이 보이지 않습니다. 어셈블리를 알고 있다면 내가 여기서 많은 것을 단순화하고 있음을 알 수 있습니다. 컴파일러 설계에 대해 아는 것이 있다면이 답변을 읽을 필요가 없습니다. 루프 풀기 또는 분기 예측에 대해 아는 사람은 고급 클래스가 203 호실에 있습니다.

댓글

  • 한 가지 if (foo)if (foo != 0)는 동일한 코드를 생성해야하며, 두 번째로 ‘ ‘ 실제로 사용중인 어셈블리 언어에 명시 적 부울 피연산자 및 테스트입니다. 예를 들어 jzjump if zero를 의미합니다. 즉, if (a == 0) goto target; . 수량은 직접 테스트되지도 않습니다. 조건은 특수 기계어에 저장된 부울 플래그로 변환됩니다. 실제로 ‘는
  • No Kaz, 구형 CPU ‘는 그렇게 작동하지 않았습니다. T jz / jnz는 비교 명령없이 수행 할 수 있습니다. 이것이 제 전체 게시물의 요점이었습니다.
  • ‘ 비교 지침에 대해 아무것도 쓰지 않았습니다.
  • 할 수 있습니까? jz 명령은 있지만 jnz는없는 프로세서를 인용하십니까? (또는 기타 비대칭 조건부 지침 세트)

답변

1과 참 사이의 대응은 일부 수학적 특성에 의해 필요합니다. 그런 속성을 찾을 수 없으며 순전히 역사적인 관습이라고 제안합니다.

두 개의 요소가있는 필드에 덧셈과 곱셈이라는 두 가지 연산이 있습니다.이 필드에 대한 부울 연산을 두 가지 방법으로 매핑 할 수 있습니다. :

전통적으로 True는 1로, False는 0으로 식별합니다. AND는 *로, XOR은 +로 식별합니다. 따라서 OR는 덧셈을 포화시킵니다.

그러나 우리는 쉽게 할 수 있습니다. True를 0으로, False를 1로 식별합니다. 그런 다음 OR를 *로, XNOR을 +로 식별합니다. 따라서 AND는 포화 덧셈입니다.

Comments

  • If wikipedia의 링크를 따라 가면 부울 대수의 개념이 두 요소로 구성된 Galois 필드의 개념과 관련이 있다는 것을 알 수있었습니다 ( en.wikipedia.org/wiki / GF % 282 % 29 ). 기호 0과 1은 일반적으로 덧셈과 곱셈 ID를 나타내는 데 사용됩니다. 실수도 ID가 0과 1 인 필드이기 때문입니다.
  • @NeilG Giorgio는 단순한 컨벤션 이상으로 ‘라고 말하려고합니다. 부울 대수에서 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를 뒤집 으면 필드가 없습니다. 더 이상. 따라서 적절한 필드의 ID로 0과 1을 정의하는 IMO는 거짓과 진실을 매우 충실하게 포착하는 것처럼 보입니다.
  • @giorgio : 무슨 일이 일어나고 있는지 명확하게하기 위해 대답을 편집했습니다.

답변

이상하게도 0이 항상 거짓은 아닙니다.

특히 Unix 및 Posix 규칙 EXIT_SUCCESS를 0으로 정의하고 EXIT_FAILURE를 1로 정의하는 것입니다. 실제로 표준 C 규칙 입니다!

Posix 쉘 및 종료 (2) syscalls, 0은 “성공”을 의미하며 직관적으로 거짓보다 참입니다.

특히 쉘의 if는 프로세스 반환 EXIT_SUCCESS (즉, 0)는 “then”분기를 따릅니다!

Schema (Common Lisp 또는 MELT ) 0 및 nil (즉, Scheme의 ())은 true이며, false 값은 #f

동의합니다. 순조롭게 진행합니다!

답변

C는 동일한 데이터에서 때때로 비트 연산과 논리 연산 사이를 이동해야하는 영역 인 하드웨어에 가까운 저수준 프로그래밍에 사용됩니다. 테스트를 수행하기 위해 숫자 표현식을 부울로 변환해야하는 경우 복잡해집니다. 코드입니다.

다음과 같이 작성할 수 있습니다.

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

  

하나의 분리 된 예에서는 그렇게 나쁘지는 않지만 그렇게해야하는 것은 성가 시게됩니다.

마찬가지로, 반대 작업입니다. 비교와 같은 부울 연산의 결과로 0 또는 1을 생성하는 데 유용합니다. modemctrl 여부에 따라 일부 단어의 세 번째 비트를 설정한다고 가정 해 보겠습니다. 캐리어 감지 비트가 있습니다.

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

여기에 != 0, 양방향 & 표현식의 결과를 0 또는 그러나 결과가 단지 정수이기 때문에 부울을 정수로 추가 변환하기 위해 성가신 캐스트를 추가 할 필요가 없습니다.

현재 C는 bool 유형의 경우에도 이와 같은 코드의 유효성은 “좋은 일이고 그렇지 않으면 발생할 수있는 이전 버전과의 호환성으로 인한 대규모 파손으로 인해 계속 유지됩니다.

C가 매끄러운 또 다른 예 : 4 방향 스위치로 두 개의 부울 조건 테스트 :

싸움 없이는 C 프로그래머로부터 이것을 빼앗을 수 없습니다!

마지막으로 C는 때때로 서비스를 제공합니다. 일종의 고급 어셈블리 언어입니다. 어셈블리 언어에는 부울 유형도 없습니다. 부울 값은 메모리 위치 또는 레지스터에서 비트 또는 0 대 0이 아닌 값입니다. 정수 0, 부울 0 및 주소 0은 모두 어셈블리 언어 명령어 세트에서 동일한 방식으로 테스트됩니다 (및 부동 소수점 0도 가능). C와 어셈블리 언어 사이의 유사성은 유용합니다. 예를 들어 C가 다른 언어를 컴파일하기위한 대상 언어로 사용되는 경우 (강력하게 형식화 된 부울이있는 언어도!)

Answer

부울 또는 진리 값에는 2 개의 값만 있습니다. 참과 거짓.

이것은 정수로 표현되지 아니라 비트 (0 및 1 ).

0 또는 1 이외의 다른 정수를 말하는 것은 거짓이 아닙니다. 진리표는 정수가 아닌 진리 값을 다룹니다.

진실 값 전망에서 -1 또는 2는 모든 진리표와 이와 관련된 부울 논리를 깨뜨립니다.

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

대부분의 언어에는 일반적으로 boolean가 있습니다. 정수와 같은 숫자 유형으로 캐스트 할 때 0의 정수 값으로 캐스트되는 거짓을 나타내는 유형입니다.

주석

  • 0 AND -1 == 어떤 부울 값으로 캐스팅하든. 그것이 ‘ 제 질문에 대한 것입니다. TRUE 또는 FALSE로 전송하는 이유입니다.내가 말하지 않았을 수도 있지만 의도하지 않았을 수도 있습니다. 정수가 참인지 거짓인지, 부울로 형변환 할 때 어떤 값으로 평가되는지 물었습니다.

답변

궁극적으로 일부 API는 형편 없기 때문에 핵심 언어를 깨는 것에 대해 이야기하고 있습니다. Crappy API는 새로운 것이 아니며 언어를 깨뜨려도 수정할 수 없습니다. 0은 거짓이고 1은 참이며이를 존중하지 않는 모든 언어는 근본적으로 깨졌습니다. 3 방향 비교는 다음과 같습니다. 3 개의 가능한 결과를 반환하므로 결과가 암시 적으로 bool로 변환되는 비즈니스가 없습니다. 이전 C API는 단순히 끔찍한 오류 처리 기능을 가지고 있으며 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))를 의미합니다.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다