Miért 0 hamis?

Ez a kérdés lehet néma, de miért 0 értékeli ezt: false és bármely más [egész szám] érték a true értékre a legtöbb programozási nyelv?

Karakterlánc összehasonlítás

Mivel a kérdés kicsit túl egyszerű, még egy kicsit elmagyarázom magamnak: először is minden programozó számára nyilvánvalónak tűnhet, de miért ne lenne programozási nyelv – valójában lehet, de nem olyan, amelyet használtam – ahol 0 true értékre, az összes többi [egész] értékre false értéket ad? Ez az egyetlen megjegyzés véletlenszerűnek tűnhet, de van néhány példám, ahol jó ötlet lehetett. Először is vegyük a húrok háromirányú összehasonlításának példáját, C “s strcmp mint példa: minden olyan programozó, aki C-t próbálja első nyelvként, megkísérelheti a következő kódot írni:

Mivel strcmp 0 amely false -re értékeli, ha a karakterláncok egyenlőek, amit a kezdő programozó megpróbált megtenni, csúnyán elbukik, és általában nem érti először. Ha ehelyett 0 értékelték volna, hogy true, akkor ezt a függvényt a legegyszerűbb – a fenti kifejezésben – az egyenlőség összehasonlításakor lehetett volna használni, és a -1 és 1 megfelelő ellenőrzéseket csak szükség esetén végezték volna el. A visszatérési típust legtöbbször bool -nek tekintettük (gondolatunkban erre gondolok).

Ezenkívül vezessünk be egy új típust, sign, amely éppen -1, 0 és 1. Ez nagyon hasznos lehet. Képzelje el, hogy van egy űrhajó-üzemeltető a C ++ nyelven, és szeretnénk, ha a std::string (nos, már létezik a compare függvény, de az űrhajó-üzemeltető szórakoztatóbb). A deklaráció jelenleg a következő lenne:

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

0 értékelték volna true, az űrhajó-üzemeltető nem is létezne, és így deklarálhattuk volna a operator== -t:

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

Ez operator== egyszerre háromirányú összehasonlítást kezeltek, és továbbra is felhasználhatók a következő ellenőrzés elvégzésére, miközben továbbra is ellenőrizni tudták, hogy melyik karakterlánc a lexikográfiai szempontból felülmúlja a másikat, ha szükséges:

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

Régi hibakezelés

Most vannak kivételeink, ezért ez a rész csak a régi nyelvekre vonatkozik, ahol ilyen nincs létezik (például C). Ha megnézzük a C szabványos könyvtárát (és a POSIX könyvtárat is), akkor biztosan láthatjuk, hogy a maaaaany függvények sikeresen 0 -et adnak vissza, máskülönben pedig egész számot. Sajnos néhány embert láttam tegyen ilyeneket:

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

Ha belegondolunk, hogyan gondolkodunk programozáskor gyakran a következő érvelési mintánk van:

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

Ha belegondolunk megint értelmes lett volna az egyetlen semleges értéket, 0, hogy yes (és hogy “C” függvények működnek), míg az összes többi érték ott lehet, hogy megoldja a no sok esetét. Mindazonáltal az összes általam ismert programozási nyelvben (talán néhány kísérleti ezoterikus nyelv kivételével), hogy yes false -re értékeli if állapotban, wh Az összes no eset true -re változik. Sok helyzet van, amikor a “működik” egy esetet képvisel, míg a “nem működik” a valószínű okokat. Ha így gondolkodunk, akkor ha 0 értékeli true, a többit pedig false sokkal értelmesebb lett volna.

Következtetés

A következtetésem lényegében az eredeti kérdésem: miért terveztünk olyan nyelveket, ahol 0 található false és a többi érték true, figyelembe véve néhány fenti példámat, és talán még néhányat, amire nem gondoltam?

Utánkövetés: Nagyon jó látni, hogy sok válasz van sok ötlettel és annyi lehetséges okkal imádom, hogy milyen szenvedélyesnek tűnik emiatt.Eredetileg unalomból tettem fel ezt a kérdést, de mivel annyira szenvedélyesnek tűnik, úgy döntöttem, hogy tovább megyek, és rákérdezek a logikai választás indokaira 0 és 1 a Math.SE-n 🙂

Megjegyzések

  • strcmp() nem jó példa az igaz vagy hamis, mivel 3 különböző értéket ad vissza. És meg fog lepődni, ha elkezdi használni a héjat, ahol a 0 igazat, bármi más hamisat jelent.
  • @ ott–: A Unix héjakban a 0 sikert és nem -zero jelentése kudarc – nem teljesen ugyanaz, mint ” true ” és ” false “.
  • @KeithThompson: A Bash-ban (és más héjakban) ” siker ” és ” hiba ” valóban megegyezik a ” true ” és ” false “. Vegyük például a if true ; then ... ; fi állítást, ahol a true egy parancs, amely nulla értéket ad vissza, és ez azt mondja, hogy if a ... futtatásához.
  • A hardverben nincsenek logikai értékek, csak bináris számok, és a legtöbb történelmi ISA-ban nem nulla számot vesznek figyelembe. mint ” true ” az összes feltételes elágazási utasításban (hacsak ‘ nem használnak zászlót helyette). Tehát az alacsony szintű nyelvek mindenképpen kötelesek követni az alapul szolgáló hardver tulajdonságokat.
  • @MasonWheeler Ha egy logikai típus nem ‘ nem jelent semmit. Például a python típusa bool típusú, de az összehasonlítások / ha a feltételek stb. Bármilyen visszatérési értékkel bírhatnak.

