OSDN Git Service

Abs()の追加
authorkimikage <kimikage_ceo@hotmail.com>
Thu, 10 Nov 2011 11:18:56 +0000 (20:18 +0900)
committerkimikage <kimikage_ceo@hotmail.com>
Thu, 10 Nov 2011 11:18:56 +0000 (20:18 +0900)
Karinto/Numeric/Operator.cs
KarintoTest/NumericTest/OperatorTest.cs

index 44f789b..f5be42c 100755 (executable)
@@ -22,7 +22,18 @@ namespace Karinto.Numeric
         public static BinaryOperator Mul;\r
         public static BinaryOperator Div;\r
         public static UnaryOperator Neg;\r
+        public static UnaryOperator Abs;\r
+\r
+        /// <summary>\r
+        /// 加法単位元\r
+        /// </summary>\r
+        /// <remarks>Tが参照型の場合,Zeroに破壊的操作をしてはならない</remarks>\r
         public static T Zero;\r
+\r
+        /// <summary>\r
+        /// 乗法単位元\r
+        /// </summary>\r
+        /// <remarks>Tが参照型の場合,Oneに破壊的操作をしてはならない</remarks>\r
         public static T One;\r
 \r
         private static BinaryOperator invalidOp2 = \r
@@ -64,6 +75,7 @@ namespace Karinto.Numeric
                 {\r
                     return -number;\r
                 };\r
+                Operator<int>.Abs = Math.Abs;\r
                 return;\r
             }\r
             if (prototype is long)\r
@@ -90,6 +102,7 @@ namespace Karinto.Numeric
                 {\r
                     return -number;\r
                 };\r
+                Operator<long>.Abs = Math.Abs;\r
                 return;\r
             }\r
             if (prototype is decimal)\r
@@ -116,6 +129,7 @@ namespace Karinto.Numeric
                 {\r
                     return -number;\r
                 };\r
+                Operator<decimal>.Abs = Math.Abs;\r
                 return;\r
             }\r
             if (prototype is double)\r
@@ -142,6 +156,7 @@ namespace Karinto.Numeric
                 {\r
                     return -number;\r
                 };\r
+                Operator<double>.Abs = Math.Abs;\r
                 return;\r
             }\r
             if (prototype is float)\r
@@ -168,6 +183,7 @@ namespace Karinto.Numeric
                 {\r
                     return -number;\r
                 };\r
+                Operator<float>.Abs = Math.Abs;\r
                 return;\r
             }\r
             Add = invalidOp2;\r
@@ -178,6 +194,14 @@ namespace Karinto.Numeric
             {\r
                 return Sub(Zero, number);\r
             };\r
+            Abs = delegate(T number)\r
+            {\r
+                if (number.CompareTo(Zero) < 0)\r
+                {\r
+                    return Neg(number);\r
+                }\r
+                return number;\r
+            };\r
         }\r
     }\r
 }\r
index 9713f75..17307e9 100755 (executable)
@@ -62,7 +62,11 @@ namespace KarintoTest.NumericTest
 \r
             public int CompareTo(Object value)\r
             {\r
-                return number.CompareTo(value);\r
+                if (!(value is MyNumber))\r
+                {\r
+                    throw new ArgumentException();\r
+                }\r
+                return number.CompareTo(((MyNumber)value).number);\r
             }\r
 \r
         }\r
@@ -89,6 +93,9 @@ namespace KarintoTest.NumericTest
             Assert.AreEqual(left * right, I4.Mul(left, right));\r
             Assert.AreEqual(left / right, I4.Div(left, right));\r
             Assert.AreEqual(-left, I4.Neg(left));\r
+            Assert.AreEqual(0, I4.Abs(0));\r
+            Assert.AreEqual(Math.Abs(left - right), I4.Abs(left - right));\r
+            Assert.AreEqual(Math.Abs(right - left), I4.Abs(right - left));\r
         }\r
 \r
         [TestCase(123456789012345L, 67890123L)]\r
@@ -101,6 +108,9 @@ namespace KarintoTest.NumericTest
             Assert.AreEqual(left * right, I8.Mul(left, right));\r
             Assert.AreEqual(left / right, I8.Div(left, right));\r
             Assert.AreEqual(-left, I8.Neg(left));\r
