Как убедиться, что `1 << n` выполняется как 256-битная операция?

Другими словами, как мне убедиться, что 1 << nfor не переполняется n < 256?

В настоящее время я использую uint256(1) << n.

Есть ли лучший способ, или гарантируется, что выражение uint256(1)будет заменено постоянным значением во время компиляции (а не вычислено во время выполнения)?

Спасибо.

Ответы (2)

Согласно документации Solidity, в случае 1<<n, 1останется произвольно точным, пока не будет преобразовано в нелитеральные типы, поэтому все должно быть в порядке.

Числовые литеральные выражения сохраняют произвольную точность до тех пор, пока они не будут преобразованы в нелитеральный тип (т. е. при использовании их вместе с нелитеральным выражением). Это означает, что вычисления не переполняются, а деления не усекаются в числовых литеральных выражениях.

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

Что ж, забавно, я заметил, что простое 1 << nпоследовательно усекается задолго до того, как nдостигает 256 (не совсем проверял, когда, но я предположил, что оно переполняется в n == 8, из-за того, что он 1помещается в uint8).
На самом деле, вот предупреждение от Remix при попытке возврата 1 << nиз функции, которая возвращает uint256: «Предупреждение: результат сдвига имеет тип uint8 и, следовательно, может переполниться. Заглушите это предупреждение, преобразовав литерал в ожидаемый тип».

Константы в исходном коде могут быть приведены к типам, предлагающим наименьшую точность, которая будет поддерживать значение. Это может привести к неприятностям. Неожиданное неявное приведение в экспоненциальном операторе Solidity

Вы можете избежать подобных проблем, явно приведя их с высокой точностью.

Учитывать.

if(uint(1) < n) {}

Надеюсь, поможет.