Skip to content

Commit a5b5504

Browse files
committed
[GR-18163] Update Math.sqrt to raise a Math::DomainError for negative numbers
PullRequest: truffleruby/3226
2 parents b8086af + c19881c commit a5b5504

File tree

6 files changed

+13
-4
lines changed

6 files changed

+13
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Compatibility:
4747
* Update `File.utime` to return the number of file names in the arguments (#2616, @bjfish).
4848
* Update `Dir.foreach` to accept an `encoding` parameter (#2627, @bjfish).
4949
* Update `IO.readlines` to ignore negative limit parameters (#2625 , @bjfish).
50+
* Update `Math.sqrt` to raise a `Math::DomainError` for negative numbers (#2621, @bjfish).
5051

5152
Performance:
5253

spec/ruby/core/math/sqrt_spec.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
it "accepts any argument that can be coerced with Float()" do
2828
Math.sqrt(MathSpecs::Float.new).should be_close(1.0, TOLERANCE)
2929
end
30+
31+
it "raises a Math::DomainError when given a negative number" do
32+
-> { Math.sqrt(-1) }.should raise_error(Math::DomainError)
33+
end
3034
end
3135

3236
describe "Math#sqrt" do

src/main/java/org/truffleruby/core/CoreLibrary.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ public class CoreLibrary {
141141
public final RubyClass loadErrorClass;
142142
public final RubyClass localJumpErrorClass;
143143
public final RubyClass matchDataClass;
144+
public final RubyClass mathDomainErrorClass;
144145
public final RubyClass moduleClass;
145146
public final RubyClass nameErrorClass;
146147
public final RubyClass nilClass;
@@ -444,7 +445,8 @@ public CoreLibrary(RubyContext context, RubyLanguage language) {
444445
enumerableModule = defineModule("Enumerable");
445446
defineModule("GC");
446447
kernelModule = defineModule("Kernel");
447-
defineModule("Math");
448+
var mathModule = defineModule("Math");
449+
mathDomainErrorClass = defineClass(mathModule, standardErrorClass, "DomainError");
448450
objectSpaceModule = defineModule("ObjectSpace");
449451

450452
weakMapClass = defineClass(objectSpaceModule, objectClass, "WeakMap");

src/main/java/org/truffleruby/core/MathNodes.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,10 @@ public abstract static class SqrtNode extends SimpleMonadicMathNode {
592592

593593
@Override
594594
protected double doFunction(double a) {
595+
if (a < 0.0) {
596+
exceptionProfile.enter();
597+
throw new RaiseException(getContext(), coreExceptions().mathDomainError("sqrt", this));
598+
}
595599
return Math.sqrt(a);
596600
}
597601

src/main/java/org/truffleruby/core/exception/CoreExceptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ public RubyException mathDomainErrorLog(Node currentNode) {
423423

424424
@TruffleBoundary
425425
public RubyException mathDomainError(String method, Node currentNode) {
426-
RubyClass exceptionClass = context.getCoreLibrary().getErrnoClass("EDOM");
426+
RubyClass exceptionClass = context.getCoreLibrary().mathDomainErrorClass;
427427
Rope rope = StringOperations.encodeRope(
428428
StringUtils.format("Numerical argument is out of domain - \"%s\"", method),
429429
UTF8Encoding.INSTANCE);

src/main/ruby/truffleruby/core/math.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ module Math
1313
PI = 3.14159265358979323846
1414
E = 2.7182818284590452354
1515

16-
DomainError = Errno::EDOM
17-
1816
module_function
1917

2018
def hypot(a, b)

0 commit comments

Comments
 (0)