Tidak ada kasus di mana pembagian dengan nol dapat terjadi di sini.
The SMT Solver Z3 mendukung IEEE tepat aritmatika floating point. Mari kita minta Z3 untuk menemukan angka a
dan b
sedemikian rupa sehingga 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)
Hasilnya adalah UNSAT
. Tidak ada angka seperti itu.
String SMTLIB di atas juga memungkinkan Z3 untuk memilih mode pembulatan sewenang-wenang ( rm
). Ini berarti bahwa hasilnya berlaku untuk semua mode pembulatan yang mungkin (yang ada lima). Hasilnya juga mencakup kemungkinan bahwa salah satu variabel dalam permainan mungkin NaN
atau tidak terbatas.
a == b
diimplementasikan sebagai fp.eq
kualitas sehingga +0f
dan -0f
membandingkan sama. Perbandingan dengan nol diimplementasikan menggunakan fp.eq
juga. Karena pertanyaannya ditujukan untuk menghindari pembagian dengan nol, ini adalah perbandingan yang tepat.
Jika tes kesetaraan diimplementasikan menggunakan persamaan bitwise, +0f
dan -0f
akan menjadi cara untuk membuat a - b
nol. Versi sebelumnya yang salah dari jawaban ini berisi detail mode tentang kasus itu untuk yang penasaran.
Z3 Online belum mendukung teori FPA. Hasil ini diperoleh dengan menggunakan cabang tidak stabil terbaru. Itu dapat direproduksi menggunakan .NET bindings sebagai berikut:
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);
Menggunakan Z3 untuk menjawab pertanyaan mengambang IEEE bagus karena sulit untuk mengabaikan kasus-kasus (seperti NaN
, -0f
, +-inf
) dan Anda dapat mengajukan pertanyaan yang sewenang-wenang. Tidak perlu menafsirkan dan mengutip spesifikasi. Anda bahkan dapat mengajukan pertanyaan campuran mengambang dan bilangan bulat seperti "apakah int log2(float)
algoritma khusus ini benar?".