3 / 2 = 1 ? Definitivamente, está errado!
March 26th, 2005
Bem, eu estou vivendo no ano de 2005. Linguagens novas surgem diariamente e, a maioria insiste no erro. 3 / 2 não é igual a 1 e sim igual a 3/2. Acho que aprendi isto no primário.
Infelizmente, muitas linguagens acham que devem deixar as coisas erradas pois outras também estão erradas. Para linguagens que possuem tipos de dados estáticos, até existe uma certa tolerância. Mas acho que já está na hora das linguagens dinâmicas mudarem a filosofia. Em Ruby, por exemplo, uma variável que possui um valor inteiro, dependendo das operações, poderá ser promovida a um tipo inteiro gigante (Bignum) automaticamente.
Mas porque a divisão de dois inteiros não gera automaticamente um número racional? Em Ruby, a situação pode ser facilmente contornada utilizando-se:
require ‘mathn’.
De qualquer forma, eu acharia mais interessante se a linguagem provesse o processo automaticamente. Da mesma forma, uma linguagem acusar um erro quando o usuário pretende extrair a raiz quadrada de um número negativo, está errado. :-)
Frescuras? Sim. Até que a gente entra em contato. Primeiro causa uma sensação de segurança. Depois vira uma necessidade. Mas se Lisp, Smalltalk, Factor, etc possuem estas facilidades, acho que seria bem interessante Ruby prover (ou será que já está previsto?).
Depois vejo se existe alguma RCR por lá.
Atualização:
http://rcrchive.net/rcr/show/260
O Gavin Sinclair solicitou a implementação de racionais como uma classe da linguagem. Não fala nada em conversão direta, mas eu já votei. ( garanto que ninguém sabe qual foi o meu voto ;-)
http://rcrchive.net/rcr/show/195
Implementação em C dos números complexos como uma classe do Ruby. Também já tem o meu voto. Mas pô, a RCR é de 17 de janeiro de 2004 e ainda não foi feito nada? Ah, depende da RCR 194. Ok. Já votei também. :-)
Acho que fiz a minha parte. Se eu fosse um ‘expert’ em C eu mandava a solução também.
Entry Filed under: Ruby
7 Comments
1. Rider of the storm | March 27th, 2005 at 12:51 pm
Se voce raciocinar como no “mundo real” 3/2=1 pode estar correto, por exemplo :
Se voce tem 3 computadores para dividir para 2 pessoas (de preferencia eu e meu filho :-) voce só poderá distribuir 1 para cada, seria impossivel transformar o resultado em algo “racional”, se optasse pela solução de ‘dividir’ o computador que sobrou, por outro lado se ao invés dos computadores voce tivesse maçãs ou bananas, ai sim, uma faca solucionaria o problema! :-)
2. Guaracy Monteiro | March 27th, 2005 at 3:46 pm
Nope. Se tens 2 computadores e queres dividir para três pessoas (tu, o teu filho e a tua esposa), então 2 / 3 = 0. Não tem computador para ninguém, melhor procurar outra atividade. :-)
O problema foi a operação aplicada. 2 / 3 = 2/3 (não é possível mudar a matemática). Bem, também pode ser 0,666666….. (o que não irá alterar a situação, apenas torná-la mais imprecisa).
Se não é possível cortar, outras operações deveriam ser utilizadas (’mod’, ‘divmod’, ‘modulo’, %, etc, dependendo da linguagem) bem como decisões deveriam ser tomadas (if’s).
No primeiro caso, cada pessoa pode utilizar um computador e sobra um (3.divmod(2) => [1,1]). No segundo caso, 2 pessoas podem utilizar um computador e uma vai assistir TV.
Mas como é uma caso de RealLife ™, bastaria comprar outro ou permitir que um seja utilizado por duas pessoas simultâneamente (tanto o Linux como o Windows permitem colocar dois monitores e dois teclados em um micro; 1/2 micro por pessoa :-)
3. Rider of the storm | March 27th, 2005 at 4:13 pm
[Quote]Se tens 2 computadores e queres dividir para três pessoas (tu, o teu filho e a tua esposa), então 2 / 3 = 0. Não tem computador para ninguém, melhor procurar outra atividade. :-)[/Quote]
Embora eu nada saiba de Ruby, näo é isto que acontece na linguagem? se não for então já vejo uma incoerencia, se 3/2=1 (objeto do meu comentário) então, necessariamente, 2/3=0, isto se a linguagem tiver “tipagem forte”, claro que poderia se optar por gerar uma msg de erro, mas não vejo como um “furo” a opcao de autor. Dividir inteiros e ter como resultado um outro tipo (float ou seja la como se queira chamar) é meio estranho! não sei qual foi o “pensamento” do cara para ter escolhido a opcao de 3/2=1 e 3/2=0 (se é que seja assim!) mas talvez ele possa ter pensado algo do tipo “Se quisermos manter os tipos originais então 3/2=1 porque é possivel um resutado do mesmo tipo (o mais coerente seria 1), o mesmo aconteceria com 2/3=0 porque o único resultado do mesmo tipo seria o ‘0′” E o que aconteceira se fosse 3.0/2.0 ou 2.0/3.0 ai penso que seguindo esta “filosofia” seria possivel um “float” como resultado.
4. Rider of the storm | March 27th, 2005 at 4:51 pm
… ter escolhido a opcao de 3/2=1 e 3/2=0 (se é que seja assim!)
Leia-se
… ter escolhido a opcao de 3/2=1 e *2/3=0* (se é que seja assim!)
5. Guaracy Monteiro | March 27th, 2005 at 6:23 pm
> Embora eu nada saiba de Ruby, näo é isto que acontece na linguagem?
Sim, e é o que eu acho que está errado.
> se não for então já vejo uma incoerencia, se 3/2=1 (objeto do meu
> comentário) então, necessariamente, 2/3=0, isto se a linguagem tiver
> “tipagem forte”, claro que poderia se optar por gerar uma msg de
Acho que não seria o caso ‘tipagem forte’ e sim ‘estática’ ou ‘dinâmica’. Abri uma excessão para os caso no meu comentário. No Delphi, que é estática, no momento que uma variável é definida como inteira, ela fica assim até o fim. Em Ruby e outras, as variáveis são dinâmicas, isto é, podem ter o tipo alterado durante o programa. Porém fica não pode ser classificada como ‘tipagem fraca’; Se uma variável possui um valor “23″ (string) e outra possui o valor 23 (fixnum), operação de soma envolvendo as duas causa um erro. Mas como não existem variáveis em Ruby, tudo é um objeto, é possível fazer algumas brincadeiras. Veja coerce em:
http://ruby-ptbr.rubyforge.org//index.php?sitesig=PT&page=PT_020_Artigos&subpage=PT_030_Bases
> erro, mas não vejo como um “furo” a opcao de autor. Dividir inteiros
> e ter como resultado um outro tipo (float ou seja la como se queira
> chamar) é meio estranho! não sei qual foi o “pensamento” do cara para
> ter escolhido a opcao de 3/2=1 e 3/2=0 (se é que seja assim!) mas
> talvez ele possa ter pensado algo do tipo “Se quisermos manter os
> tipos originais então 3/2=1 porque é possivel um resutado do mesmo
> tipo (o mais coerente seria 1), o mesmo aconteceria com 2/3=0 porque
> o único resultado do mesmo tipo seria o ‘0′” E o que aconteceira se
> fosse 3.0/2.0 ou 2.0/3.0 ai penso que seguindo esta “filosofia” seria
> possivel um “float” como resultado.
Para uma linguagem, o ‘tipo’ da variável não tem muito sentido. Mesmo em linguagens estáticas existe uma certa flexibilidade nas conversões (dividir um inteiro por um float, por exemplo) e até mesmo a conversão explicita (como conheces Delphi, sabes a diferença entre int(val) e trunc(val) ). No caso específico de Ruby, as conversões acontecen automaticamente.
(supondo-se um processador de 32bits)
a = 1_000_000
a.class => Fixnum (inteiro)
a = a * a
a.class => Bignum (em algumas linguagens ocorre um erro)
a = a * 1.0
a.class => Float
As conversões aconteceram automaticamente. Portanto, se a linguagem tiver tipos racionais e complexos, o mesmo deveria acontecer (o problema é que Ruby não prove estes dois tipos, o que me levou a votar na adoção).
(sqrt -45) => #C(0.0 6.7082038)
(/ 34 12) => 17/6
ok -45 sqrt .
#{ 0 6.708203932499369 }#
ok 45 sqrt .
6.708203932499369
ok 34 12 / .
17/6
ok 9887766554433221 9988776655443322 * .
98766691733395809125700199400162
No caso dos números complexos, a coisa é mais ‘complexa’. Acho que tirando algumas áreas, pouca gente utiliza na prática. Já os número racionais possuem uma utilidade bastante valiosa por eliminarem a imprecisão dos números de ponto flutuante no computador. Mas como eu falei: só depois de usar que a gente sente falta (mesmo que não seja realmente necessário)
6. Rider of the storm | March 27th, 2005 at 7:04 pm
Katso! vc tá me deixando curioso, assim vou ter que acabar instalando esta tal de ruby, é! mas como não haverá mesmo tempo para me dedicar, talvez vc possa matar minha curiosidade, como ficaria em ruby, estas 2 situacoes?
1)
a=3
b=2.0
a/b
2)
a=3.0
b=2
a/b
7. Guaracy Monteiro | March 27th, 2005 at 7:39 pm
Em ambas o resultado seria 1.5
Sempre é bom lembrar que em Ruby, “tudo” é objeto. Eu até poderia forçar um resultado inteiro utilizando div:
3.div(2.0) => 1
3.0.div(2) => 1 (reconheço que aqui ficou feio)
ps. como falei em “require ‘mathn’” que implementa a possibilidade de trabalhar com números racionais, mesmo a inclusão resultaria na conversão para Float nos dois casos que informaste. Apenas se os dois forem inteiros o resultado seria racional.