ComicSansMS / GhulbusMath

@@ -59,6 +59,16 @@
Loading
59 59
        return denom;
60 60
    }
61 61
62 +
    template<typename F, typename = std::enable_if_t<std::is_floating_point_v<F>>>
63 +
    explicit constexpr operator F() const noexcept {
64 +
        return static_cast<F>(numerator()) / static_cast<F>(denominator());
65 +
    }
66 +
67 +
    friend constexpr bool isValid(Rational<T> const& r) noexcept
68 +
    {
69 +
        return r.denominator() != 0;
70 +
    }
71 +
62 72
    friend constexpr bool isInteger(Rational<T> const& r) noexcept
63 73
    {
64 74
        return r.denominator() == 1;

@@ -1,4 +1,4 @@
Loading
1 -
#include <gbMath/Rational.hpp>
1 +
#include <gbMath/Rational.hpp>
2 2
#include <gbMath/RationalIO.hpp>
3 3
4 4
#include <catch.hpp>
@@ -73,11 +73,36 @@
Loading
73 73
            CHECK(r.numerator() == 1);
74 74
            CHECK(r.denominator() == 2);
75 75
        }
76 +
        {
77 +
            Rational<int> r(0, 1);
78 +
            CHECK(r.numerator() == 0);
79 +
            CHECK(r.denominator() == 1);
80 +
        }
81 +
        {
82 +
            Rational<int> r(0, 255);
83 +
            CHECK(r.numerator() == 0);
84 +
            CHECK(r.denominator() == 1);
85 +
        }
86 +
        {
87 +
            Rational<int> r(0, -255);
88 +
            CHECK(r.numerator() == 0);
89 +
            CHECK(r.denominator() == 1);
90 +
        }
76 91
        {
77 92
            Rational<int> r(255, 0);
78 93
            CHECK(r.numerator() == 1);
79 94
            CHECK(r.denominator() == 0);
80 95
        }
96 +
        {
97 +
            Rational<int> r(-1, 0);
98 +
            CHECK(r.numerator() == -1);
99 +
            CHECK(r.denominator() == 0);
100 +
        }
101 +
        {
102 +
            Rational<int> r(-255, 0);
103 +
            CHECK(r.numerator() == -1);
104 +
            CHECK(r.denominator() == 0);
105 +
        }
81 106
        {
82 107
            Rational<int> r(0, 0);
83 108
            CHECK(r.numerator() == 0);
@@ -85,6 +110,28 @@
Loading
85 110
        }
86 111
    }
87 112
113 +
    SECTION("Float conversion")
114 +
    {
115 +
        CHECK(static_cast<float>(Rational<int>(1, 2)) == 0.5f);
116 +
        CHECK(static_cast<float>(Rational<int>(1, 8)) == 0.125f);
117 +
        CHECK(static_cast<float>(Rational<int>(5, 8)) == 0.625f);
118 +
        CHECK(static_cast<float>(Rational<int>(1, 3)) == 1.f / 3.f);
119 +
        CHECK(static_cast<float>(Rational<int>(255, 256)) == 0.99609375f);
120 +
    }
121 +
122 +
    SECTION("Is Valid")
123 +
    {
124 +
        CHECK(isValid(Rational<int>(1, 2)));
125 +
        CHECK(isValid(Rational<int>(0, 1)));
126 +
        CHECK(isValid(Rational<int>(0, 5)));
127 +
        CHECK(isValid(Rational<int>(-1, 2)));
128 +
        CHECK_FALSE(isValid(Rational<int>(1, 0)));
129 +
        CHECK_FALSE(isValid(Rational<int>(-1, 0)));
130 +
        CHECK_FALSE(isValid(Rational<int>(100, 0)));
131 +
        CHECK_FALSE(isValid(Rational<int>(-100, 0)));
132 +
        CHECK_FALSE(isValid(Rational<int>(0, 0)));
133 +
    }
134 +
88 135
    SECTION("Is Integer")
89 136
    {
90 137
        CHECK(isInteger(Rational<int>(2, 1)));
@@ -692,4 +739,370 @@
Loading
692 739
            CHECK(r == Rational<int>(3, 8));
693 740
        }
694 741
    }
742 +
743 +
    SECTION("Div by Zero values propagate")
