• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Edo

Divisão por zero

7 mensagens neste tópico

Estava eu a submeter este programa

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <vector>
using namespace std;

int main() {
    ofstream fout("gift1.out");
    ifstream fin("gift1.in");

    int number_persons;
    fin >> number_persons;
    std::map<string, int> person_money;
    std::vector<string> persons;
    string current_person;
    while(number_persons--) {
        fin >> current_person;
        person_money[current_person] = 0;
        persons.push_back(current_person);
    }
    int money_given, nr_gifts;
    while(fin >> current_person) {
        fin >> money_given >> nr_gifts;
        person_money[current_person] -= money_given;
        person_money[current_person] += money_given % nr_gifts;
        int to_credit = money_given / nr_gifts;
        while(nr_gifts--) {
            fin >> current_person;
            person_money[current_person] += to_credit;
        }
    }
    
    for(size_t i = 0; i < persons.size(); ++i)
        fout << persons[i] << " " << person_money[persons[i]] << endl;
    return 0;
}

ao Greedy Gift Givers da USACO e vejo que ele não passa num teste. Testo no meu computador e tudo corre lindamente e a solução obtida é a correcta. A questão é como é que o programa não explodiu durante a execução quando fez divisões por zero?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Hmm... a única explicação que encontro é que o programa não fez divisões por zero.

Tens a certeza que "gift1.in" contem dados que permitam atribuir o valor 0 a nr_gifts?

já agora qual é o compilador?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tens a certeza que "gift1.in" contem dados que permitam atribuir o valor 0 a nr_gifts?

Segundo o enunciado isso pode acontecer. Edo, é estranho que funcione no teu pc, qual é o input? Já viste a página com dicas quando essa situação acontece?

O enunciado pode ser visto aqui

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O meu compilador é gcc version 4.0.1 (Apple Inc. build 5484) e o Processador um G5.

Um programa compilado neste computador com o código int a = 0; int c = 2/a; não dá erro nenhum 0.0

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ok. Penso que está explicado então. Não conheço os macintosh ainda. Estou em vias de comprar o meu primeiro este natal. O teu post estava a deixar-me muito curioso e cheguei realmente a colocar a dada a altura a hipótese de estares a utilizar outro sistema que não um PC.

Portanto...

A divisão de inteiros por zero resulta em Undefined Behavior per o ISO C++ Standard IEC 14882-2003(E) §5.6.4, pág. 86. Basicamente o compilador é livre de fazer o que quizer. Em muitos casos não faz nada, e deixa ser o hardware a decidir. É o caso nos PCs com os compiladores que conheço (Visual C++ e GCC) onde o compilador segue em frente e é o CPU que atira uma exception.

If the second operand of / or % is zero the behavior is undefined; otherwise (a/:cheesygrin:*b + a%b is equal to a.

Aparentemente no caso do teu GCC, o compilador coloca o resultado a zero (duvido que seja o hardware a fazê-lo. Mas é irrelevante). É realmente uma opção deveras questionável. Mas o standard é claro neste sentido, portanto tecnicamente não existem soluções erradas. Para todos os efeitos, o compilador poderia por o computador a tocar o Hino Nacional e ainda assim seria correcto uma vez que o comportamento é declarado como undefined.

É sempre necessário quando não tens controle sobre o input, mas aparentemente nos Macintosh checar as tuas divisões por zero tomam uma importância ainda maior.

EDIT: Já agora, uma pequena nota. Se os valores forem constantes, então o compilador apanha realmente o erro e penso que mesmo no teu caso não deixará passar uma vez que este já é um erro de construção de código. A não ser que compiles com -Wno-div-by-zero.

EDIT2: Notei agora... dá mesmo 0.0? Um floating point? Pôxa...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem testei com estes dois porgramas:

#include <stdio.h>
#include <stdarg.h>

int main (int argc, char const *argv[])
{
   int a = 0;
   int b = 2 / a;
   printf("%d\n", b);
   return 0;
}

#include <stdio.h>
#include <stdarg.h>

int main (int argc, char const *argv[])
{
   double a = 0;
   double b = (2.0 / a);
   printf("%f\n", b);
   return 0;
}

Compilei ambos sem flags. O promeiro imprimiu 0 e o segundo inf. Nunca tinha posto em duvida que o hardware devia lançar uma excepção em caso de divisão por zero por isso é que fiquei muito surpreendido.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

É, mas está tudo bem. Não te preocupes.

Já sabes o que tens a fazer.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora