Hallo C#-Nutzer
Ich komme von C++11 und bin noch neu in der C#-Welt.
Mein Anliegen ist folgendes:
Ich muss in einem Software-Projekt für mein Studium die einzelnen Nibblets (4 Bit Blöcke) eines UInt32-Integers gezielt auslesen und schreiben können.
Zum auslesen benutze ich folgende Methode:
using System.Globalization;
...
/// <summary>
/// Extracts a nibble from a larger number.
/// </summary>
/// <typeparam name="T">Any integer type.</typeparam>
/// <param name="t">The value to extract nibble from</param>
/// <param name="nibblePos">The nibble position,
/// where 0 is the last significant nibble</param>
/// <returns>The extracted nibble.</returns>
private byte GetNibble<T>(this T t, int nibblePos) where T : struct, IConvertible
{
nibblePos *= 4;
var value = t.ToUInt32(CultureInfo.CurrentCulture);
return (byte)((value >> nibblePos) & 0xF);
}
Jetzt brauche ich noch das Gegenstück zum setzen der einzelnen Nibblets.
Wie müsste das aussehen?
An dieser Stelle schon mal Danke für eure Hilfe.
ZaHaDum1984
Hallo ZaHaDum1984,
wo hängt es genau?
Denn deine Hausaufgaben sind für dich da und wir machen sie dir nicht! (siehe [Hinweis] Wie poste ich richtig? Punkt 4 und 4.2)
Hallo ZaHaDum1984,
wo hängt es genau?
Das Problem ist, dass das Byte, also 8 Bits, die kleinste adressierbare Speichereinheit ist.
Beim Auslesen macht das keine Probleme, da ich da das signifikantere Nibblet ignorieren kann. Aber beim setzen mit Bit-Shifting bedeutet das doch, dass ich immer 8 Bits des Integers ändere und eben nicht nur 4 Bits. Folglich würde ich doch immer mein Ziel-Nibblet und das nächste Nibblet ändern.
Oder sehe ich da s falsch?
Naja ein Nibblet hat ja einen dezimal Wert von 0...15.
Wenn du sicherstellst, dass der übergebene Wert in diesen Grenzen liegt, änderst du nur 1 Nibblet.
EDIT: Wertebereich angepasst. 😁
@ZaHaDum1984:
Schon in C11 war das nicht so wie du glaubst.
Auch da muss natürlich das "alte" byte genommen, das entsprechende andere nibble "gesichert" und dann zusammengefügt werden.
Das das in structs von der C Syntax gemacht wird, hat nichts damit zu tun das der Prozessor es nicht anders kann.
Also anderes nibble per & 0xF0 oder 0x0F "sichern, und dann zusammenführen.
Hey,
Nibble clearen und mit neuem Wert verodern:
var clearmask = ~(0xF << nibblePos);
value = (value && clearmask) || (nibble << nibblePos);
beste Grüße
zommi
Naja ein Nibblet hat ja einen dezimal Wert von 0...15.
Wenn du sicherstellst, dass der übergebene Wert in diesen Grenzen liegt, änderst du nur 1 Nibblet.
Das ist bereits sichergestellt.
Also würde das folgende Nibblet dann nicht mit 0000 überschrieben werden?
Es kommt natürlich drauf an, wie du schreibst.
Wenn du knallhart das Byte setzen willst, geht das natürlich schief.
Wenn du es machst wie zommi es gezeigt hat, dann nicht.
Hey,
Nibble clearen und mit neuem Wert verodern:var clearmask = ~(0xF << nibblePos); value = (value && clearmask) || (nibble << nibblePos);
Bei dieser Lösung gibt es noch Probleme mit den Datentypen.
private UInt32 SetNibble<T>(T t, byte newNibble, int nibblePos) where T : struct, IConvertible
{
nibblePos *= 4;
var value = t.ToUInt32(CultureInfo.CurrentCulture);
var clearmask = ~(0xF << nibblePos);
return (UInt32)((value && clearmask) || (newNibble << nibblePos));
}
Fehlermeldung:
Operator '&&' cannot be applied to operands of type 'uint' and 'int'
Oh ja, hehe: && und || sind logisch, & und | sind bitweise.
Edit: ... und was mir gerade noch so auffällt:
Übersehe ich was oder macht die generische Methode eigentlich keinen Sinn, da du ja eh in einen UInt32 castest?!
Oh ja, hehe: && und || sind logisch, & und | sind bitweise.
Stimmt ja, manchmal sehe ich wirklich den Wald vor lauter Bäumen nicht. 😁
Allerdings bekomme ich jetzt, statt der Fehlermeldung, folgende Warnung vom Compiler:
Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first
Ich bin mir nicht ganz sicher ob ich diese Warnung in meinem Fall ignorieren kann, oder nicht.
Nachtrag: Diese Warnung erscheint nur bei einem Rebuild der Solution.
Nach einem anschließenden Build, ist sie verschwunden. 🤔