帮酷LOGO
  • 显示原文与译文双语对照的内容
Arbitrary precision integers in JavaScript

  • 源代码名称:proposal-bigint
  • 源代码网址:http://www.github.com/tc39/proposal-bigint
  • proposal-bigint源代码文档
  • proposal-bigint源代码下载
  • Git URL:
    git://www.github.com/tc39/proposal-bigint.git
  • Git Clone代码到本地:
    git clone http://www.github.com/tc39/proposal-bigint
  • Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/tc39/proposal-bigint
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
  • : JavaScript中任意精度整数

    Daniel Ehrenberg,Igalia,阶段 3

    感谢 Brendan Eich,Waldemar Horwat,Jaro Sevcik,Benedikt Meurer,Michael Saboff,Adam Klein和其他人的帮助和反馈。

    代码示例:

    找到第n 个素数:

    // Takes a BigInt as an argument and returns a BigIntfunctionnthPrime(nth) {
     functionisPrime(p) {
     for (let i =2n; i < p; i++) {
     if (p % i ===0n) returnfalse;
     }
     returntrue;
     }
     for (let i =2n; ; i++) {
     if (isPrime(i)) {
     if (--nth ===0n) return i;
     }
     }
    }

    读取并在堆的asm.js 中添加两个无符号 64位 整数:

    functionAdd64Module(stdlib, foreign, buffer) {
     "use asm";
     var cast =stdlib.BigInt.asUintN;
     var values =newstdlib.BigUint64Array(buffer);
     functionadd64(aIndex, bIndex) {
     aIndex = aIndex|0;
     bIndex = bIndex|0;
     var aValue = values[aIndex>>3];
     var bValue = values[bIndex>>3];
     returncast(64, aValue + bValue);
     }
     return { add64: add64 };
    }

    用例

    在JavaScript编码中,大于 253的整数会出现,其中转换为双精度浮点将丢失真实的相关数据:

    • 适用于有符号或者无符号 64位 整数的大小写
      • 读取某些计算机寄存器,有线协议
      • 包含guid的Protobufs或者JSON文档
      • stat 可以将某些数据作为 64位 整数
      • 精确时间戳
    • 大于 64位 int
      • 一般满足合理用户期望的高级语言,整数算术将是"正确"而不是突然 overflow
      • 基础实现;可以能某些应用程序对于基于tmodel的on计算很高兴
      • 大整数。比如 。求解工程欧拉问题的任意数学计算
      • 精确的几何计算

    这里建议提供了一个新的。第二基元数字类型 BigInt,以满足这些用例。

    API概要

    BigInts是一种支持文本( 1234n ) 和运算符重载( 1n + 2n 使 3n )的新数值类型。

    文字,运算符及其含义

    在逻辑上,BigInts是任意的数学整数,运算符定义自然地脱落:

    • 二进制 +-*** 在应用到两个BigInts时发现它们的数学答案
    • /% 向 0舍入
    • 按位操作 |&<<>>^ 操作逻辑
      • 被解释为两个( 请参阅讨论 )的无限长补码的负数。
    • 将比较运算符应用于两个BigInts时,比较运算符 =====<>>=<= 执行数学比较
    • 缺少操作符
      • >>> 是不支持的,因为所有BigInts都是签名的;要获得无符号的移位,请将一个正BigInt传递到 >> ( 讨论子
      • 由于 asm.js 要求,BigInts上不支持一元 + ;详细信息解释了 below
    • 在条件中,if (0n) 执行 else 分支。

    BigInts的文本类似于数字文本,但后面跟了 n 。 它们可以用二进制,八进制或者十六进制符号写,比如,0x100n 。 旧版八进制语法( 0640 ) 是不允许的,只有新的样式( 0o064n ) 。

    BigInt的选择来自于试图保留用户对缺少 BigInt 和目前基于 Number的事物之间的兼容性的直觉。 因为隐含强迫导致 TypeErrors,所以如果现有用户在应用程序中工作,则它的指导原则应该与数字保持一致,只需要升级到 BigInt 。 NAME BigInt 希望强调这种not-by-default用法。 后缀 n 基本上是任意的。

    wsdl构造函数

    BigInts是一个基本类型,BigInt 构造一个构造函数,可以类似于 Number --to,并在属性访问时作为BigInt值的对象包装。

    当调用作为函数时,它类似于 Number 构造函数: 它将字符串。数字等转换为 BigInts 。

    库函数
    • BigInt.asUintN(width, BigInt): 在 0和 2 width-1之间封装一个 BigInt
    • BigInt.asIntN(width, BigInt): 在 -2 width-1和 2 width-1-1之间封装一个 BigInt

    TypedArrays和数据视图

    BigInts为JavaScript提供了准确表示 64位 有符号和无符号整数的能力:

    • BigUint64Array和 BigInt64Array,它的元素从属性访问读取,它们是 BigInts
    • sql dataview 。getbigint64/getbiguint64,返回一个 BigInt

    类似地,BigInts可以以由WebAssembly用于 64位 参数,并将值返回给函数。

    没有隐式转换或者混合操作数

    一个关键的设计决定是禁止BigInts和数字之间的混合操作。 驱动因素:任何隐含强迫都会丢失信息。

    在大整数和浮点数之间添加两个值时,结果的数学值可以能超出了两个数值。 比如, (2n**53n + 1n) + 0.5 有一个不能在任何范围内精确表示的值。 浮点算法不是精确的数学值,但至少它是由 IEEE 754定义的。 另一方面,为了保持更大值的整数精度,另一个目的是提供一个方法来保持整数精度。

    许多具有多个数值类型的动态类型编程语言实现了一个数字塔 。 当运算符与两个类型一起使用时,将生成一个介于numeric类型,类型为domain类型,而"较普通"操作数被强制转换为"更通用"类型。 很不幸,就像前面的例子所示,任意整数和双精度浮点之间没有"更通用"类型。 典型的解决方法是将浮点作为"更通用"类型。

    在使用整数和浮点数提供整数和浮点数的动态类型编程语言中,整数是像 1 和浮点数一样编写的,但是有时候会出现问题。 可以通过查找小数点来扫描可能引入浮点精度的操作的代码。 JavaScript通过使一个简单的文字像 1 一样的简单的文字来实现失败的范围。 因此,如果允许混合精度,一个无辜的计算如 2n ** 53n + 1 将产生浮点 2**53 --defeating这个功能的核心功能。

    为了避免这个问题,本建议禁止数字和BigInts之间隐含强制,包括混合类型的操作。 1n + 1 引发一个a 。所以它将 1n 作为参数传递到任何需要数字的JavaScript标准库函数或者 Web API 。 相反,要在类型之间进行转换,需要显式调用 Number() 或者 BigInt() 来确定哪个域要在。 0 === 0n 返回 false

    比较形成了这里规则的例外: 在数学上定义良好,允许比较运算符( 例如 <== ) 在数字和BigInts之间比较。 不像 + 这样的操作符,没有精度损失,因为输出只是一个布尔值。 这里外,== 在与字符串相比的比较中扩展了,比如 0n ==""true 。 尽管我们可以能无法将这个支持扩展到用户定义的类型,但这对于满足用户的期望很重要。

    的设计目标

    不破坏用户的直觉

    当一个混乱的情况出现时,这个方案会误发一个异常而不是静默地给出错误的答案。 这是 behind 在添加一个BigInt和一个数字时引发的错误: 如果我们没有好答案最好不要给一个。

    一些JavaScript用户肯定有一个直觉,即使在执行这种操作的成本下,也不会抛出异常。 Axel Rauschmeyer 精心设计的方案,阐述这种方法。 进一步讨论提出了一些问题,直接提升现有数字的行为,无论是兼容性还是对JavaScript价值的合理期望都是合理的。 目前,这个存储库将遵循不同的类型方法。

    不破坏数学

    理想情况下,所有操作符的语义应该基于某些数学原则,并且明确定义,而不是过度暴露实现构件。 /% 转向 0,这是 MATCH 良好的规约;除这里之外,所有操作员都有清晰的数学定义。

    不中断 asm.js

    尽管这里建议引入了运算符重载,但它会引发 asm.js 依赖于设置类型检查的任何情况。 asm.js 依赖于几个标识:

    • 后跟表达式的一元 + 始终是数字,或者是引发的结果。 因此,不幸的是,+ 上的需要抛出,而不是在数字上与 + 对称: 否则,以前的"类型声明" asm.js 代码将是多态的。
    • |0 总是在int32范围中返回数字,或者抛出。 这个建议保持了这一点,因为它将把一个tmodel作为混合操作数类型抛出。
    • Math.fround 总是返回float32范围中的数字,或者引发。 如果使用BigInt调用 Math.fround,则这里建议将引发,并保留属性。

    同样,>>> 0 总是返回一个uint32范围的数字,在BigInt上不支持 >>> 时抛出。 注意:asm.js 本身不需要这里属性,因为 >>> 可能是重载运算符,|0 用于所有 int 参数声明,但 >>> 0 是在JavaScript代码中实现这里属性的常用习惯用法。

    本建议对使用标准库函数( 包括标准库函数和 BigInt.asIntN 以及 BigUint64ArrayBigInt64Array ),使BigInt在 asm.js 代码中可用来生成支持。 这里建议中的运算符重载不应使 asm.js 模型复杂化: asm.js 已经将运算符视为浮点,双精度和无符号整数之间的"重载"。

    不破坏潜在的未来值类型扩展

    • 应该将cowpath平铺到值类型,如前面讨论的,与 SIMD.js. 完成的工作一致
    • BigInts是一种新的基本类型,并且有关联的包装器,与它的他基元和 SIMD.js, 和值类型一样。
    • 值类型的运算符重载可以以遵循类似的Pattern,这样可以以避免双重调度的难题。 由于不支持混合操作数,BigInt没有超级功能,这很难泛化。 混合比较是这个原则的一个例外,但是。
    • L 被建议作为正Int64值的文本后缀。 这里建议使用 n 为以后的( bikeshedding欢迎) 保留空间。

    不破坏JavaScript人机工程学

    这个建议带有运算符重载,以便不使BigInts太难使用。 一个特别的危险,如果BigInts使用 static 方法,就是用户可以以在it--this上使用 + 操作符。 通过包括操作符重载,将BigInts正确添加比将它们转换为数字要更短,这将使这种方法的可能性最小化。

    不破坏一致的JavaScript模型

    这里建议添加了一个新的带有包装器的基元类型,与符号类似。 作为将BigInts集成到JavaScript规范中的一部分,需要很大的严格性来区分在规范中浮动的三种类型: 数学值,BigInts和数字。

    不要破坏网站

    我们需要选择一个兼容的NAME 来添加到全局对象。 有一些担担,NAME Integer 可以能有一个web兼容性风险,尽管我们并没有有关这个的数据。 更改现有数字上执行的现有操作的语义也可以能具有兼容性风险,这里方案避免了这些变化。

    不破坏性能

    这里的设计工作是在V8中与计划的Prototype设计一起完成的;这将用于开发反馈以确保该提议能够有效地实现。

    设计替代在这里不选择

    /uint64

    Brendan Eich以前提出了两个types--signed和无符号 int64/uint64,用于 JavaScript 。 这些都满足了BigInts的许多具体用例。 有一个声明是可以提供更为可以预测的性能;但是,我理解,如果在到处使用适当的强制转换操作符( 比如,BigInt.asUintN ),那么需要像V8这样的实现提供同一个接口的性能相同的性能。 这种方法的风险在于没有harder-to-remove悬悬器,或者者人工工程学对性能敏感的code--we来说会过于糟糕。

    允许混合操作数

    我们可以允许像 1 + 1n 这样的混合操作数返回 2 ( 数字) 。 它将失去精度,更难以高性能实现,而且不适合用户定义的类型。

    现在忽略TypedArrays和数据视图方法

    一种可以能是等待为is类创建一个可以能未来的ssid/rtc方案以及数据视图方法。 然而,它们包括在现有的TypedArrays的Pattern 之后,比内容更为常见的类型返回 Numbers--a 。

    for以后的建议

    函数和常量库( Bug )

    增加整数相关的数学库函数是合理的,特别是可以以根据 CPU的指令更高效地使用。 这包括:

    • Bitcast与数字之间
    • 查找第一个设置/取消设置位
    • Popcount
    • 查找最重要的设置/取消位
    • 用于在特定模量( 。比如,64位 有符号或者无符号) 中进行算术的方便函数,而不需要使用包装函数和算法分别使用。
    • 最大和最小 64位 有符号和无符号整数的常量

    其他任何数值类型,以及对二进制数据和值类型的一般化

    在ES2015开发过程中,增加 64位 整数的建议在值类型/二进制数据方案中被广泛的推广。 这个大建议变得非常复杂和笨拙,所以从ES2015中删除。 当前的建议更小,并且可以以增量的方式构建。 值类型和较小的整数类型可以能是可以以跟随的,这个方案是为了推广,但不是 block 。

    实现状态

    • V8 Georg Neis和 Jakob Kummerow
    • 通过 Caio Lima和 Robin Morisset实现 pmt
    • SpiderMonkey Templeton

    规范

    有关更详细的细节,请参阅规范

    相关规范建议




    Copyright © 2011 HelpLib All rights reserved.    知识分享协议 京ICP备05059198号-3  |  如果智培  |  酷兔英语