Skip to content

Commit e3e5821

Browse files
committed
[GR-10330] Correct and finish implementation of Math.acos() function.
1 parent aaf95f1 commit e3e5821

File tree

2 files changed

+70
-3
lines changed

2 files changed

+70
-3
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_math.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,39 @@ def ftest(self, name, got, expected, ulp_tol=5, abs_tol=0.0):
102102
if failure is not None:
103103
self.fail("{}: {}".format(name, failure))
104104

105+
def testAcos(self):
106+
self.assertRaises(TypeError, math.acos)
107+
self.ftest('acos(-1)', math.acos(-1), math.pi)
108+
self.ftest('acos(0)', math.acos(0), math.pi/2)
109+
self.ftest('acos(1)', math.acos(1), 0)
110+
self.assertRaises(ValueError, math.acos, INF)
111+
self.assertRaises(ValueError, math.acos, NINF)
112+
self.assertRaises(ValueError, math.acos, 1 + eps)
113+
self.assertRaises(ValueError, math.acos, -1 - eps)
114+
self.assertTrue(math.isnan(math.acos(NAN)))
115+
116+
self.assertEqual(math.acos(True), 0.0)
117+
self.assertRaises(ValueError, math.acos, 10)
118+
self.assertRaises(ValueError, math.acos, -10)
119+
self.assertRaises(TypeError, math.acos, 'ahoj')
120+
121+
self.assertRaises(ValueError, math.acos, 9999992432902008176640000999999)
122+
123+
class MyFloat:
124+
def __float__(self):
125+
return 0.6
126+
self.ftest('acos(MyFloat())', math.acos(MyFloat()), 0.9272952180016123)
127+
128+
class MyFloat2:
129+
def __float__(self):
130+
return 1.6
131+
self.assertRaises(ValueError, math.acos, MyFloat2())
132+
133+
class MyFloat3:
134+
def __float__(self):
135+
return 'ahoj'
136+
self.assertRaises(TypeError, math.acos, MyFloat3())
137+
105138
def test_ceil_basic(self):
106139
self.assertEqual(math.ceil(10), 10)
107140
self.assertEqual(math.ceil(-10), -10)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MathModuleBuiltins.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.oracle.graal.python.builtins.objects.floats.PFloat;
4141
import com.oracle.graal.python.builtins.objects.ints.PInt;
4242
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
43+
import com.oracle.graal.python.nodes.PNode;
4344
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
4445
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
4546
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
@@ -827,19 +828,52 @@ public double ldexpOO(Object mantissa, Object exp) {
827828

828829
}
829830

830-
@Builtin(name = "acos", fixedNumOfArguments = 1)
831+
@Builtin(name = "acos", fixedNumOfArguments = 1, doc = "Return the arc cosine (measured in radians) of x.")
832+
@TypeSystemReference(PythonArithmeticTypes.class)
833+
@ImportStatic(MathGuards.class)
831834
@GenerateNodeFactory
832835
public abstract static class AcosNode extends PythonBuiltinNode {
833836

837+
public abstract double execute(Object value);
838+
834839
@Specialization
835-
public double acos(int value) {
840+
public double acos(int value,
841+
@Cached("createBinaryProfile()") ConditionProfile doNotFit) {
842+
if (doNotFit.profile(value > 1 || value < -1)) {
843+
throw raise(ValueError, "math domain error");
844+
}
836845
return Math.acos(value);
837846
}
838847

839848
@Specialization
840-
public double acos(double value) {
849+
public double acos(PInt value,
850+
@Cached("createBinaryProfile()") ConditionProfile doNotFit) {
851+
return acos(value.intValue(), doNotFit);
852+
}
853+
854+
@Specialization
855+
public double acos(double value,
856+
@Cached("createBinaryProfile()") ConditionProfile doNotFit) {
857+
if (doNotFit.profile(Double.isInfinite(value) || -1 > value || value > 1)) {
858+
throw raise(ValueError, "math domain error");
859+
}
841860
return Math.acos(value);
842861
}
862+
863+
@Specialization(guards = "!isNumber(value)")
864+
public double acos(Object value,
865+
@Cached("create(__FLOAT__)") LookupAndCallUnaryNode dispatchFloat,
866+
@Cached("create()") AcosNode acosNode) {
867+
Object result = dispatchFloat.executeObject(value);
868+
if (result == PNone.NO_VALUE) {
869+
throw raise(TypeError, "must be real number, not %p", value);
870+
}
871+
return acosNode.execute(result);
872+
}
873+
874+
protected AcosNode create() {
875+
return MathModuleBuiltinsFactory.AcosNodeFactory.create(new PNode[0]);
876+
}
843877
}
844878

845879
@Builtin(name = "cos", fixedNumOfArguments = 1)

0 commit comments

Comments
 (0)