Wie stelle ich sicher, dass `1 << n` als 256-Bit-Operation ausgeführt wird?

Mit anderen Worten, wie stelle ich sicher, dass 1 << nfür nicht überläuft n < 256?

Derzeit verwende ich uint256(1) << n.

Gibt es einen besseren Weg oder ist garantiert, dass der Ausdruck uint256(1)während der Kompilierung durch einen konstanten Wert ersetzt (und nicht zur Laufzeit berechnet) wird?

Danke schön.

Antworten (2)

Laut der Solidity-Dokumentation bleibt im Fall von 1<<n, willkürlich genau, bis es in nicht wörtliche Typen konvertiert wird, also sollten Sie in Ordnung sein.1

Literale Zahlenausdrücke behalten eine beliebige Genauigkeit, bis sie in einen nicht-literalen Typ konvertiert werden (dh indem sie zusammen mit einem nicht-literalen Ausdruck verwendet werden). Das bedeutet, dass Berechnungen nicht überlaufen und Divisionen in zahlenliteralen Ausdrücken nicht abgeschnitten werden.

[1] http://solidity.readthedocs.io/en/develop/types.html

Nun, das ist lustig, ich habe beobachtet, dass ein simples 1 << nkonsequent abgeschnitten wird, lange bevor nes 256 erreicht (ich habe nicht genau überprüft, wann, aber ich habe vermutet, dass es bei überläuft n == 8, weil es 1in ein passt uint8).
Tatsächlich ist hier eine Warnung von Remix, wenn versucht wird, 1 << nvon einer Funktion zurückzukehren, die Folgendes zurückgibt uint256: "Warnung: Das Ergebnis der Verschiebung hat den Typ uint8 und könnte daher überlaufen. Stillen Sie diese Warnung, indem Sie das Literal in den erwarteten Typ konvertieren.".

Konstanten im Quellcode können mit Typen umgewandelt werden, die die geringste Genauigkeit bieten, die den Wert unterstützen. Das kann zu Ärger führen. Unerwartete implizite Umwandlung im Exponentialoperator von Solidity

Sie können diese Art von Problemen vermeiden, indem Sie sie explizit mit hoher Präzision werfen.

Halten.

if(uint(1) < n) {}

Ich hoffe es hilft.