[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunit.framework / Constraints / FloatingPointNumerics.cs
1 // ***********************************************************************
2 // Copyright (c) 2009 Charlie Poole
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
23 #define PORTABLE
24 #define TIZEN
25 #define NUNIT_FRAMEWORK
26 #define NUNITLITE
27 #define NET_4_5
28 #define PARALLEL
29 using System;
30 using System.Runtime.InteropServices;
31
32 namespace NUnit.Framework.Constraints
33 {
34
35     /// <summary>Helper routines for working with floating point numbers</summary>
36     /// <remarks>
37     ///   <para>
38     ///     The floating point comparison code is based on this excellent article:
39     ///     http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
40     ///   </para>
41     ///   <para>
42     ///     "ULP" means Unit in the Last Place and in the context of this library refers to
43     ///     the distance between two adjacent floating point numbers. IEEE floating point
44     ///     numbers can only represent a finite subset of natural numbers, with greater
45     ///     accuracy for smaller numbers and lower accuracy for very large numbers.
46     ///   </para>
47     ///   <para>
48     ///     If a comparison is allowed "2 ulps" of deviation, that means the _values are
49     ///     allowed to deviate by up to 2 adjacent floating point _values, which might be
50     ///     as low as 0.0000001 for small numbers or as high as 10.0 for large numbers.
51     ///   </para>
52     /// </remarks>
53     public class FloatingPointNumerics
54     {
55
56         #region struct FloatIntUnion
57
58         /// <summary>Union of a floating point variable and an integer</summary>
59         [StructLayout(LayoutKind.Explicit)]
60         private struct FloatIntUnion
61         {
62             /// <summary>The union's value as a floating point variable</summary>
63             [FieldOffset(0)]
64             public float Float;
65
66             /// <summary>The union's value as an integer</summary>
67             [FieldOffset(0)]
68             public int Int;
69
70             /// <summary>The union's value as an unsigned integer</summary>
71             [FieldOffset(0)]
72             public uint UInt;
73         }
74
75         #endregion // struct FloatIntUnion
76
77         #region struct DoubleLongUnion
78
79         /// <summary>Union of a double precision floating point variable and a long</summary>
80         [StructLayout(LayoutKind.Explicit)]
81         private struct DoubleLongUnion
82         {
83             /// <summary>The union's value as a double precision floating point variable</summary>
84             [FieldOffset(0)]
85             public double Double;
86
87             /// <summary>The union's value as a long</summary>
88             [FieldOffset(0)]
89             public long Long;
90
91             /// <summary>The union's value as an unsigned long</summary>
92             [FieldOffset(0)]
93             public ulong ULong;
94         }
95
96         #endregion // struct DoubleLongUnion
97
98         /// <summary>Compares two floating point _values for equality</summary>
99         /// <param name="left">First floating point value to be compared</param>
100         /// <param name="right">Second floating point value t be compared</param>
101         /// <param name="maxUlps">
102         ///   Maximum number of representable floating point _values that are allowed to
103         ///   be between the left and the right floating point _values
104         /// </param>
105         /// <returns>True if both numbers are equal or close to being equal</returns>
106         /// <remarks>
107         ///   <para>
108         ///     Floating point _values can only represent a finite subset of natural numbers.
109         ///     For example, the _values 2.00000000 and 2.00000024 can be stored in a float,
110         ///     but nothing inbetween them.
111         ///   </para>
112         ///   <para>
113         ///     This comparison will count how many possible floating point _values are between
114         ///     the left and the right number. If the number of possible _values between both
115         ///     numbers is less than or equal to maxUlps, then the numbers are considered as
116         ///     being equal.
117         ///   </para>
118         ///   <para>
119         ///     Implementation partially follows the code outlined here:
120         ///     http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
121         ///   </para>
122         /// </remarks>
123         public static bool AreAlmostEqualUlps(float left, float right, int maxUlps)
124         {
125             FloatIntUnion leftUnion = new FloatIntUnion();
126             FloatIntUnion rightUnion = new FloatIntUnion();
127
128             leftUnion.Float = left;
129             rightUnion.Float = right;
130
131             uint leftSignMask = (leftUnion.UInt >> 31);
132             uint rightSignMask = (rightUnion.UInt >> 31);
133
134             uint leftTemp = ((0x80000000 - leftUnion.UInt) & leftSignMask);
135             leftUnion.UInt = leftTemp | (leftUnion.UInt & ~leftSignMask);
136
137             uint rightTemp = ((0x80000000 - rightUnion.UInt) & rightSignMask);
138             rightUnion.UInt = rightTemp | (rightUnion.UInt & ~rightSignMask);
139
140             if (leftSignMask != rightSignMask) // Overflow possible, check each against zero
141             {
142                 if (Math.Abs(leftUnion.Int) > maxUlps || Math.Abs(rightUnion.Int) > maxUlps)
143                     return false;
144             }
145
146             // Either they have the same sign or both are very close to zero
147             return Math.Abs(leftUnion.Int - rightUnion.Int) <= maxUlps;
148         }
149
150         /// <summary>Compares two double precision floating point _values for equality</summary>
151         /// <param name="left">First double precision floating point value to be compared</param>
152         /// <param name="right">Second double precision floating point value t be compared</param>
153         /// <param name="maxUlps">
154         ///   Maximum number of representable double precision floating point _values that are
155         ///   allowed to be between the left and the right double precision floating point _values
156         /// </param>
157         /// <returns>True if both numbers are equal or close to being equal</returns>
158         /// <remarks>
159         ///   <para>
160         ///     Double precision floating point _values can only represent a limited series of
161         ///     natural numbers. For example, the _values 2.0000000000000000 and 2.0000000000000004
162         ///     can be stored in a double, but nothing inbetween them.
163         ///   </para>
164         ///   <para>
165         ///     This comparison will count how many possible double precision floating point
166         ///     _values are between the left and the right number. If the number of possible
167         ///     _values between both numbers is less than or equal to maxUlps, then the numbers
168         ///     are considered as being equal.
169         ///   </para>
170         ///   <para>
171         ///     Implementation partially follows the code outlined here:
172         ///     http://www.anttirt.net/2007/08/19/proper-floating-point-comparisons/
173         ///   </para>
174         /// </remarks>
175         public static bool AreAlmostEqualUlps(double left, double right, long maxUlps)
176         {
177             DoubleLongUnion leftUnion = new DoubleLongUnion();
178             DoubleLongUnion rightUnion = new DoubleLongUnion();
179
180             leftUnion.Double = left;
181             rightUnion.Double = right;
182
183             ulong leftSignMask = (leftUnion.ULong >> 63);
184             ulong rightSignMask = (rightUnion.ULong >> 63);
185
186             ulong leftTemp = ((0x8000000000000000 - leftUnion.ULong) & leftSignMask);
187             leftUnion.ULong = leftTemp | (leftUnion.ULong & ~leftSignMask);
188
189             ulong rightTemp = ((0x8000000000000000 - rightUnion.ULong) & rightSignMask);
190             rightUnion.ULong = rightTemp | (rightUnion.ULong & ~rightSignMask);
191
192             if (leftSignMask != rightSignMask) // Overflow possible, check each against zero
193             {
194                 if (Math.Abs(leftUnion.Long) > maxUlps || Math.Abs(rightUnion.Long) > maxUlps)
195                     return false;
196             }
197
198             // Either they have the same sign or both are very close to zero
199             return Math.Abs(leftUnion.Long - rightUnion.Long) <= maxUlps;
200         }
201
202         /// <summary>
203         ///   Reinterprets the memory contents of a floating point value as an integer value
204         /// </summary>
205         /// <param name="value">
206         ///   Floating point value whose memory contents to reinterpret
207         /// </param>
208         /// <returns>
209         ///   The memory contents of the floating point value interpreted as an integer
210         /// </returns>
211         public static int ReinterpretAsInt(float value)
212         {
213             FloatIntUnion union = new FloatIntUnion();
214             union.Float = value;
215             return union.Int;
216         }
217
218         /// <summary>
219         ///   Reinterprets the memory contents of a double precision floating point
220         ///   value as an integer value
221         /// </summary>
222         /// <param name="value">
223         ///   Double precision floating point value whose memory contents to reinterpret
224         /// </param>
225         /// <returns>
226         ///   The memory contents of the double precision floating point value
227         ///   interpreted as an integer
228         /// </returns>
229         public static long ReinterpretAsLong(double value)
230         {
231             DoubleLongUnion union = new DoubleLongUnion();
232             union.Double = value;
233             return union.Long;
234         }
235
236         /// <summary>
237         ///   Reinterprets the memory contents of an integer as a floating point value
238         /// </summary>
239         /// <param name="value">Integer value whose memory contents to reinterpret</param>
240         /// <returns>
241         ///   The memory contents of the integer value interpreted as a floating point value
242         /// </returns>
243         public static float ReinterpretAsFloat(int value)
244         {
245             FloatIntUnion union = new FloatIntUnion();
246             union.Int = value;
247             return union.Float;
248         }
249
250         /// <summary>
251         ///   Reinterprets the memory contents of an integer value as a double precision
252         ///   floating point value
253         /// </summary>
254         /// <param name="value">Integer whose memory contents to reinterpret</param>
255         /// <returns>
256         ///   The memory contents of the integer interpreted as a double precision
257         ///   floating point value
258         /// </returns>
259         public static double ReinterpretAsDouble(long value)
260         {
261             DoubleLongUnion union = new DoubleLongUnion();
262             union.Long = value;
263             return union.Double;
264         }
265
266         private FloatingPointNumerics()
267         {
268         }
269     }
270 }