2011-09-12 13 views
9

Sto cercando una semplice spiegazione per come funziona modulo operandi di Ruby e perché, in Rubyoperando modulo in Ruby rispetto a PHP

puts 4 % 3 # 1 
puts -4 % 3 # 2 <--why? 
puts -4 % -3 # -1 

ma in PHP:

<?php 

echo 4 % 3; # 1 
echo -4 % 3; # -1 
echo -4 % -3; # -1 

Sembra a me come -4% 3 è actally 8% 3 (8 è la differenza tra 4 e -4).

+3

Il comportamento di X% Y, dove X o Y sono negativi è una scelta di progettazione (che può essere "indefinito comportamento"). Niente di più, niente di meno. Questa sezione su [divisione intera] (http://www.davidflanagan.com/2006/06/integer-division-and-negative-numbers.html) e i commenti possono portare a ulteriori approfondimenti. IIRC la ragione di questo "comportamento strano" in Ruby è discussa sulla ML. –

+1

Se Ruby fa le cose in un modo, e PHP fa le cose un altro, supponi che Ruby stia facendo nel modo giusto! j/k –

risposta

15

Entrambi possono essere considerati corretti, a seconda della definizione. Se a % n == r, allora dovrebbe ritenere che:

a == q*n + r 

dove q == a/n.

Se r è positivo o negativo è determinato dal valore di q. Quindi nel tuo esempio, uno di:

-4 == -1*3 + (-1) // PHP 
-4 == -2*3 + 2  // Ruby 

Per dirla in altro modo, la definizione di % dipende dalla definizione di /.

Vedere anche la tabella qui: http://en.wikipedia.org/wiki/Modulus_operator#Remainder_calculation_for_the_modulo_operation. Vedrai che questo varia in modo sostanziale tra i vari linguaggi di programmazione.

+1

Ah, questo mi ha fatto fare clic: "la definizione di% dipende dalla definizione di /". Grazie! – typeoneerror

-1

Secondo Wolfram Alpha, 2 è corretto.

modifica: Sembra che dovresti chiederti perché PHP funziona in questo modo?

edit2: PHP lo definisce come il resto della deviazione A/B. Suppongo che sia per te un errore, un errore o un modo diverso di fare le cose. Personalmente, vado per il primo 2.

+1

Sto chiedendo la differenza, non quale sia corretta, quindi suppongo che sto chiedendo perché PHP funziona in questo modo. qualche idea? – typeoneerror

+3

@Kyle: non è né un bug né sbagliato. –

6

Here's a snippet sul tema da The Ruby Programming Language, di Matz e David Flanagan.

Quando uno (ma non entrambi) degli operandi è negativo, rubino esegue la divisione intera e modulo operazioni diverso rispetto linguaggi come C, C++, e Java fare (ma lo stesso delle lingue Python e Tcl). Considera il quoziente -7/3. Ruby arrotonda verso l'infinito negativo e restituisce -3. C e le lingue correlate ruotano invece verso lo zero e return -2. In Ruby, -a/b è uguale a/-b ma non è uguale a (a/b).

La definizione di Ruby del funzionamento del modulo differisce anche da quella di C e Java. In Ruby, -7% 3 è 2. In C e Java, il risultato è -1 . La grandezza del risultato è diversa, poiché il quoziente è diverso. Ma anche il segno del risultato è diverso. In Ruby, il segno del risultato è sempre il segno del secondo operando. In C e Java, il segno del risultato è sempre il segno del primo operando. (metodo resto del rubino comporta come l'operatore C modulo.)

1

si riduce effettivamente giù per l'attuazione del linguaggio intero colata/raccordo.Poiché l'equazione reale è:

a - (n * int(a/n)) 

È la porzione int(a/n) dell'equazione che differisce. Se a == -4 e n == 3, PHP restituirà -1, mentre Ruby produrrà -2. Ora l'equazione si presenta così in Ruby:

-4 - (3 * -2) 

e questo in PHP

-4 - (3 * -1) 
Problemi correlati