2015-06-29 23 views
18

Assumere a, b, c, e d sono dichiarati double (o float). Le seguenti espressioni sono sempre vere?Sono disuguaglianze galleggiante garantiti per essere coerenti

! ((a >= b) && (c <= d)) || ((a-c) >= (b-d)) 

! ((a > b) && (c <= d)) || ((a-c) > (b-d)) 

! ((a >= b) && (c < d)) || ((a-c) > (b-d)) 

C'è alcuna garanzia dalla IEEE 754 o la corrente C o C++ standard? E qualsiasi compilatore lo ottimizzerà come semplicemente vero in fase di compilazione? Sono interessato principalmente ai valori normali, non tanto ai valori subnormali o speciali.

A me sembra che ciò dipenda dagli errori di arrotondamento durante la sottrazione.

+0

"qualsiasi compilatore ottimizzerà questo come semplicemente vero in fase di compilazione" - perché non lo provi? –

+2

@ 101010 "quando' a! = B' anche i loro bit di rappresentazione sono diversi "- errato. (+0 e -0, NaN, ecc.) –

+0

Il compilatore può conoscere i valori di a, b, c e d in fase di compilazione? –

risposta

10

Per la 3a a produrre falsi dovrebbe essere sufficiente per prendere il gran uguale a e b e piccole ineguale c e d, ad esempio a=1e30, b=1e30, c=1e-31, d=1e-30.

EDIT: Ok, per il secondo per produrre falso, per analogia al 3, dovrebbe essere sufficiente per tenere piccola disuguale a e b e grandi uguali c e d, ad esempio a=1e-30, b=1e-31, c=1e30, d = 1e30.

Nessuna idea di un controesempio per la prima espressione ...

+1

A destra, solo il numero uno sta in piedi. –

+0

Sospetto che non sia possibile scegliere valori che rendono # 1 falso. –

+4

Impostazione di abc e d su + Infinity restituisce false per # 1 [demo] (http://ideone.com/oXmPXP), anche se suppongo che ciò non contenga perché è un valore "speciale" – samgak

7

Serge Rogatch dato controesempi per la seconda e terza espressioni.

Il primo, !(a >= b && c <= d) || a-c >= b-d, è sempre vero in IEEE 754 aritmetica, se a, b, c e d devono tutti essere finito. La sottrazione di numeri finiti non può produrre un NaN. Quindi un controesempio deve soddisfare a >= b && c <= d && a-c < b-d. Tuttavia, a >= b implica che a-c >= b-c, qualsiasi sia c e c <= d implichi che b-c >= b-d, qualunque sia . La transitività di >= si prende cura di tutto il resto.

Si può prendere a = c = 1.0/0.0 e prendere scelte arbitrarie di b e d per un controesempio se ti rilassi la condizione che a, b, c e d devono tutti essere finito. Tutti i controesempi sono essenzialmente di questa forma.

+0

"Tuttavia, a> = b implica che a-c> = b-c, qualunque sia c, e c <= d implica che b-c> = b-d, qualunque sia b." - Come possiamo essere sicuri che questa ipotesi sia vera? –

+0

@temple: se a e b sono finiti, c può essere -oo, finito o oo. Se c è -oo, allora a-c == oo e b-c = oo. Se c è oo, allora a - c = -oo e b - c = -oo. Se c è finito, quindi, prima di arrotondare, a-c> = b-c. Arrotondamenti> =. – tmyklebu

Problemi correlati