744 +
    {
745 +
        Rational<int> const divz(100, 0);       // ∞
746 +
        Rational<int> const ndivz(-100, 0);     // -∞
747 +
        Rational<int> const divzz(0, 0);        // nan
748 +
        REQUIRE(divz.numerator() == 1);
749 +
        REQUIRE(divz.denominator() == 0);
750 +
        REQUIRE(ndivz.numerator() == -1);
751 +
        REQUIRE(ndivz.denominator() == 0);
752 +
        REQUIRE(divzz.numerator() == 0);
753 +
        REQUIRE(divzz.denominator() == 0);
754 +
        SECTION("Float conversion")
755 +
        {
756 +
            CHECK(static_cast<float>(divz) == std::numeric_limits<float>::infinity());
757 +
            CHECK(static_cast<float>(ndivz) == -std::numeric_limits<float>::infinity());
758 +
            CHECK(std::isnan(static_cast<float>(divzz)));
759 +
760 +
            CHECK(static_cast<double>(divz) == std::numeric_limits<double>::infinity());
761 +
            CHECK(static_cast<double>(ndivz) == -std::numeric_limits<double>::infinity());
762 +
            CHECK(std::isnan(static_cast<double>(divzz)));
763 +
        }
764 +
        SECTION("Addition")
765 +
        {
766 +
            // ∞ + x = ∞
767 +
            CHECK(divz + Rational<int>(2, 3) == divz);
768 +
            CHECK(divz + Rational<int>(-1, 3) == divz);
769 +
            CHECK(divz + Rational<int>(5, 2) == divz);
770 +
771 +
            CHECK(Rational<int>(2, 3) + divz == divz);
772 +
            CHECK(Rational<int>(-1, 3) + divz == divz);
773 +
            CHECK(Rational<int>(5, 2) + divz == divz);
774 +
775 +
            CHECK(ndivz + Rational<int>(2, 3) == ndivz);
776 +
            CHECK(ndivz + Rational<int>(-1, 3) == ndivz);
777 +
            CHECK(ndivz + Rational<int>(5, 2) == ndivz);
778 +
779 +
            CHECK(Rational<int>(2, 3) + ndivz == ndivz);
780 +
            CHECK(Rational<int>(-1, 3) + ndivz == ndivz);
781 +
            CHECK(Rational<int>(5, 2) + ndivz == ndivz);
782 +
783 +
            CHECK(divzz + Rational<int>(2, 3) == divzz);
784 +
            CHECK(divzz + Rational<int>(-1, 3) == divzz);
785 +
            CHECK(divzz + Rational<int>(5, 2) == divzz);
786 +
787 +
            CHECK(Rational<int>(2, 3) + divzz == divzz);
788 +
            CHECK(Rational<int>(-1, 3) + divzz == divzz);
789 +
            CHECK(Rational<int>(5, 2) + divzz == divzz);
790 +
        }
791 +
        SECTION("Member Addition")
792 +
        {
793 +
            Rational<int> r = divz;
794 +
            r += Rational<int>(2, 3);
795 +
            REQUIRE(r == divz);
796 +
            r += Rational<int>(-1, 3);
797 +
            REQUIRE(r == divz);
798 +
            r += Rational<int>(5, 2);
799 +
            REQUIRE(r == divz);
800 +
801 +
            r = Rational<int>(2, 3);
802 +
            r += divz;
803 +
            CHECK(r == divz);
804 +
            r = Rational<int>(-1, 3);
805 +
            r += divz;
806 +
            CHECK(r == divz);
807 +
            r = Rational<int>(5, 2);
808 +
            r += divz;
809 +
            CHECK(r == divz);
810 +
811 +
            r = ndivz;
812 +
            r += Rational<int>(2, 3);
813 +
            REQUIRE(r == ndivz);
814 +
            r += Rational<int>(-1, 3);
815 +
            REQUIRE(r == ndivz);
816 +
            r += Rational<int>(5, 2);
817 +
            REQUIRE(r == ndivz);
818 +
819 +
            r = Rational<int>(2, 3);
820 +
            r += ndivz;
821 +
            CHECK(r == ndivz);
822 +
            r = Rational<int>(-1, 3);
823 +
            r += ndivz;
824 +
            CHECK(r == ndivz);
825 +
            r = Rational<int>(5, 2);
826 +
            r += ndivz;
827 +
            CHECK(r == ndivz);
828 +
829 +
            r = divzz;
830 +
            r += Rational<int>(2, 3);
831 +
            REQUIRE(r == divzz);
832 +
            r += Rational<int>(-1, 3);
833 +
            REQUIRE(r == divzz);
834 +
            r += Rational<int>(5, 2);
835 +
            REQUIRE(r == divzz);
836 +
837 +
            r = Rational<int>(2, 3);
838 +
            r += divzz;
839 +
            CHECK(r == divzz);
840 +
            r = Rational<int>(-1, 3);
841 +
            r += divzz;
842 +
            CHECK(r == divzz);
843 +
            r = Rational<int>(5, 2);
844 +
            r += divzz;
845 +
            CHECK(r == divzz);
846 +
        }
847 +
        SECTION("Subtraction")
848 +
        {
849 +
            // ∞ - x = ∞
850 +
            // x - ∞ = -∞
851 +
            CHECK(divz - Rational<int>(2, 3) == divz);
852 +
            CHECK(divz - Rational<int>(-1, 3) == divz);
853 +
            CHECK(divz - Rational<int>(5, 2) == divz);
854 +
855 +
            CHECK(Rational<int>(2, 3) - divz == ndivz);
856 +
            CHECK(Rational<int>(-1, 3) - divz == ndivz);
857 +
            CHECK(Rational<int>(5, 2) - divz == ndivz);
858 +
859 +
            CHECK(ndivz - Rational<int>(2, 3) == ndivz);
860 +
            CHECK(ndivz - Rational<int>(-1, 3) == ndivz);
861 +
            CHECK(ndivz - Rational<int>(5, 2) == ndivz);
862 +
863 +
            CHECK(Rational<int>(2, 3) - ndivz == divz);
864 +
            CHECK(Rational<int>(-1, 3) - ndivz == divz);
865 +
            CHECK(Rational<int>(5, 2) - ndivz == divz);
866 +
867 +
            CHECK(divzz - Rational<int>(2, 3) == divzz);
868 +
            CHECK(divzz - Rational<int>(-1, 3) == divzz);
869 +
            CHECK(divzz - Rational<int>(5, 2) == divzz);
870 +
871 +
            CHECK(Rational<int>(2, 3) - divzz == divzz);
872 +
            CHECK(Rational<int>(-1, 3) - divzz == divzz);
873 +
            CHECK(Rational<int>(5, 2) - divzz == divzz);
874 +
        }
875 +
        SECTION("Member Subtraction")
876 +
        {
877 +
            Rational<int> r = divz;
878 +
            r -= Rational<int>(2, 3);
879 +
            REQUIRE(r == divz);
880 +
            r -= Rational<int>(-1, 3);
881 +
            REQUIRE(r == divz);
882 +
            r -= Rational<int>(5, 2);
883 +
            REQUIRE(r == divz);
884 +
885 +
            r = Rational<int>(2, 3);
886 +
            r -= divz;
887 +
            CHECK(r == ndivz);
888 +
            r = Rational<int>(-1, 3);
889 +
            r -= divz;
890 +
            CHECK(r == ndivz);
891 +
            r = Rational<int>(5, 2);
892 +
            r -= divz;
893 +
            CHECK(r == ndivz);
894 +
895 +
            r = ndivz;
896 +
            r -= Rational<int>(2, 3);
897 +
            REQUIRE(r == ndivz);
898 +
            r -= Rational<int>(-1, 3);
899 +
            REQUIRE(r == ndivz);
900 +
            r -= Rational<int>(5, 2);
901 +
            REQUIRE(r == ndivz);
902 +
903 +
            r = Rational<int>(2, 3);
904 +
            r -= ndivz;
905 +
            CHECK(r == divz);
906 +
            r = Rational<int>(-1, 3);
907 +
            r -= ndivz;
908 +
            CHECK(r == divz);
909 +
            r = Rational<int>(5, 2);
910 +
            r -= ndivz;
911 +
            CHECK(r == divz);
912 +
913 +
            r = divzz;
914 +
            r -= Rational<int>(2, 3);
915 +
            REQUIRE(r == divzz);
916 +
            r -= Rational<int>(-1, 3);
917 +
            REQUIRE(r == divzz);
918 +
            r -= Rational<int>(5, 2);
919 +
            REQUIRE(r == divzz);
920 +
921 +
            r = Rational<int>(2, 3);
922 +
            r -= divzz;
923 +
            CHECK(r == divzz);
924 +
            r = Rational<int>(-1, 3);
925 +
            r -= divzz;
926 +
            CHECK(r == divzz);
927 +
            r = Rational<int>(5, 2);
928 +
            r -= divzz;
929 +
            CHECK(r == divzz);
930 +
        }
931 +
        SECTION("Multiplication")
932 +
        {
933 +
            // ∞ * x = ∞
934 +
            // ∞ * -x = -∞
935 +
            CHECK(divz * Rational<int>(2, 3) == divz);
936 +
            CHECK(divz * Rational<int>(-1, 3) == ndivz);
937 +
            CHECK(divz * Rational<int>(5, 2) == divz);
938 +
939 +
            CHECK(Rational<int>(2, 3) * divz == divz);
940 +
            CHECK(Rational<int>(-1, 3) * divz == ndivz);
941 +
            CHECK(Rational<int>(5, 2) * divz == divz);
942 +
943 +
            CHECK(ndivz * Rational<int>(2, 3) == ndivz);
944 +
            CHECK(ndivz * Rational<int>(-1, 3) == divz);
945 +
            CHECK(ndivz * Rational<int>(5, 2) == ndivz);
946 +
947 +
            CHECK(Rational<int>(2, 3) * ndivz == ndivz);
948 +
            CHECK(Rational<int>(-1, 3) * ndivz == divz);
949 +
            CHECK(Rational<int>(5, 2) * ndivz == ndivz);
950 +
951 +
            CHECK(divzz * Rational<int>(2, 3) == divzz);
952 +
            CHECK(divzz * Rational<int>(-1, 3) == divzz);
953 +
            CHECK(divzz * Rational<int>(5, 2) == divzz);
954 +
955 +
            CHECK(Rational<int>(2, 3) * divzz == divzz);
956 +
            CHECK(Rational<int>(-1, 3) * divzz == divzz);
957 +
            CHECK(Rational<int>(5, 2) * divzz == divzz);
958 +
        }
959 +
        SECTION("Member Multiplication")
960 +
        {
961 +
            Rational<int> r = divz;
962 +
            r *= Rational<int>(2, 3);
963 +
            REQUIRE(r == divz);
964 +
            r *= Rational<int>(-1, 3);
965 +
            REQUIRE(r == ndivz);
966 +
            r = divz;
967 +
            r *= Rational<int>(5, 2);
968 +
            REQUIRE(r == divz);
969 +
970 +
            r = Rational<int>(2, 3);
971 +
            r *= divz;
972 +
            CHECK(r == divz);
973 +
            r = Rational<int>(-1, 3);
974 +
            r *= divz;
975 +
            CHECK(r == ndivz);
976 +
            r = Rational<int>(5, 2);
977 +
            r *= divz;
978 +
            CHECK(r == divz);
979 +
980 +
            r = ndivz;
981 +
            r *= Rational<int>(2, 3);
982 +
            REQUIRE(r == ndivz);
983 +
            r *= Rational<int>(-1, 3);
984 +
            REQUIRE(r == divz);
985 +
            r = ndivz;
986 +
            r *= Rational<int>(5, 2);
987 +
            REQUIRE(r == ndivz);
988 +
989 +
            r = Rational<int>(2, 3);
990 +
            r *= ndivz;
991 +
            CHECK(r == ndivz);
992 +
            r = Rational<int>(-1, 3);
993 +
            r *= ndivz;
994 +
            CHECK(r == divz);
995 +
            r = Rational<int>(5, 2);
996 +
            r *= ndivz;
997 +
            CHECK(r == ndivz);
998 +
999 +
1000 +
            r = divzz;
1001 +
            r *= Rational<int>(2, 3);
1002 +
            REQUIRE(r == divzz);
1003 +
            r *= Rational<int>(-1, 3);
1004 +
            REQUIRE(r == divzz);
1005 +
            r *= Rational<int>(5, 2);
1006 +
            REQUIRE(r == divzz);
1007 +
1008 +
            r = Rational<int>(2, 3);
1009 +
            r *= divzz;
1010 +
            CHECK(r == divzz);
1011 +
            r = Rational<int>(-1, 3);
1012 +
            r *= divzz;
1013 +
            CHECK(r == divzz);
1014 +
            r = Rational<int>(5, 2);
1015 +
            r *= divzz;
1016 +
            CHECK(r == divzz);
1017 +
1018 +
        }
1019 +
        SECTION("Division")
1020 +
        {
1021 +
            // x / ∞ = 0
1022 +
            // ∞ / x = ∞
1023 +
            // ∞ / -x = -∞
1024 +
            CHECK(divz / Rational<int>(2, 3) == divz);
1025 +
            CHECK(divz / Rational<int>(-1, 3) == ndivz);
1026 +
            CHECK(divz / Rational<int>(5, 2) == divz);
1027 +
1028 +
            CHECK(Rational<int>(2, 3) / divz == Rational(0, 1));
1029 +
            CHECK(Rational<int>(-1, 3) / divz == Rational(0, 1));
1030 +
            CHECK(Rational<int>(5, 2) / divz == Rational(0, 1));
1031 +
1032 +
            CHECK(ndivz / Rational<int>(2, 3) == ndivz);
1033 +
            CHECK(ndivz / Rational<int>(-1, 3) == divz);
1034 +
            CHECK(ndivz / Rational<int>(5, 2) == ndivz);
1035 +
1036 +
            CHECK(Rational<int>(2, 3) / ndivz == Rational(0, 1));
1037 +
            CHECK(Rational<int>(-1, 3) / ndivz == Rational(0, 1));
1038 +
            CHECK(Rational<int>(5, 2) / ndivz == Rational(0, 1));
1039 +
1040 +
            CHECK(divzz / Rational<int>(2, 3) == divzz);
1041 +
            CHECK(divzz / Rational<int>(-1, 3) == divzz);
1042 +
            CHECK(divzz / Rational<int>(5, 2) == divzz);
1043 +
1044 +
            CHECK(Rational<int>(2, 3) / divzz == divzz);
1045 +
            CHECK(Rational<int>(-1, 3) / divzz == divzz);
1046 +
            CHECK(Rational<int>(5, 2) / divzz == divzz);
1047 +
        }
1048 +
        SECTION("Member Division")
1049 +
        {
1050 +
            Rational<int> r = divz;
1051 +
            r /= Rational<int>(2, 3);
1052 +
            REQUIRE(r == divz);
1053 +
            r /= Rational<int>(-1, 3);
1054 +
            REQUIRE(r == ndivz);
1055 +
            r = divz;
1056 +
            r /= Rational<int>(5, 2);
1057 +
            REQUIRE(r == divz);
1058 +
1059 +
            r = Rational<int>(2, 3);
1060 +
            r /= divz;
1061 +
            CHECK(r == Rational<int>(0, 1));
1062 +
            r = Rational<int>(-1, 3);
1063 +
            r /= divz;
1064 +
            CHECK(r == Rational<int>(0, 1));
1065 +
            r = Rational<int>(5, 2);
1066 +
            r /= divz;
1067 +
            CHECK(r == Rational<int>(0, 1));
1068 +
1069 +
            r = ndivz;
1070 +
            r /= Rational<int>(2, 3);
1071 +
            REQUIRE(r == ndivz);
1072 +
            r /= Rational<int>(-1, 3);
1073 +
            REQUIRE(r == divz);
1074 +
            r = ndivz;
1075 +
            r /= Rational<int>(5, 2);
1076 +
            REQUIRE(r == ndivz);
1077 +
1078 +
            r = Rational<int>(2, 3);
1079 +
            r /= ndivz;
1080 +
            CHECK(r == Rational<int>(0, 1));
1081 +
            r = Rational<int>(-1, 3);
1082 +
            r /= ndivz;
1083 +
            CHECK(r == Rational<int>(0, 1));
1084 +
            r = Rational<int>(5, 2);
1085 +
            r /= ndivz;
1086 +
            CHECK(r == Rational<int>(0, 1));
1087 +
1088 +
1089 +
            r = divzz;
1090 +
            r /= Rational<int>(2, 3);
1091 +
            REQUIRE(r == divzz);
1092 +
            r /= Rational<int>(-1, 3);
1093 +
            REQUIRE(r == divzz);
1094 +
            r /= Rational<int>(5, 2);
1095 +
            REQUIRE(r == divzz);
1096 +
1097 +
            r = Rational<int>(2, 3);
1098 +
            r /= divzz;
1099 +
            CHECK(r == divzz);
1100 +
            r = Rational<int>(-1, 3);
1101 +
            r /= divzz;
1102 +
            CHECK(r == divzz);
1103 +
            r = Rational<int>(5, 2);
1104 +
            r /= divzz;
1105 +
            CHECK(r == divzz);
1106 +
        }
1107 +
    }
695 1108
}
Files Coverage
include/gbMath 100.00%
test 100.00%
Project Totals (53 files) 100.00%

No yaml found.

Create your codecov.yml to customize your Codecov experience

Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading