Es gibt keinen Fall, in dem hier eine Division durch Null stattfinden kann.
Der SMT Solver Z3 unterstützt präzise IEEE-Gleitkomma-Arithmetik. Lassen Sie uns Z3 bitten, Zahlen zu finden a
und b
so, dass a != b && (a - b) == 0
:
(set-info :status unknown)
(set-logic QF_FP)
(declare-fun b () (FloatingPoint 8 24))
(declare-fun a () (FloatingPoint 8 24))
(declare-fun rm () RoundingMode)
(assert
(and (not (fp.eq a b)) (fp.eq (fp.sub rm a b) +zero) true))
(check-sat)
Das Ergebnis ist UNSAT
. Es gibt keine solchen Nummern.
Mit der obigen SMTLIB-Zeichenfolge kann Z3 auch einen beliebigen Rundungsmodus auswählen ( rm
). Dies bedeutet, dass das Ergebnis für alle möglichen Rundungsmodi gilt (von denen es fünf gibt). Das Ergebnis beinhaltet auch die Möglichkeit, dass eine der im Spiel befindlichen Variablen NaN
unendlich ist.
a == b
wird als fp.eq
Qualität so implementiert +0f
und -0f
gleich vergleichen. Der Vergleich mit Null wird ebenfalls mit implementiert fp.eq
. Da die Frage darauf abzielt, eine Division durch Null zu vermeiden, ist dies der geeignete Vergleich.
Wenn der Gleichheitstest wurde mit bitweise Gleichheit, umgesetzt +0f
und -0f
ein Weg gewesen wäre , um a - b
Null. Eine falsche Vorgängerversion dieser Antwort enthält Modendetails zu diesem Fall für Neugierige.
Z3 Online unterstützt die FPA-Theorie noch nicht. Dieses Ergebnis wurde unter Verwendung des neuesten instabilen Zweigs erhalten. Es kann mit den .NET-Bindungen wie folgt reproduziert werden:
var fpSort = context.MkFPSort32();
var aExpr = (FPExpr)context.MkConst("a", fpSort);
var bExpr = (FPExpr)context.MkConst("b", fpSort);
var rmExpr = (FPRMExpr)context.MkConst("rm", context.MkFPRoundingModeSort());
var fpZero = context.MkFP(0f, fpSort);
var subExpr = context.MkFPSub(rmExpr, aExpr, bExpr);
var constraintExpr = context.MkAnd(
context.MkNot(context.MkFPEq(aExpr, bExpr)),
context.MkFPEq(subExpr, fpZero),
context.MkTrue()
);
var smtlibString = context.BenchmarkToSMTString(null, "QF_FP", null, null, new BoolExpr[0], constraintExpr);
var solver = context.MkSimpleSolver();
solver.Assert(constraintExpr);
var status = solver.Check();
Console.WriteLine(status);
Mit Z3 IEEE Float Fragen zu beantworten ist schön , weil es schwer ist , Fälle zu übersehen (wie NaN
, -0f
, +-inf
) und Sie können beliebige Fragen stellen. Keine Notwendigkeit, Spezifikationen zu interpretieren und zu zitieren. Sie können sogar gemischte Float- und Integer-Fragen stellen, z. B. "Ist dieser bestimmte int log2(float)
Algorithmus korrekt?".