Válasz

0 false, mert mindkettő nulla elem a közös félosztályokban . Annak ellenére, hogy különálló adattípusok, intuitív értelemben van konvertálni közöttük, mert izomorf algebrai struktúrákhoz tartoznak.

  • 0 az összeadás azonosítója és a szorzás nulla. Ez igaz egész számokra és racionális értékekre, de nem IEEE-754 lebegőpontos szám: 0.0 * NaN = NaN és 0.0 * Infinity = NaN .

  • false a logikai xor (⊻) és nulla a logikai identitása és (∧). Ha a Booleans-t {0, 1} -ként – a modulo 2 egész számok halmazaként – ábrázolhatjuk, úgy gondolhatjuk, hogy ⊻ hordozás nélküli összeadás és and szorzás.

  • "" és a [] azonosítás az összefűzéshez, de számos olyan művelet létezik, amelyeknél nullának van értelme. Az ismétlés az egyik, de az ismétlés és az összefűzés nem terjeszti, így ezek a műveletek nem alkotnak semiringet.

Az ilyen implicit átalakítások hasznosak kis programokban, de nagyban nehezebben indokolhatja a programokat. Csak egy a sokféle kompromisszumból a nyelvtervezésben.

Megjegyzések

  • Szép, hogy Ön felsorolt. (BTW, nil mind az üres lista [], mind a false érték a Common Lisp-ben ; van-e hajlandóság a különböző adattípusokból származó identitások egyesítésére?) Még mindig meg kell magyaráznia, miért természetes, hogy a hamisat additív identitásnak, az igazat pedig multiplikatív identitásnak tekintjük, és nem fordítva. Nem lehetséges, hogy ‘ a true -et a AND azonosítójaként és a OR?
  • +1 hasonló identitásokra való hivatkozásért. Végül egy olyan válasz, amely nem ‘ csak leforr a ” egyezményig, foglalkozzon vele “.
  • +1 egy konkrét és nagyon régi matematika részleteinek megadásáért, amelyben ezt követték és régóta értelmes volt
  • Ez a válasz nem ‘ t van értelme. A true a félidők (logikai és / vagy) identitása és nulla. Nincs ok arra, hogy alkalmazzuk a konvenciót, hogy úgy gondoljuk, hogy a false közelebb van a 0-hoz, mint a true.
  • @TonioElGringo: Az igaz és hamis különbség az XOR és az XNOR közötti különbség. Izomorf gyűrűket alkothatunk az AND / XOR használatával, ahol igaz a multiplikatív azonosság és hamis az additív, vagy OR és XNOR esetén, ahol hamis a multiplikatív azonosság és az igaz az additív, de az XNOR-ot általában nem tekintik közösnek alapvető művelet az XOR módja.

Válasz

Mivel a matematika működik.

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

Hagyományosan a C programok olyan feltételekkel rendelkeznek, mint

 if (someFunctionReturningANumber())  

helyett

 if (someFunctionReturningANumber() != 0)  

mert a nulla egyenértékű hamis fogalma jól érthető.

Megjegyzések

  • A nyelveket azért tervezték, mert a matematikának van értelme. Ez jött előbb.
  • @Morwenn, a 19. századig nyúlik vissza és George Boole. Az emberek a False-t 0-ként és True-t! 0-ként jelentik hosszabb ideig, mint ahány számítógép volt.
  • Nem tudom, ‘ miért nem látom a matematikát ‘ akkor nem működik másképp, ha csupán az összes definíciót megváltoztatja úgy, hogy az AND + és OR legyen *.
  • Pontosan: a matematika mindkét irányban működik, és a válasz úgy tűnik, hogy ez a kérdés tisztán konvencionális.
  • @Robert ‘ d nagyszerű lenne, ha meg tudná mondani a ” matematikai alapok ” a bejegyzésedben.

Válasz

Mint mások mondták, a matematika volt az első. Ezért 0 a false, az 1 pedig true.

Melyik matematikáról beszélünk? Boole-algebrák , amelyek az 1800-as évek közepétől származnak, jóval a digitális számítógépek megjelenése előtt.

Azt is mondhatja, hogy a konvenció propozíciós logikából jött ki, amely még a logikai algebráknál is régebbi. Ez sok olyan logikai eredmény formalizálása, amelyet a programozók ismernek és szeretnek (false || x egyenlő x, true && x egyenlő x és így tovább).

