luadivide-by-zero

Why doesn't divsion by zero return an error (using pcall) in Lua?


The following code should result in an error message (runtime error):

local status, result = pcall(function()
    return 10 / 0
end)

if not status then
    print("Error during division:", result) -- result will contain the error message
else
    print("Division successful:", result)
end

However, this doesn't work since status is always TRUE, regardless of the numbers used (including division by 0). I thought this might be a "version" issue, but I can't find any support for this possibility.

Any thoughts?

I tried the suggested code (above), as well as code from a 'textbook':


function riskyDivision(a, b)
    if b == 0 then
        print( "Error, division by 0")
    end
    return a/b
end

-- failure example
local status, result = pcall(riskyDivision, 10, 0)

if status then
    print("Success: " .. tostring(result))
else
    print("Failure: " .. tostring(result))  -- remember, this returns "inf"
end

In this case, 'b' DOES equal 0 ('error' message in function works), but the use of pcall doesn't. Note that the function riskyDivision function returns inf and not an error message (it returns TRUE).


Solution

  • With float division (/, IEEE 754), division by zero results in a quotient of:

    None of these raise runtime errors, so pcall has nothing to catch. This is dissimilar to other languages such as Python or Ruby which raise a ZeroDivisionError when dividing by zero.

    The riskyDivision function shown also does not raise an error, it only prints a message. Errors can be raised manually with the error function.

    local function riskydiv(a, b)
        if b == 0 then
            error('attempt to divide by zero')
        end
    
        return a / b
    end
    
    local status, res = pcall(riskydiv, 10, 0)
    
    print(status, res)
    
    false   div.lua:3: attempt to divide by zero
    

    With floor division (//, Lua 5.3+), division by zero does raise an error:

    local status, res = pcall(function ()
        return 10 // 0
    end)
    
    print(status, res)
    
    false   div.lua:2: attempt to divide by zero
    

    See also: Why does division by zero in IEEE754 standard results in Infinite value?