C++ Paritätsbit Aufgaben hilfe?
Hi,
ich brächte mal hilfe und zwar habe ich seit 5 wochen in der schule Programmieren. Dazu hat mir mein Lehrer die Aufgabe erstellt eine Dezimal Zahl als erstes in Binär zu übersetzen und dann die Parrität zu vergleichen. Mein Lehrer erklärt leider nicht viel deswegen verstehe ich die erste For Schleife nicht ganz. Wenn mir die Jemand erklären kann wäre das gut. Dazu funktioniert das so noch nicht da wenn ich 445 als zahl eingebe die zahl als 32 bit wie folgt ausgegeben wird:
0000 0000 0000 0000 0000 0001 1011 1101 = Zahl in 32bit binär
Even Even Even Even = Parität
Aber es müsste raus kommen in der Parität spalte
Even Even Odd Even
Dies wäre soweit mein Lösungsansatz.
#include <iostream>
#include <cstdlib>
int i;
int a;
int bits[sizeof(int)*8];
unsigned int unum;
int num;
int main (int nargs, char **args) {
num=atoi(args[1]);
unum = (unsigned int)num;
for(int i=0; i<sizeof(int)*8; i++) {
bits[i]=unum % 2;
unum /=2;
}
if(bits[1,2,3,4] == bits[5,6,7,8]) {
std::cout << "Even\n";
} else {
std::cout << "Odd\n";
}
if(bits[9,10,11,12] == bits[13,14,15,16]) {
std::cout << "Even\n";
} else {
std::cout << "Odd\n";
}
if(bits[17,18,19,20] == bits [21,22,23,24]) {
std::cout << "Even\n";
} else {
std::cout << "Odd\n";
}
if(bits[25,26,27,28] == bits[29,30,31,32]) {
std::cout << "Even\n";
} else {
std::cout << "Odd\n";
}
return 0;
}
2 Antworten
Ich habe gerade nochmal - einfach aus Sport - eine Template-Funktion geschrieben, welche die Parität entweder als konstanten Ausdruck oder auf Wunsch auch zur Laufzeit von einem beliebigen vorzeichen-behafteten oder -losen Ganzzahltypen berechnet:
#include <ios> // boolalpha
#include <iostream> // cout, endl
#include <limits> // numeric_limits
#include <type_traits> // is_integral, is_signed
#include <cstdlib> // size_t
template <typename INT>
constexpr bool parity(const INT n) noexcept {
using namespace ::std;
static_assert(is_integral<INT>());
using UINT = make_unsigned_t<INT>;
using limits = numeric_limits<UINT>;
static_assert(2 == limits::radix);
constexpr size_t bits { limits::digits };
UINT par { static_cast<UINT>(n) };
for (size_t i { bits >> 1 }; i; i >>= 1) {
par ^= par >> i;
}
return par & 1;
}
int main() {
using namespace ::std;
cout << boolalpha;
const long l = 0b0101;
cout << parity(l) << endl;
const int i = 0b1011;
cout << parity(i) << endl;
const short s = 0b1001;
cout << parity(s) << endl;
const char c = 0b0100;
cout << parity(s) << endl;
}
Die Funktion dürfte im Schnitt maximal-effizient sein und hat eine Laufzeitkomplexität von O(1) mit exakt log2(sizeof(INT)) durchläufen, also praktisch 5 "Faltungen" bei einem 32 Bit Integer.
Um den Code übersetzen zu können, ist aber ein C++17 Compiler notwendig.
Wie gesagt, das war jetzt nur Sport, weil "KarlRanseierIII" in seiner Antwort etwas von "aufgehübschter" und "lesbarer" geschrieben hat. Darunter verstehe ich als C++ler "effizienter" und "portabler", was mich soz. getriggert hat. ;)
Der Fragensteller kann meinen Template-Code getrost ignorieren! Das ist noch ganz weit von dem jetzigen Kenntnisstand entfernt. Aber weil ich das jetzt sowieso geschrieben hatte, kann ich es auch gleich hier veröffentlichen. :)
Oh, aber eine sehr schicke Idee! Ist dann zwar nicht mehr constexpr und wesentlich langsamer, aber dafür ein schön kompakter Einzeiler! :)
Wobei ich aber hoffe, daß count() auch faltet, und in O(log_2(bitlen)) arbeitet. Es bleibt natürlich etwas langsamer, aber wenn die STL-Implementierer nicht geschlampt haben, hält sich die Verlangsamung in Grenzen.
Trotzdem ist natürlich die Ausdrucksfähigkeit des Einzelers ziemlich charmant, das hat man oft bei der STL, auch wenn das Ergebnis nicht immer das effizienteste ist. Nehmen wir mal einen string s an:
palindrom=(s==std::string(s.rbegin(),s.rend()))
Effizienter wäre nur den halben String zu prüfen, aber noch knapper ohne Schleifen etc. geht es AFAIK nicht mehr.
- also keine Byte-weise Parität, sondern Nibble-weise Parität (wobei ich mit Nibble die untere (Low-Nibble) oder die obere (High-Nibble) Hälfte eines Bytes meine)? das wäre ja ungewöhnlich... bist dir sicher?
- ansonsten benutzt man lieber die XOR-Funktion...
- also:
for(int i=1; i<sizeof(int)*2; i++)
num ^= num>>(i*4);
std::cout << (num&0xF) << endl;
In der Schleife wird Modulo und Division genutzt, also denke ich mal, dass der Fragensteller noch nicht bereit für Bitschubsereien ist. :)
Wie geschrieben erst seit 4 wochen Programmieren als sind wir noch nicht sehr weit und das ist alles was ich mir ausdenken konnte^^
mit den booleschen Operationen fing bei uns Wochen-lang die eine Vorlesung an... ich konnt nich mehr vor Lachen... besonders weil der eine US-amerikanisch angehauchte Kommilitone jedenfalls so tat, als ob er sich veralbert vorkam (die US-Studis haben angeblich keine Vorlesung in der Form... sondern n Lehrbuch und dann Übungen, die vom Prof persönlich betreut werden...)... kicher
LOL
was soll eigentlich bei „bits[1,2,3,4]“ rauskommen? die Bits 1, 2, 3 und 4? das geht so nich... *gacker* da kommt wohl eher das Bit-Nr. 1 raus... wenn es sich überhaupt compilieren lässt... :)
Der Ausdruck "bits[0,1,2,3]" ist durchaus korrektes C++ und entspricht "bits[3]". Die Indizes vor den Kommaoperatoren werden hierbei einfach verworfen.
Das ist in diesem Falle zwar eine total sinnlose Sache, aber der Kommaoperator hat durchaus seine Gründe zu existieren. :)
Compilen lässt sich das unter GNU schon sonst hätte ich den code so nichtmal hier reingeschrieben.
Vielen dank aber leider ist das für mich noch zu hoch und ich brauche noch für den anfang einen längeren code aber dafür für mich einfacheren.
Klar gibt es immer einfacher wege etwas zu schreiben aber da ich kompletter anfänger bin hilft mir das nicht ganz weiter falls du deinen Code noch auseinander nehmen würdest und mir schrit für schritt erklären würdest dann wäre dies sehr hilfreich für die zukunft fall ich soetwas wieder brauche was sehr wahrscheinlich ist.
erklär du doch erstmal, was du eigentlich unter „Parität“ verstehst... LOL
Was soll das falls du lesen kannst habe ich seit Fucking 4 wochen Programmieren im Berufskollge da lernt man sowas noch nicht nicht und nein keine Ahnung da uns dies auch nicht weiter erklärt wurde schön für dich das du alles so toll kannst aber wenn du nicht weiter helfen willst. Dann kannst du auch was anderes machen. Danke das du eine Antwort hinterlassen hast aber es bringt mir nichts wenn ich diese nicht verstehe. Und dann einfach so übernehme oder????
Wobei ich natürlich auch ein std::bitset<32>(val).count()&1 machen kann.
*pfeif*
(Es wäre nur halt keine gute Übung :-P)