Alapvetően két elemű halmazon beszélünk az aritmetikáról. Gondoljon a bináris számolásra. A logikai algebrák eredete ennek a koncepciónak és elméleti megalapozásának. Az olyan nyelvek konvenciói, mint a C, csak egy egyszerű alkalmazás.

Megjegyzések

  • , az biztos. De ha a ” szabványos ” módon tartjuk, az jól illeszkedik az általános aritmetikához (0 + 1 = 1, nem 0 + 1 = 0).
  • Igen, de feltehetően az ÉS-t írná a + és az OR gombbal, ha megfordítaná a definíciókat.
  • A matematika nem ‘ nem az első. Math felismerte, hogy a 0 és az 1 olyan mezőt alkot, amelyben az ÉS olyan, mint a szorzás, az OR pedig az összeadás.
  • @ Kaz: De a {0, 1} az OR és az AND nem alkot mezőt.
  • Kicsit zavar, hogy több válasz és megjegyzés azt mondja, hogy true = 1. Ez ‘ nem egészen pontos, mert true != 0 ami nem teljesen ugyanaz. Az egyik ok (és nem az egyetlen), amiért el kell kerülni az összehasonlításokat, például if(something == true) { ... }.

Válasz

Úgy gondoltam, hogy ennek köze van az elektronika “öröklődéséhez”, valamint a logikai algebrához, ahol

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

strcmp 0 értéket ad vissza, ha a karakterláncok egyenlőek, a megvalósítással van összefüggésben, mivel valójában azt jelenti, hogy kiszámolja a két karakterlánc közötti távolságot. Az, hogy a 0-t is véletlenül hamisnak tekintik, csak egybeesés.

0 visszatérése a sikernek van értelme mert a 0 ebben az esetben nincs hiba jelentése, és bármely más szám hibakódnak számít. Bármely más szám használata sikernek kevésbé lenne értelme, mivel csak egyetlen sikerkódja van, míg több hibakódja is lehet. Ön a “Működött?” mint ha az if kifejezés kifejezés és a 0 = igen kimondása sokkal értelmesebb lenne, de a kifejezés helyesebb: “Valami baj történt?” és akkor látod, hogy a 0 = nem sok értelme van. A false/true -re gondolni itt nincs igazán értelme, mivel valójában no error code/error code.

Megjegyzések

  • Haha, te vagy az első, aki kifejezetten kimondja a visszatérési hiba kérdését. Már tudtam, hogy értelmezem a magam módján, és ezt meg is kérdezhetném másképp, de te ‘ te vagy az első, aki kifejezetten kifejezi (a sok válasz és megjegyzés közül).Valójában nem mondanám ‘ azt, hogy egyik vagy másik útnak nincs értelme, de több mindkettőnek különböző módon van értelme 🙂
  • Valójában én ‘ d mondjuk 0 a success/no error számára az egyetlen, aminek van értelme, ha más egész számok hibakódokat képviselnek . Ez az 0 véletlenül a false -et is képviseli, más esetekben pedig nem igazán fontos, mert ‘ itt egyáltalán nem igazakról vagy hamisakról beszélünk;)
  • nekem ugyanaz volt az elképzelésem, ezért támogattam
  • strcmp() a távolság kiszámítása nagyon jó. Ha strdiff() -nek hívták volna, akkor a if (!strdiff()) nagyon logikus lenne.
  • ” elektronika […] ahol 0 = […] hamis, 1 = […] igaz ” – ez még az elektronikában is csak egy konvenció , és nem csak ‘ t. Ezt pozitív logikának hívjuk, de használhatunk negatív logikát is, ahol a pozitív feszültség hamisat, a negatív pedig igazat jelöl. Ezután az áramkör, amelyet ‘ használ az ÉS számára, VAGY, vagy VAGY ÉS lesz, és így tovább. A De Morgan ‘ törvény miatt mindez ekvivalens lesz. Előfordul, hogy ‘ megtalálja az elektronikus áramkör egy részét, amely a kényelem kedvéért negatív logikában valósul meg, és ekkor az adott részen lévő jelek nevét felette egy sáv jelöli.

Válasz

Amint azt a ebben a cikkben , a false és a true értékeket nem szabad összekeverni a 0 és 1 egész számokkal, de azonosíthatók a Galois mező elemeivel (véges mező) két elemből (lásd itt ).

A mező két művelettel rendelkező halmaz, amely bizonyos axiómákat kielégít.

A 0 és 1 szimbólumokat hagyományosan egy mező additív és multiplikatív identitásának jelölésére használják, mivel a valós számok is egy mező (de nem véges), amelynek azonossága a 0 és 1 szám.

Az additív azonosság a mező 0. eleme, amely az összes x esetében:

x + 0 = 0 + x = x 

