Skip to content

floor and ceil of an infinity or NaN throw OverflowException #830

Description

@Rafael-SOWNet

floor and ceil of an infinity or of NaN throw System.OverflowException: Value is infinity or NaN out of evaluation. Introduced by #827.

An internal PeterO.Numbers exception reaching the caller is a bug on its own terms — the library's
contract is that evaluation answers, returns an unevaluated node, or returns NaN, not that it throws
a numeric-library exception the caller has no reason to expect.

Measured on master (46140f8)

eval(floor(+oo))     !!! OverflowException: Value is infinity or NaN
eval(ceil(-oo))      !!! OverflowException: Value is infinity or NaN
simplify(floor(+oo)) !!! OverflowException: Value is infinity or NaN
eval(floor(0/0))     !!! OverflowException: Value is infinity or NaN
eval(floor(x/0))     !!! OverflowException: Value is infinity or NaN

For contrast, the neighbours that behave:

eval(abs(+oo))       +oo
eval(sgn(+oo))       1
eval(abs(0/0))       NaN

Cause

Evaluation.Continuous.Arithmetics.Classes.cs:275-290 (and the Ceilf copy at 299-311):

Real n when !isExact => Integer.Create(n.EDecimal.Floor().ToEInteger()),
Complex n when !isExact => Complex.Create(
    n.RealPart.EDecimal.Floor(), n.ImaginaryPart.EDecimal.Floor()),

Real includes the infinities and NaN. EDecimal.Floor() passes them through, and
EInteger.ToEInteger() refuses them.

What the answers should be

floor(+oo)  +oo         ceil(+oo)  +oo
floor(-oo)  -oo         ceil(-oo)  -oo
floor(NaN)  NaN         ceil(NaN)  NaN

floor of an infinity is that infinity — there is no greatest integer below +oo, and +oo is the
answer every other CAS gives and the one abs already gives here. NaN propagates, as it does
everywhere else.

The complex branch needs the same guard componentwise: floor(1/2 + oo*i) should not throw either.

Related

The limit crash in the same node pair is #829. Both come from #827 and both are cases the node's own
tests did not reach; a checklist of the places a new subtype must be wired would have caught both.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions