int () truncates its result to 32 bits

未关闭 适合新手
#911 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
88/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
javascript, python
领域
compilers

调研方向

builtin.js 的第 291 行开始,其中 int() 当前使用 JavaScript 的按位转换,并检查 development/automated_tests/transcrypt/div_issues/init.py 中的 Issue 911 testlet。让大整数检查通过,同时保留负浮点数向零截断的行为,然后使用指定的编译器选项在 Node 下运行该 testlet。

由索引模型根据 Issue 内容生成。

描述

int (x) compiles to float (x) | 0. JavaScript's | converts its left operand with ToInt32, so the result is always a signed 32 bit integer. Arguments outside -2**31 ... 2**31 - 1 come back wrong, multiples of 2**32 come back as 0.

Reproducer

values = [8589934588, 9007199254740988, 2147483648, 4294967296]
for v in values:
    print (v, '->', int (v))

CPython:

8589934588 -> 8589934588
9007199254740988 -> 9007199254740988
2147483648 -> 2147483648
4294967296 -> 4294967296

Transcrypt:

8589934588 -> -4
9007199254740988 -> -4
2147483648 -> -2147483648
4294967296 -> 0

Run with 3.7.16 on Python 3.7, compiled with -b -n -e 6 and executed under
node. Line 291 of __builtin__.js is identical on current master.

The failure is quiet. A memory size in kB, a file offset or a timestamp in microseconds passes 2**31 during normal operation and then yields a small or negative number instead of an error.

Testlet

For development/automated_tests/transcrypt/div_issues/__init__.py:

    autoTester.check ('Issue 911')  # int () truncated to 32 bits
    autoTester.check (int (2147483648))
    autoTester.check (int (4294967296))
    autoTester.check (int (8589934588))
    autoTester.check (int (9007199254740988))
    autoTester.check (int (-5.7), int (5.7))

Possible fix

export function int (any) {
    var f = float (any);
    return f === Infinity || f === -Infinity || isNaN (f) ? 0 : Math.trunc (f);
};

This makes int () exact over the whole range where a JavaScript number is exact, up to 2**53 - 1, and leaves truncation toward zero for negative floats unchanged. With the patch applied the reproducer above matches CPython.

Math.trunc is ES6. The default target is esv 6 and javascriptVersion gates nothing in the code generator, so no version switch is needed. int has no callers inside the runtime.

Note on NaN and Infinity

NaN | 0 and Infinity | 0 currently yield 0, where CPython raises ValueError and OverflowError. The version above keeps the 0 to stay minimal. Raising instead would match CPython but changes behaviour beyond the range fix, so it seems worth deciding separately.

主要语言
Python
星标
2.9k
派生
218
PR 合并指标
30 天内没有已合并 PR

贡献指南

这个仓库没有索引到贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

TranscryptOrg/Transcrypt 的其他 Issue

查看 TranscryptOrg/Transcrypt 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。