2017-09-30 3 views
1

Wenn vor kurzem in einem Stück Code suchen, stieß ich auf eine Linie, die mir zu denken hatte:Kann das Produkt zweier positiver Schwimmer negativ sein?

if a*b > 0: 
    # do stuff 

Es wird angenommen werden, dass a und b Schwimmer sind.

Frage:
Ist es möglich, dass es existiert (sehr klein, positiv, und wahrscheinlich nahe an ~ eps_mach) Werte von a und b so dass ihr Produkt negativ ist? Wenn nicht, könnte es sein, dass wir a*b==0 weder a==0 noch b==0 haben.

keine vollständige slouch sein, hier sind meine Gedanken:

  1. Nein, es ist möglich, da in FP das Produkt arithmetische wahrscheinlich so definiert ist, dass die Vorzeichenbits von a und b bestimmen Sie das Vorzeichenbit von a*b. Daher läuft die Berechnung auf einer Basisebene "Das Vorzeichenbit von a ist positiv. Das Vorzeichenbit von b ist positiv. Setze das Vorzeichenbit von a*b auf positiv." Ich stelle mir vor, diese Konvention ist spezifiziert und universell irgendwo vorausgesetzt, es existiert.

  2. Die a*b==0 mit a!=0 und b!=0 scheint sicherlich möglich.

  3. Die Antwort wird computerabhängig und sprachabhängig sein.

Dies führt mich zu einer Teilfrage:

Frage:
Wäre es sicherer sein, den Code wie unten zu implementieren? Wenn es nicht sicherer ist, wie sollte es dann gemacht werden?

if (a>0 and b>0) or (a<0 and b<0): 
    # do stuff 
+0

@old_timer Warum würden Sie eine NaN eher als positive Unendlichkeit erwarten? –

+0

@old_timer IEEE754 fordert die Unendlichkeit, ebenso wie die Java-Sprachspezifikation. Andere Sprachen mögen etwas Seltsames tun, aber ich würde generell Unendlichkeit erwarten. Es macht einen Unterschied, denn NaN> 0 ist wie alle NaN-Vergleiche falsch. –

+0

Ich lösche meine Kommentare. –

Antwort

2

Unter dem IEEE-754-Standard (mit Standardrundungsmodus), wobei das Ergebnis jeder Operation Gleitkomma- (bla bla Transzendentalien) zur nächsten darstellbaren Zahl gerundet ist. Das Produkt von zwei beliebigen positiven Zahlen ist positiv, so dass im schlechtesten Fall die nächstliegende darstellbare Zahl Null ist. Es gibt keine Möglichkeit, dass die nächste darstellbare Zahl negativ ist.

Ihr vorgeschlagener alternativer Code ist korrekt. Für Sprachen mit einer sgn/signum Funktion können Sie auch etwas wie if sgn(a)*sgn(b) > 0 tun.

+0

Ausgezeichnet! Vielen Dank. – floater

3

Die beiden Teile des Codes sind nicht gleichwertig, weil das Produkt von zwei positiven aber winzigen Zahlen tatsächlich Null sein kann.

Welches ist richtig hängt davon ab, was der Test wirklich ist.

Wenn der nachfolgende Code das Produkt streng positiv verwenden muss, benötigen Sie das Formular a*b > 0, nicht die einzelnen Werte.

Wenn jeder Wert streng positiv sein muss, testen Sie dies.

Der Test, den Sie vorschlagen, ist korrekt, wenn die Anforderung lautet, dass beide nicht null sind und das gleiche Vorzeichen haben.

Hier ist ein Java-Programm, das einige der Fälle prüft, darunter sowohl kleine, aber streng positiv:

public class Test { 
    public static void main(String[] args) { 
    testit(Double.MIN_VALUE, Double.MIN_VALUE); 
    testit(-Double.MIN_VALUE, -Double.MIN_VALUE); 
    testit(1e-320, 1e-320); 
    testit(1e300, 1e300); 
    } 

    public static void testit(double a, double b) { 
    System.out.println("a="+a+" b="+b); 
    System.out.println("a*b > 0 " + (a * b > 0)); 
    System.out.println("(a>0 && b>0) " + (a > 0 && b > 0)); 
    System.out.println("(a<0 && b<0) " + (a < 0 && b < 0)); 
    System.out.println(); 
    } 
} 
+0

Ah, ja. Ein Schluckauf in meiner Frage. Der erste Test, den ich aufgelistet habe, war eine "Abkürzung", um festzustellen, ob genau eines von a oder b negativ ist. Es kam mir als gefährlich in den Sinn, was jetzt bestätigt wurde. – floater

Verwandte Themen