+            Assert.AreEqual(0L, I8.Abs(0L));\r
+            Assert.AreEqual(Math.Abs(left - right), I8.Abs(left - right));\r
+            Assert.AreEqual(Math.Abs(right - left), I8.Abs(right - left));\r
         }\r
 \r
         [Test]\r
@@ -115,6 +125,9 @@ namespace KarintoTest.NumericTest
             Assert.AreEqual(left * right, M.Mul(left, right));\r
             Assert.AreEqual(left / right, M.Div(left, right));\r
             Assert.AreEqual(-left, M.Neg(left));\r
+            Assert.AreEqual(0.0m, M.Abs(0.0m));\r
+            Assert.AreEqual(Math.Abs(left - right), M.Abs(left - right));\r
+            Assert.AreEqual(Math.Abs(right - left), M.Abs(right - left));\r
         }\r
 \r
         [TestCase(1234.5f, 67.8e-9f)]\r
@@ -127,6 +140,9 @@ namespace KarintoTest.NumericTest
             Assert.AreEqual(left * right, F4.Mul(left, right));\r
             Assert.AreEqual(left / right, F4.Div(left, right));\r
             Assert.AreEqual(-left, F4.Neg(left));\r
+            Assert.AreEqual(0.0f, F4.Abs(0.0f));\r
+            Assert.AreEqual(Math.Abs(left - right), F4.Abs(left - right));\r
+            Assert.AreEqual(Math.Abs(right - left), F4.Abs(right - left));\r
         }\r
 \r
         [TestCase(1234.5, 67.8e-9)]\r
@@ -139,6 +155,9 @@ namespace KarintoTest.NumericTest
             Assert.AreEqual(left * right, F8.Mul(left, right));\r
             Assert.AreEqual(left / right, F8.Div(left, right));\r
             Assert.AreEqual(-left, F8.Neg(left));\r
+            Assert.AreEqual(0.0, F8.Abs(0.0));\r
+            Assert.AreEqual(Math.Abs(left - right), F8.Abs(left - right));\r
+            Assert.AreEqual(Math.Abs(right - left), F8.Abs(right - left));\r
         }\r
 \r
         [Test]\r
@@ -157,24 +176,29 @@ namespace KarintoTest.NumericTest
 \r
             MyNumber left = new MyNumber(1234.5);\r
             MyNumber right = new MyNumber(67.8);\r
+            MyNumber zero = left - left;\r
 \r
             Assert.AreEqual(0, (int)Operator<MyNumber>.Zero);\r
             Assert.AreEqual(1, (int)Operator<MyNumber>.One);\r
             Assert.AreEqual(left + right, Operator<MyNumber>.Add(left, right));\r
             Assert.AreEqual(left - right, Operator<MyNumber>.Sub(left, right));\r
-            Assert.AreEqual(left - left - left, Operator<MyNumber>.Neg(left));\r
+            Assert.AreEqual(zero - left, Operator<MyNumber>.Neg(left));\r
+            Assert.AreEqual(zero, Operator<MyNumber>.Abs(zero));\r
+            Assert.AreEqual(left - right, Operator<MyNumber>.Abs(left - right));\r
+            Assert.AreEqual(left - right, Operator<MyNumber>.Abs(right - left));\r
         }\r
 \r
         [Test]\r
         public void CheckSpeed()\r
         {\r
-            int m = 10240;\r
+            const int m = 10240;\r
             int n = random.Length;\r
             int v1 = 1;\r
 \r
             I4.Add(1, 1); // dummy\r
 \r
-            DateTime start = DateTime.Now;\r
+            DateTime start;\r
+            start = DateTime.Now;\r
             for (int j = 0; j < m; ++j)\r
             {\r
                 for (int i = 1; i < n; ++i)\r
@@ -196,7 +220,7 @@ namespace KarintoTest.NumericTest
             TimeSpan dt2 = DateTime.Now - start;\r
 \r
             Assert.AreEqual(v1, v2);\r
-            Assert.Less(dt2.Ticks * 0.1, dt1.Ticks);\r
+            Assert.Less(dt2.Ticks, dt1.Ticks * 10);\r
 \r
         }\r
     }\r