és a multiplikatív identitás a mező 1. eleme, oly módon, hogy az összes x esetében:

x * 1 = 1 * x = x 

Két elem véges mezőjében csak ez a két elem szerepel, mégpedig additív identitás 0 (vagy false) és az 1 multiplikatív identitás (vagy true). Ennek a mezőnek a két művelete a logikai XOR (+) és a logikai ÉS (*).

Megjegyzés. Ha megfordítja a műveleteket (XOR a szorzás és az AND az összeadás), akkor a szorzás nem disztributív az összeadás felett, és nincs többé mezője. Ilyen esetben nincs oka a két elem 0 és 1 (tetszőleges sorrendben) hívására. Vegye figyelembe azt is, hogy nem választhatja az OR műveletet az XOR helyett: függetlenül attól, hogy az OR / AND-t hogyan értelmezi összeadásként / szorzásként, az eredményül kapott szerkezet nem mező (nem minden inverz elem létezik, ahogy azt a mező axiómái megkövetelik).

A C függvényekkel kapcsolatban:

  • Sok függvény egy egész számot ad vissza, amely hibakód. A 0 azt jelenti, hogy NINCS HIBA.
  • Intuitív módon a strcmp függvény kiszámítja a két karakterlánc közötti különbséget. A 0 azt jelenti, hogy nincs különbség két karakterlánc között, vagyis hogy két karakterlánc egyenlő.

A fenti intuitív magyarázatok segíthetnek emlékezni a visszatérő értékek értelmezésére, de még egyszerűbb csak ellenőrizze a könyvtár dokumentációját.

Megjegyzések

  • +1 annak bizonyítására, hogy ha önkényesen cserélgeti ezeket, a matematika már nem működik.
  • Megfordítva: Ha két elemű műveletet és * és + mezőt adunk meg, akkor a True-t 0-val, a False-t 1-vel azonosítjuk. A OR-t a * -val, az XOR-t a + -al azonosítjuk.
  • Meg fogja találni, hogy mindkettő ezen azonosítások ugyanazon a mezőn keresztül történnek, és mindkettő összhangban van a logikai szabályokkal. A megjegyzés sajnos helytelen 🙂
  • Ha azt feltételezi, hogy True = 0, és az XOR +, akkor az True-nak kell lennie az XOR identitásának. De nem azért, mert True XOR True = Hamis. Hacsak nem definiálja újra az XOR műveletet a True-on, így a True XOR True = True. Aztán természetesen az építkezésed működik, mert csak átnevezted a dolgokat (bármilyen matematikai struktúrában mindig sikeresen létrehozhatsz névmutatást és izomorf struktúrát kapsz). Másrészt, ha hagyja, hogy az Igaz, a Hamis és az XOR a szokásos jelentéssel bírjon, akkor az Igaz XOR Igaz = Hamis és Igaz nem lehet az additív identitás, vagyis az Igaz nem lehet 0.
  • @Giorgio: Az utolsó megjegyzésemben megjavítottam a megjegyzésem kommentje alapján…

Válasz

Fontolja meg, hogy alternatív rendszerek is elfogadható tervezési döntések lehetnek.

Héjak: A 0 kilépési állapot igaz, a nulla értéke hamis

