Попытка умножения с переполнением

Раст в панике: попытка умножения с переполнением

Я пытаюсь составить полином для алгоритма шифрования AES. fn new() предназначен для построения бит-векторного представления числа x. любого поля galois_field, чтобы использовать его для сложения и умножения Extension_field (из алгоритма AES).

#[derive(Debug)]
struct polynomial(Vec<u8>);

impl polynomial {
    fn new(mut x: i16) -> Self {
        println!("polynomial::new() --> Start");

        let mut poly: Vec<u8> = Vec::new();

        for e in 0..16 {
            poly.push(0);
        }

        for e in (0..16).rev() {
            println!("polynomial::new() :: loop :: --> In ");

            if x > 0 {
                if x - 2_i16.pow(e) >= 2_i16.pow(e - 1) || x - 2_i16.pow(e) == 0 {
                    x -= 2_i16.pow(e);
                    poly[e as usize] = 1;
                }
            } else {
                if x - 1 == 0 {
                    poly[e as usize] = 1;
                    println!("x : {x}");
                    println!("polynomial : {poly:#?}");
                }
            }
        }

        println!("polynomial::new() --> End");
        return Self(poly);
    }
}

fn main() {
    let x = polynomial::new(7);
    let y = polynomial::new(41);

    let z = polynomial::add(x, y);
    println!("z : {z:#?}");
}

Когда я запускаю код, я знаю, что ошибка возникает во втором println! макросе, но я не знаю, в каком if операторе. Это вывод во время выполнения:

polynomial::new() --> Start
polynomial::new() :: loop :: --> In 
thread 'main' panicked at /usr/src/debug/rust/rustc-1.78.0-src/library/core/src/num/mod.rs:324:5:
attempt to multiply with overflow

Я понятия не имею, почему это происходит. Хотел поставить RUST_BACKTRACE = 1 но не знаю как.

Просто в командной строке RUST_BACKTRACE=1 запустите груз или какой бы двоичный файл вы ни запускали, приятель. Что будет делать. Вы используете груз? Однако я не вижу функции добавления. в полиномическом следует использовать заглавную букву (Полиномиальный). Молодцы с AES!

Daniel Mortara 07.06.2024 04:31

Подсказка: каков результат 2**16? Какое самое большое число i16 может храниться?

Chayim Friedman 07.06.2024 04:38

добавляя к приведенному выше предложению, имейте в виду, что если e равно 0, то 2_i16 будет 2_i16(-1), что должно равняться 0,5. следовательно, int не может с этим справиться, так существует ли тип данных, который может с этим справиться?

Titoot 07.06.2024 04:48

@ChayimFriedman, я понимаю, что вы имеете в виду, но я не понимаю, почему максимальный бит i16 равен «2_i16.pow(14)» вместо «2_i16.pow(15)»

Rust Coder 07.06.2024 14:22

@Titoot, спасибо за указание, правильное if должно быть «if e > 0».

Rust Coder 07.06.2024 15:26

1 бит на знак, еще 1 бит на ведущую 1, затем остается 14 бит.

Chayim Friedman 08.06.2024 21:59
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
6
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На самом деле решение было очень простым. Мне нужно было только изменить примитивные значения на i32 и не позволять им переполнять максимальное значение u16.

fn new(mut x: i32) -> Result<Self, ()> {
    if x > std::u16::MAX.into() {
        println!("x must be equal or lower than u16::MAX");
        return Err(());
    }

    let mut poly: Vec<u8> = Vec::new();

    for e in 0..16 {
        poly.push(0);
    }

    for e in (0..16).rev() {
       if x - 2_i32.pow(e) > -1 {
          x -= 2_i32.pow(e);
          poly[e as usize] = 1;
       }
    }

Другие вопросы по теме