Состояние до и после из книги Страуструпа

В главе 5.10.1 "Программирование: принципы и практика с использованием C++" есть упражнение "Попробуйте это" для отладки неправильного ввода области. Предварительными условиями являются, если входные данные для длины и ширины равны 0 или отрицательны, в то время как постусловие проверяет, является ли область 0 или отрицательной. Чтобы процитировать проблему: "Найдите пару значений, чтобы предварительное условие этой версии области выполнялось, а постусловие - нет". Код на данный момент:

#include <iostream>
#include "std_lib_facilities.h"

int area (int length, int width) {
    if (length <= 0 || width <= 0) { error("area() pre-condition"); }
    int a =  length * width;
    if(a <= 0) { error("area() post-condition"); }
    return a;
}

int main() {

int a;
int b;
while (std::cin >> a >> b) {
    std::cout << area(a, b) << '\n';
}

system("pause");
return 0;
}

В то время как код, кажется, работает, я не могу обернуть голову, какие входные данные получат предварительное условие для успеха, но вызовут постусловие. До сих пор я пытался вводить строки в один из входов, но это просто завершает программу, и пытался найти ascii, эквивалентный 0, но результат тот же. Это должен быть какой-то хитрый вопрос или я что-то упустил?

3 ответа

Решение

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

Числа, которые при умножении вызывают переполнение со знаком, могут привести к тому, что значение будет отрицательным и, несомненно, приведет к тому, что результат будет неправильным.

То, какие значения вызывают целочисленное переполнение, будет зависеть от вашей архитектуры и компилятора, но суть в том, что умножение двух 4-байтовых целых приведет к 8-байтовому значению, которое не может быть сохранено в 4-байтовом целом числе.

Я попробовал это, и кажется, что это работает: area(1000000,1000000);

Выход был: -727379968

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