A 0-t kezelő héjak példája a kilépés állapotát igazként már említettük.

 $ ( 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  

Ennek oka van a sikernek egy módja van, de a kudarc sokféleképpen, így a 0 használata speciális értékként, amely “nincs hiba”, pragmatikus.

Ruby: 0 pontosan olyan, mint bármely más szám

A “normál” programozási nyelvek között van néhány olyan kiugró érték, mint például a Ruby, amelyek a 0-t valós értékként kezelik.

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

A indoklás szerint csak false és nil hamisak lehetnek. Sok Ruby-újonc számára ez nagyon jó. Egyes esetekben azonban jó, hogy a 0-t ugyanúgy kezeljük, mint bármely más számot.

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" 

, egy ilyen rendszer csak olyan nyelven működik, amely képes megkülönböztetni a logikai értékeket külön típusként a számoktól. A számítás korábbi napjaiban az összeállítási nyelvvel vagy a nyers gépnyelven dolgozó programozóknak nem volt ilyen luxusuk. Valószínűleg természetes, hogy a 0-at “üres” állapotként kezeljük, és kissé 1-re állítjuk zászlóként, amikor a kód észleli, hogy valami történt. Tágabb értelemben az a megállapodás alakult ki, hogy a nullát hamisnak, a nem nulla értékeket pedig igaznak tekintették. Ennek azonban nem kell így lennie.

Java: A számokat egyáltalán nem lehet logikai értékként kezelni

Java-ban a true és a false az egyetlen logikai érték. A számok nem logikai értékek, és nem is dobhatók logikai értékekbe ( Java nyelv specifikáció, Sec 4.2.2 ):

Az integrált típusok és a boolean típus között nincs casting .

Ez a szabály csak teljesen elkerüli a kérdést – az összes logikai kifejezést kifejezetten be kell írni a kódba.

Megjegyzések

  • A Rebol és a Red mind a 0 értékű INTEGER! értékeket igaznak tekinti, és külön NINCS! típussal rendelkezik (csak egy értékkel, NINCS) feltételes hamisként kezelve a LOGIC! false mellett. I ‘ jelentős csalódottságot tapasztaltam a 0-t hamisnak kezelő JavaScript-kód megírásában; egy növekmény ehetően ügyetlen döntés egy dinamikusan tipizált nyelv mellett. Ha olyan dolgot szeretne tesztelni, amely null vagy 0 lehet, akkor fel kell írnia a if (thing === 0) szöveget, az egyszerűen nem jó.
  • @HostileFork én nem ‘ nem tudom. Úgy látom, hogy van értelme, hogy a 0 true (mint minden más egész szám) dinamikus nyelven. Néha előfordult, hogy elkaptam egy 0 -t, amikor megpróbáltam elkapni a None -t Pythonban, és ezt néha elég nehéz észrevenni.
  • A rubin nem kirívó. Ruby ezt elveszi Lisp-től (Ruby-t titokban még ” MatzLisp ” -nek is hívják. A Lisp az informatika egyik fő nyelve. A nulla is csak egy igazi érték a POSIX shellben, mert ‘ egy szövegrészt: if [ 0 ] ; then echo this executes ; fi. A hamis adatok értéke egy üres karakterlánc, a tesztelhető hamisítás pedig egy parancs sikertelen felmondási állapota, amelyet non -zér jelent.

Válasz

Mielőtt az általános esetet tárgyalnánk, megbeszélhetjük az ellenpéldákat.

Karakterlánc-összehasonlítások

Ugyanez vonatkozik sokféle összehasonlításra is. Az ilyen összehasonlítások távolságot számolnak két objektum között. Ha az objektumok egyenlőek, akkor a távolság minimális. Tehát, ha az “összehasonlítás sikeres”, akkor az értéke 0. De valójában a strcmp visszatérési értéke nem logikai érték, ez távolság, és hogy mi csapdába ejti a programozókat, akik nem tudják, hogy if (strcmp(...)) do_when_equal() else do_when_not_equal().

A C ++ – ban újratervezhetnénk a strcmp elemet egy Distance objektum, amely felülírja a (z) operator bool() objektumot, ha igaz értéket ad vissza, amikor 0 (de akkor más problémák haladnának meg). Vagy a C közönségében csak van egy streq függvény, amely 1-et ad vissza, ha a karakterlánc egyenlő, és 0-t különben.

API hívások / program kilépési kód

Itt érdekel valami, amiért valami nem sikerült, mert ez hibára készteti a döntéseket. Amikor a dolgok sikerrel járnak, nem akar semmit különösebben megtudni – a szándéka megvalósul. A visszatérő értéknek tehát át kell adnia ezeket az információkat.Ez nem logikai érték, hanem hibakód. A speciális hibaérték 0 azt jelenti, hogy “nincs hiba”. A tartomány többi része olyan helyileg értelmezhető hibákat képvisel, amelyekkel kezelnie kell (beleértve az 1-et is, ami gyakran “meghatározatlan hibát” jelent).

Általános eset

Ebből adódik a kérdés: miért vannak logikai értékek True és False általánosan ábrázolva 1-rel, illetve 0-val?

Nos, a szubjektív “így jobb érzés” érv mellett itt van néhány ok (szubjektív is), amire gondolok:

  • elektromos áramkör analógia. Az áram 1 másodpercig BE és 0 másodpercig KI. Szeretem, ha (1, Igen, Igaz, Be) van együtt, és (0, Nem, Hamis, Ki), nem pedig egy másik keverék

  • a memória inicializálása. Amikor memset(0) egy csomó változó (legyen az ints, float, bool), azt akarom, hogy értéke megegyezzen a legkonzervatívabb feltételezésekkel. Például. az összegem eredetileg 0, az állítmány hamis stb.

Lehet, hogy mindezek az okok az oktatásomhoz kötődnek – ha megtanítottak volna 0-t társítani az kezdetén fordítva mennék.

Megjegyzések

  • Valójában létezik legalább egy programozási nyelv, amely a 0-t igazként kezeli. Az unix shell.
  • +1 a valódi probléma kezeléséhez: Morwenn ‘ kérdésének többsége nem ‘ t kb. bool.
  • @ dan04 Az. A teljes bejegyzés arról szól, hogy milyen okokból választják ki a szereplőgárdát int és bool között számos programozási nyelven. Az összehasonlítás és a hibagesztusok csak példák azokra a helyekre, ahol értelmes lenne más módon leadni, mint amit jelenleg ‘ csinál.

Válasz

Magas szintű szempontból három egészen különböző adattípusról beszélsz:

  1. Boolean. A Boolean algebra matematikai konvenciója a 0 értéket használja a false és a true, ezért van értelme követni ezt a konvenciót. Úgy gondolom, hogy ez a módszer intuitívabban is értelmesebb.

  2. Az összehasonlítás eredménye. Ez három érték: <, = és > (vegye figyelembe, hogy egyik sem true). Számukra ésszerű -1, 0 és 1 értékeket használni (vagy általánosabban negatív, nulla és pozitív értékeket).

    Ha ellenőrizni szeretné az egyenlőséget a Második funkcióval rendelkezik, amely általános összehasonlítást végez, úgy gondolom, hogy ezt kifejezetten meg kell tennie olyasmi használatával, mint strcmp(str1, str2) == 0. Zavarba ejtőnek találom az ! használatát ebben a helyzetben, mert egy nem logikai értéket úgy kezel, mintha logikai érték lenne.

    Ne feledje továbbá, hogy az összehasonlítás és Az egyenlőség ne legyen ugyanaz. Például, ha az embereket születési dátum szerint rendeli meg, a Compare(me, myTwin) értéknek vissza kell térnie 0 , de Equals(me, myTwin) vissza kell adnia a false értéket.

  3. A függvény sikere vagy kudarca , esetleg a siker vagy kudarc részleteivel is. Ha a Windows-ról beszél, akkor ezt a típust HRESULT és a nem nulla érték nem feltétlenül jelenti a kudarcot. Valójában egy negatív érték kudarcot és nem negatív sikert jelez. A siker értéke nagyon gyakran S_OK = 0, de lehet például S_FALSE = 1 vagy más értékek is.

A zavart a tény okozza hogy logikusan hármat a meglehetősen különböző adattípusok valójában egyetlen adattípusként (egész számként) vannak ábrázolva C-ben és néhány más nyelven, és hogy egész számot használhat egy feltételben. De nem gondolom, hogy lenne értelme újból definiálni a logikai értéket, hogy egyes nem logikai típusúakat egyszerűbbé tegyünk bizonyos körülmények között.

Fontoljon meg egy másik típust is, amelyet gyakran használnak a C állapotban: mutató . Ott természetes, hogy egy NULL -mutatót (amelyet 0 néven képviselnek) false. Tehát a javaslatod követése a mutatókkal való munkát is megnehezítené. (Bár személy szerint inkább a mutatók kifejezett összehasonlítását szeretném összehasonlítani a NULL vel, ahelyett, hogy logikai értékként kezelném őket.)

Válasz

A nulla hamis lehet, mert a legtöbb CPU-nak ZERO jelzője van, amely az elágazáshoz használható. Ment egy összehasonlítási műveletet.

Lássuk, miért.

Néhány psuedocode, mivel a közönség valószínűleg nem olvassa az összeállítást

c- forrás egyszerű hurokhívások 10-szer mozognak

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

valamilyen színlelt összeállítás ehhez

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- másik egyszerű forrás a ciklus 10 alkalommal hívogat >

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 

további c források

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

és az assembly

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

megtudja, milyen rövid ez?

további c forrás

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

és az összeállítás (feltételezhet egy marginálisan intelligens fordítóprogramot, amely = = 0 helyettesítheti összehasonlítás nélkül )

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

Most kipróbálhatja a true = 1 konvenciót

még néhány c forrás #define TRUE 1 int foo = TRUE; if (foo == IGAZ) wibble ()

és az assembly

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

megnézheti, hogy a nonzero true eset milyen rövid?

Tényleg a korai CPU-k kis zászlókészletekkel voltak összekötve az akkumulátorral.

Annak ellenőrzésére, hogy az a> b vagy a = b általában összehasonlítási utasítást igényel-e.

  • Hacsak B nem vagy ZERO – ebben az esetben a ZERO jelzőt egyszerű logikai NOR-ként állítják be, vagy az összes bit az Akkumulátorban.
  • Vagy NEGATÍV, amelyben csak a “jel bitet” kell használni, azaz az akkumulátor legjelentősebb bitjét. ha két komplementaritmust használ. (Leginkább mi csináljuk)

Ezt megismételhetjük. Néhány régebbi CPU-n nem kellett összehasonlító utasítást használni a nullával egyenlő akkumulátor vagy a nullánál kisebb akkumulátor esetében.

Most látja, miért lehet a nulla hamis?

Felhívjuk figyelmét, hogy ez psuedo-kód, és egyetlen valós utasításkészlet sem néz ki így. Ha ismeri az összeállítást, akkor tudja, hogy itt nagyon leegyszerűsítem a dolgokat. Ha tudsz valamit a fordító tervezéséről, akkor nem kellett elolvasnod ezt a választ. Bárki, aki tud bármit a hurok kibontásáról vagy az elágazás előrejelzéséről, a haladó osztály a 203-as teremben van.

Megjegyzések

  • Az Ön állítása itt nincs jól megfogalmazva, mert egy dologra if (foo) és if (foo != 0) -nek ugyanazt a kódot kell generálnia, másodszor pedig ‘ megmutatja, hogy a ‘ által használt összeállítási nyelv valójában kifejezett logikai operandusok és tesztek számukra. Például jz jelentése: jump if zero. Más szóval if (a == 0) goto target; . És a mennyiséget még közvetlenül nem is teszteljük; a feltételt konvertáljuk egy logikai zászlóvá, amelyet egy speciális gépi szó tárol. Ez ‘ valójában inkább cpu.flags.zero = (a == 0); if (cpu.flags.zero) goto target;
  • Nem Kaz, a régebbi CPU ‘ s nem így működött. T a jz / jnz összehasonlítási utasítás elvégzése nélkül is végrehajtható. Ami valóban az egész hozzászólásom lényege volt.
  • Nem írtam ‘ semmit egy összehasonlítási utasításról.
  • Tudna idézzen egy processzort, amely jz utasítással rendelkezik, de nincs jnz? (vagy a feltételes utasítások bármely más aszimmetrikus halmaza)

Válasz

Nagyon sok válasz utal arra, hogy az 1 és az igaz közötti megfelelést valamilyen matematikai tulajdonság szükségessé teszi. Nem találok ilyen tulajdonságokat, és azt javasolhatom, hogy pusztán történelmi konvenció.

Ha két elemű mezőt adunk meg, két műveletünk van: összeadás és szorzás. Kétféle módon térképezhetjük fel a Boolean műveleteket ezen a mezőn :

Hagyományosan a True-t 1-vel, a False-t 0-val azonosítjuk. Az AND-t * -val, az XOR-t a + -al azonosítjuk. Így az OR telítő adalék.

Ugyanakkor ugyanolyan könnyen azonosítsuk a True-t 0-val, a False-t 1-vel. Ezután a VAGY-t * -val, az XNOR-t a + -al azonosítjuk. Így az AND telítődési kiegészítés. követte a wikipédia linkjét, megállapíthatta, hogy a logikai algebra fogalma lezárult a két elem Galois-mezőjéhez ( hu.wikipedia.org/wiki / GF% 282% 29 ). A 0 és 1 szimbólumokat hagyományosan az additív és a multiplikatív identitás jelölésére használják, mert a valós számok is olyan mezők, amelyek azonosítói a 0 és 1 számok.

  • @NeilG Azt hiszem, Giorgio megpróbálja mondani ‘ s nem csupán egyezményt. A logikai algebrában a 0 és az 1 alapvetően megegyezik a GF (2) 0 és 1 értékével, amelyek valós számban majdnem ugyanúgy viselkednek, mint a 0 és az 1 az összeadás és a szorzás tekintetében.
  • @svick: Nem , mert egyszerűen átnevezheti a szorzást és a telítődési összeadást OR és ÉS értékre, majd megfordíthatja a címkéket úgy, hogy a 0 igaz, az 1 pedig hamis legyen.Giorgio szerint a logikai logika egyezménye volt, amelyet a számítástechnika konvenciójaként fogadtak el. szorzás az összeadás felett (lásd: hu.wikipedia.org/wiki/Field_%28mathematics%29 ), de ha +: = AND és *: = XOR , akkor T XOR (T ÉS F) = T XOR F = T, míg (T XOR T) ÉS (T XOR F) = F ÉS T = F. Ezért a műveletek és az azonosságok átfordításával nem rendelkezik mezővel többé. Tehát úgy tűnik, hogy az IMO, ha a 0-t és az 1-et egy megfelelő mező identitásaként definiálja, elég hűen rögzíti a hamisakat és az igazakat.
  • @giorgio: A választ úgy szerkesztettem, hogy nyilvánvalóvá váljon, mi történik.
  • Válasz

    Furcsa módon a nulla nem mindig hamis.

    Különösen a Unix és a Posix konvenció az, hogy a EXIT_SUCCESS -et 0-ként definiáljuk (és EXIT_FAILURE mint 1). Valójában ez még egy szokásos C konvenció !

    Tehát a Posix héjak és a kilépés esetén (2) syscalls, 0 jelentése “sikeres”, amely intuitív módon inkább igaz, mint hamis.

    Különösen az “s if héj akarja a process return EXIT_SUCCESS (vagyis 0), hogy az “akkor” ágát kövesse!

    A sémában (de nem a Common Lisp-ben vagy a MELT ) 0 és nulla (azaz a () a rendszerben) igaz, mivel az egyetlen hamis érték #f

    Egyetértek, nikkelek!

    Válasz

    C a hardverhez közeli alacsony szintű programozáshoz használatos, egy olyan területen, ahol néha át kell váltani a bitenkénti és a logikai műveletek között ugyanazon az adaton. Ha egy numerikus kifejezést konvertálni kell logikai értékre, csak a teszt elvégzése érdekében, akkor zavaros lenne. a kódot.

    Ilyeneket írhat:

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

    helyett

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

    Egy elkülönített példában nem is olyan rossz, de ennek elvégzése kellemetlen lesz.

    Hasonlóképpen, társalogjon a műveletekkel. Egy logikai művelet eredményéhez hasznos, mint egy összehasonlítás, csak 0 vagy 1 előállítása: Tegyük fel, hogy néhány szó harmadik bitjét annak alapján szeretnénk beállítani, hogy modemctrl rendelkezik a hordozó érzékelő bitjével:

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

    Itt meg kell adnunk a != 0, a kétirányú & kifejezés eredményének csökkentésére 0 vagy 1, de mivel az eredmény csak egy egész szám, megkíméljük attól, hogy néhány bosszantó szereplőt kelljen hozzáadnunk a logikai érték egész számgá történő további konvertálásához.

    Annak ellenére, hogy a modern C id = “3b09aa4254”>

    típusú, még mindig megőrzi az ilyen kód érvényességét, mind azért, mert “jó dolog, mind az ellenkező esetben kompatibilis, hatalmas visszalépés miatt.

    Egy másik példa, ahol C csúszós: két logikai feltétel tesztelése négyirányú kapcsolóként:

    Ezt harc nélkül nem vehette el a C programozótól!

    Végül a C néha szolgál amolyan magas szintű összeszerelő nyelvként. Az összeállítási nyelvekben szintén nincsenek logikai típusaink. A logikai érték csak egy bit vagy nulla vagy nulla érték egy memóriahelyen vagy regiszterben. Az egész nullát, a logikai értéket és a null címet ugyanúgy tesztelik az összeállítási nyelv utasításkészleteiben (és talán még lebegőpontos nullát is). A C és az összeállítási nyelv közötti hasonlóság hasznos, például amikor a C-t célnyelvként használják egy másik nyelv összeállításához (méghozzá olyanhoz, amely erősen beírta a logikai értékeket!)

    Válasz

    A logikai vagy igazságértéknek csak 2 értéke van. Igaz és hamis.

    Ezeket nem egész számként, hanem bitként (0 és 1) kell ábrázolni. ).

    Bármely más egész szám 0 vagy 1 melletti mondása nem hamis, zavaros állítás. Az igazságtáblák igazságértékekkel foglalkoznak, nem egész számokkal.

    A prospektív igazságértékből -1 vagy 2 megszakítaná az összes igazságtáblát és minden hozzájuk kapcsolódó logikai logikát.

    • 0 ÉS -1 ==?!
    • 0 VAGY 2 ==?!

    A legtöbb nyelv általában boolean típus, amely számtípusra (például egész számra) vetve hamis értéket mutat, és 0 egész értékként kell leadni.

    Megjegyzések

    • 0 ÉS -1 == bármilyen logikai értékre vetíti őket. ‘ ez az, amiről a kérdésem szól, miért vetik őket TRUE vagy FALSE.Soha nem mondtam – talán tettem is, de nem szándékoltam – az egész számok igazak vagy hamisak voltak, azt kérdeztem, miért értékelnek akármelyiket, ha logikai értékre vetik őket.

    Válasz

    Végül arról beszél, hogy az alapnyelvet meg kell bontani, mert egyes API-k gagyiak. A gagyi API-k nem új keletűek, és a nyelv törésével nem lehet őket kijavítani. Matematikai tény, hogy 0 hamis és 1 igaz, és minden nyelv, amely ezt nem tartja tiszteletben, alapvetően megszakad. A háromirányú összehasonlítás hiányos, és nincs vállalkozása, amelynek eredménye implicit módon átalakul bool vé, mivel három lehetséges eredményt ad vissza. A régi C API-k egyszerűen szörnyű hibakezeléssel rendelkeznek, és azért is vannak akadályozva, mert a C-nek nincsenek meg a szükséges nyelvi tulajdonságai ahhoz, hogy ne legyenek szörnyű felületei.

    Ne feledje, hogy nem azoknál a nyelveknél mondom, amelyeknek nincs implicit egész-> logikai átalakítás.

    Megjegyzések

    • ” Matematikai tény, hogy a 0 hamis és az 1 igaz ” Erm.
    • Tudna-e hivatkozni ” matematikai tényére, hogy a 0 hamis és 1 igaz “? Válaszod veszedelmesen hangzik, mint egy röhögés.
    • ‘ nem matematikai tény, de ‘ század óta matematikai konvenció.
    • A Boole algebrát egy véges mező képviseli, amelyben 0 és 1 az additonra és a szorzásra hasonlító műveletek azonosságelemei. Ezek a műveletek rendre OR vagy AND. Valójában a logikai algebra hasonlóan van írva, mint a normál algebra, ahol a szembeállítás az AND-t, a + szimbólum az OR-t jelöli. Tehát például a abc + a'b'c jelentése: (a and b and c) or (a and (not b) and (not c)).

    Vélemény, hozzászólás?

    Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük