1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #include <Standard_Real.hxx>
17 #include <Standard_RangeError.hxx>
18 #include <Standard_NumericError.hxx>
19 #include <Standard_NullValue.hxx>
20 #include <Standard_Stream.hxx>
21 #include <Standard_OStream.hxx>
23 static const Standard_Real ACosLimit = 1. + Epsilon(1.);
25 //============================================================================
26 // function : HashCode
28 //============================================================================
29 Standard_Integer HashCode (const Standard_Real theReal, const Standard_Integer theUpperBound)
31 if (theUpperBound < 1)
33 throw Standard_RangeError ("Try to apply HashCode method with negative or null argument.");
38 Standard_Integer I[2];
41 // U.R = Abs(me); // Treat me = -0.0 ADN 27/11/97
44 return HashCode (U.I[0] ^ U.I[1], theUpperBound);
47 //-------------------------------------------------------------------
48 // ACos : Returns the value of the arc cosine of a real
49 //-------------------------------------------------------------------
50 Standard_Real ACos (const Standard_Real Value)
52 if ((Value < -ACosLimit) || (Value > ACosLimit)){
53 throw Standard_RangeError();
61 return M_PI; //acos(-1.)
66 //-------------------------------------------------------------------
67 // ACosApprox : Returns the approximate value of the arc cosine of a real.
68 // The max error is about 1 degree near Value=0.
69 //-------------------------------------------------------------------
71 inline Standard_Real apx_for_ACosApprox (const Standard_Real x)
73 return (-0.000007239283986332 +
74 x * (2.000291665285952400 +
75 x * (0.163910606547823220 +
76 x * (0.047654245891495528 -
77 x * (0.005516443930088506 +
78 0.015098965761299077 * x))))) / sqrt(2*x);
81 Standard_Real ACosApprox (const Standard_Real Value)
88 return M_PI - apx_for_ACosApprox(XX);
93 return apx_for_ACosApprox(XX);
95 // The code above is the same but includes 2 comparisons instead of 3
96 // Standard_Real xn = 1.+Value;
97 // Standard_Real xp = 1.-Value;
98 // if (xp < RealSmall() || xn < RealSmall())
101 // return M_PI - apx_for_ACosApprox (xn);
102 // return apx_for_ACosApprox (xp);
105 //-------------------------------------------------------------------
106 // ASin : Returns the value of the arc sine of a real
107 //-------------------------------------------------------------------
108 Standard_Real ASin (const Standard_Real Value)
110 if ((Value < -ACosLimit) || (Value > ACosLimit)){
111 throw Standard_RangeError();
115 return M_PI_2; //asin(1.)
117 else if (Value < -1.)
119 return -M_PI_2; //asin(-1.)
124 //-------------------------------------------------------------------
125 // ATan2 : Returns the arc tangent of a real divide by an another real
126 //-------------------------------------------------------------------
127 Standard_Real ATan2 (const Standard_Real Value, const Standard_Real Other)
129 if ( Value == 0. && Other == 0. ){
130 throw Standard_NullValue();
132 return atan2(Value,Other);
135 //-------------------------------------------------------------------
136 // Sign : Returns |a| if B >= 0; -|a| if b < 0.
137 //-------------------------------------------------------------------
138 Standard_Real Sign(const Standard_Real a, const Standard_Real b)
143 return (-1.0 * Abs(a));
147 //==========================================================================
148 //===== The special routines for "IEEE" and differents hardwares ===========
149 //==========================================================================
155 //--------------------------------------------------------------------
156 // HardwareHighBitsOfDouble :
157 // Returns 1 if the low bits are at end. (exemple: decmips and ALPHA )
158 // Returns 0 if the low bits are at begin. (exemple: sun, sgi, ...)
159 //--------------------------------------------------------------------
160 static int HardwareHighBitsOfDouble()
163 MaxDouble.real = DBL_MAX;
164 //=========================================================
165 // reperesentation of the max double in IEEE is
166 // "7fef ffff ffff ffff" for the big indiens.
167 // "ffff ffff 7fef ffff" for the littel indiens.
168 //=========================================================
170 if(MaxDouble.map[1] != 0xffffffff){
177 //--------------------------------------------------------------------
178 // HardwareLowBitsOfDouble :
179 // Returns 0 if the low bits are at end. (exemple: decmips )
180 // Returns 1 if the low bits are at begin. (exemple: sun, sgi, ...)
181 //--------------------------------------------------------------------
182 static int HardwareLowBitsOfDouble()
185 MaxDouble.real = DBL_MAX;
186 //=========================================================
187 // reperesentation of the max double in IEEE is
188 // "7fef ffff ffff ffff" for the big indiens.
189 // "ffff ffff 7fef ffff" for the littel indiens.
190 //=========================================================
192 if(MaxDouble.map[1] != 0xffffffff){
199 static int HighBitsOfDouble = HardwareHighBitsOfDouble();
200 static int LowBitsOfDouble = HardwareLowBitsOfDouble();
202 double NextAfter(const double x, const double y)
212 //=========================================
213 // -oo__________0___________+oo
215 // The direction is "Null", so there is nothing after
216 //=========================================
218 } else if (((x<y) && (x>=0.0)) || ((x>y) && (x<0.0))) {
219 //=========================================
220 // -oo__________0___________+oo
223 //=========================================
224 if (res.map[LowBitsOfDouble]==0xffffffff) {
225 res.map[LowBitsOfDouble]=0;
226 res.map[HighBitsOfDouble]++;
228 res.map[LowBitsOfDouble]++;
231 //=========================================
232 // -oo__________0___________+oo
235 //=========================================
236 if (res.map[LowBitsOfDouble]==0) {
237 if (res.map[HighBitsOfDouble]==0) {
238 res.map[HighBitsOfDouble]=0x80000000;
239 res.map[LowBitsOfDouble]=0x00000001;
241 res.map[LowBitsOfDouble]=0xffffffff;
242 res.map[HighBitsOfDouble]--;
245 res.map[LowBitsOfDouble]--;
251 //-------------------------------------------------------------------
252 // ATanh : Returns the value of the hyperbolic arc tangent of a real
253 //-------------------------------------------------------------------
254 Standard_Real ATanh(const Standard_Real Value)
256 if ( (Value <= -1.) || (Value >= 1.) ){
258 std::cout << "Illegal agument in ATanh" << std::endl ;
260 throw Standard_NumericError("Illegal agument in ATanh");
263 return std::atanh(Value);
269 //-------------------------------------------------------------------
270 // ACosh : Returns the hyperbolic Arc cosine of a real
271 //-------------------------------------------------------------------
272 Standard_Real ACosh (const Standard_Real Value)
276 std::cout << "Illegal agument in ACosh" << std::endl ;
278 throw Standard_NumericError("Illegal agument in ACosh");
281 return std::acosh(Value);
287 //-------------------------------------------------------------------
288 // Cosh : Returns the hyperbolic cosine of a real
289 //-------------------------------------------------------------------
290 Standard_Real Cosh (const Standard_Real Value)
292 if ( Abs(Value) > 0.71047586007394394e+03 ){
294 std::cout << "Result of Cosh exceeds the maximum value Standard_Real" << std::endl ;
296 throw Standard_NumericError("Result of Cosh exceeds the maximum value Standard_Real");
301 //-------------------------------------------------------------------
302 // Sinh : Returns the hyperbolicsine of a real
303 //-------------------------------------------------------------------
304 Standard_Real Sinh (const Standard_Real Value)
306 if ( Abs(Value) > 0.71047586007394394e+03 ){
308 std::cout << "Result of Sinh exceeds the maximum value Standard_Real" << std::endl ;
310 throw Standard_NumericError("Result of Sinh exceeds the maximum value Standard_Real");
315 //-------------------------------------------------------------------
316 // Log : Returns the naturaOPl logarithm of a real
317 //-------------------------------------------------------------------
318 Standard_Real Log (const Standard_Real Value)
319 { if ( Value <= 0. ){
321 std::cout << "Illegal agument in Log" << std::endl ;
323 throw Standard_NumericError("Illegal agument in Log");
327 //-------------------------------------------------------------------
328 // Sqrt : Returns the square root of a real
329 //-------------------------------------------------------------------
330 Standard_Real Sqrt (const Standard_Real Value)
334 std::cout << "Illegal agument in Sqrt" << std::endl ;
336 throw Standard_NumericError("Illegal agument in Sqrt");