¿Cómo me aseguro de que `1 << n` se ejecute como una operación de 256 bits?

En otras palabras, ¿cómo me aseguro de que 1 << nno se desborde n < 256?

Actualmente, estoy usando uint256(1) << n.

¿Hay una mejor manera, o se garantiza que la expresión uint256(1)se reemplaza con un valor constante durante la compilación (y no se calcula durante el tiempo de ejecución)?

Gracias.

Respuestas (2)

De acuerdo con la documentación de Solidity, en el caso de 1<<n, 1seguirá siendo arbitrariamente preciso hasta que se convierta en tipos no literales, por lo que debería estar bien.

Las expresiones literales numéricas retienen una precisión arbitraria hasta que se convierten a un tipo no literal (es decir, usándolas junto con una expresión no literal). Esto significa que los cálculos no se desbordan y las divisiones no se truncan en expresiones numéricas literales.

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

Bueno, eso es divertido, he observado que un simple 1 << nse trunca constantemente mucho antes de nllegar a 256 (no verifiqué cuándo, pero supuse que se desborda en n == 8, debido al hecho de que 1cabe en a uint8).
De hecho, aquí hay una advertencia de Remix, cuando intenta regresar 1 << nde una función que devuelve uint256: "Advertencia: el resultado del cambio tiene el tipo uint8 y, por lo tanto, podría desbordarse. Silencie esta advertencia convirtiendo el literal al tipo esperado".

Las constantes en el código fuente se pueden convertir con tipos que ofrezcan la menor precisión que admitirá el valor. Eso puede llevar a problemas. Conversión implícita inesperada en el operador exponencial de Solidity

Puede evitar ese tipo de problemas al lanzarlos explícitamente con alta precisión.

Considerar.

if(uint(1) < n) {}

Espero eso ayude.