static NumberKind GetBestFloatKind(NumberKind k1, NumberKind k2) { var kSize = k1.BitSize(Semantics); if (kSize == 64) { return(NumberKind.Double); } else if (kSize == 32) { return(NumberKind.Float); } else { if (k1 == NumberKind.Real || k2 == NumberKind.Real) { return(NumberKind.Real); } else { return(NumberKind.Quad); } } }
static NumberKind OperationKind(NumberKind k1, NumberKind k2, bool unsignedWins = false) { if (k1.IsInteger()) { if (k2.IsInteger()) { var sameSignedness = (k1.IsSigned() && k2.IsSigned()) || (k1.IsUnsigned() && k2.IsUnsigned()); if (sameSignedness) { var minKSize = Semantics.DefaultKind.BitSize(Semantics); var k1Size = k1.BitSize(Semantics); var k2Size = k2.BitSize(Semantics); if (k1Size < minKSize && k2Size < minKSize) { if (k1.IsSigned()) { return(Semantics.DefaultKind.Signed()); } else { return(Semantics.DefaultKind.Unsigned()); } } else { var kSize = Math.Max(k1Size, k2Size); if (kSize == k1Size) { return(k1); } else { return(k2); } } } else { if (unsignedWins) { k1 = k1.Unsigned(); k2 = k2.Unsigned(); } else { k1 = k1.Signed(); k2 = k2.Signed(); } var minKSize = Semantics.DefaultKind.BitSize(Semantics); var k1Size = k1.BitSize(Semantics); var k2Size = k2.BitSize(Semantics); if (k1Size < minKSize && k2Size < minKSize) { if (k1.IsSigned()) { return(Semantics.DefaultKind.Signed()); } else { return(Semantics.DefaultKind.Unsigned()); } } else { var kSize = Math.Max(k1Size, k2Size); if (kSize == k1Size) { return(k1); } else { return(k2); } } } } else { return(k2); } } else { if (k2.IsInteger()) { return(k1); } else { var k1Size = k1.BitSize(Semantics); var k2Size = k2.BitSize(Semantics); if (k1Size == k2Size) { if (k1 == k2) { return(k1); } else { return(GetBestFloatKind(k1, k2)); } } else { var biggest = Math.Max(k1Size, k2Size); return(biggest == k1Size ? k1 : k2); } } } }