You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lua5.3与Lua5.1阶乘代码差异:为何19!后结果异常?

Why Your Factorial Script Breaks in Lua 5.3 (But Works in 5.1)

Great question! This issue comes down to a critical change between Lua 5.1 and 5.3: Lua 5.3 added native 64-bit integer support, while Lua 5.1 only used double-precision floating-point numbers for all values. Let’s break this down:

1. How Lua 5.1 Handles Your Script

In Lua 5.1, every number is a double-precision float. These floats can exactly represent all integers up to 2^53 (about 9e15). Beyond that, they lose precision (since floats store a fixed number of significant digits), but they never "overflow" into nonsensical values—they just use an approximate representation. That’s why your script runs smoothly all the way until the float can’t handle the size anymore (around 1e308, the max for doubles).

2. The Lua 5.3 Problem

Lua 5.3 introduced 64-bit signed integers, and it follows a strict rule: if both operands of a math operation are integers, the operation runs as integer arithmetic.

In your script, N and F start as integers, so every F = F * N is an integer multiplication. The problem? 64-bit signed integers have a maximum value of 9223372036854775807 (roughly 9e18). Let’s check the factorials:

  • 20! = 2432902008176640000 (~2.4e18) — still fits in a 64-bit integer, so no problem.
  • 21! = 51090942171709440000 (~5.1e19) — way larger than the 64-bit integer limit.

When this happens, Lua 5.3 triggers integer overflow. Since integers use two’s complement representation, the overflow wraps around into a negative number or a garbage positive value. Your loop condition F < 1e200 is still true (negative numbers are definitely less than 1e200), so the script keeps running—but the factorial values are completely wrong from that point on.

Fixing the Script

To make your script work in Lua 5.3, you just need to force the arithmetic to use floating-point numbers instead of integers. Here are a few simple ways:

Option 1: Initialize F as a float

Change the first line to start with a floating-point value:

N, F = 1, 1.0  -- 1.0 is a float, not an integer
while F < 1e200 do
    print(N .. "! is " .. F)
    N = N + 1
    F = F * N
end

Now every multiplication will use floating-point arithmetic, matching Lua 5.1’s behavior.

Option 2: Explicitly convert to float during multiplication

If you prefer to keep the initial integer values, you can cast one operand to a float in the multiplication:

N, F = 1, 1
while F < 1e200 do
    print(N .. "! is " .. F)
    N = N + 1
    F = F * N + 0.0  -- Adding 0.0 forces the result to be a float
end

Either fix will prevent integer overflow, and your script will run just like it did in Lua 5.1—you’ll lose precision once you pass 2^53, but you won’t get those weird overflowed values.

内容的提问来源于stack exchange,提问作者costica_p

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:32:05