public void TestReciprocal(byte color, byte alpha) { var rcpa = FixedMathCC8.ToReciprocalByte(FixedMathCC8.FromByte(alpha)); var final = FixedMathCC8.ToByte(FixedMathCC8.FromByte(color), rcpa); Assert.AreEqual(color, final); }
public void TestDivMul() { for (uint i = 1; i < 256; ++i) { var ifp = i / 255f; for (uint j = 1; j < 256; ++j) { var jfp = j / 255f; // references var dddd = Math.Min(1, ifp / jfp); // var mref = (uint)((ifp * jfp) * 255f); // var dref = (uint)( dddd * 255f); var mref = (uint)Math.Round((ifp * jfp) * 255f); var dref = (uint)Math.Round(dddd * 255f); Assert.Less(mref, 256); Assert.Less(dref, 256); TestContext.WriteLine($"{i}x{j} = {mref}"); TestContext.WriteLine($"{i}/{j} = {dref}"); // slow var mval0 = (i * j) / 255; var dval0 = Math.Min(255, (i * 255) / j); Assert.Less(dval0, 256); Assert.AreEqual(mref, mval0, 1); Assert.AreEqual(dref, dval0, 1); // expanded 65535 const uint U16 = 65535; var i16 = FixedMathCC8.From255To65535(i); var j16 = FixedMathCC8.From255To65535(j); var mval1 = (i16 * j16) >> 16; var dval1 = Math.Min(U16, (i16 * U16) / j16); mval1 = FixedMathCC8.From65535To255(mval1); dval1 = FixedMathCC8.From65535To255(dval1); Assert.AreEqual(mref, mval1, 1); Assert.AreEqual(dref, dval1, 1); // reciprocal 65535 var rj15 = Math.Min(U16, (U16 * U16) / j16); var dval2 = (i16 * rj15) >> 16; // expanded to 4095 const uint U12 = (1 << 12) - 1; var i12 = FixedMathCC8.FromByte(i); var j12 = FixedMathCC8.FromByte(j); var mval4 = (i12 * j12) >> 12; var dval4 = Math.Min(U12, (i12 * U12) / j12); mval4 = FixedMathCC8.ToByte(mval4); dval4 = FixedMathCC8.ToByte(dval4); Assert.AreEqual(mref, mval4, 1); Assert.AreEqual(dref, dval4, 1); // reciprocal direct to 255 (12+12+8) var rj12 = FixedMathCC8.ToReciprocalByte(j12); dval4 = FixedMathCC8.ToByte(i12, rj12); Assert.AreEqual(dref, dval4, 1); } } }