【问题标题】:Convert JavaScript number n to string s such that Object.is(eval(s), n) for all n?将 JavaScript 数字 n 转换为字符串 s,使得 Object.is(eval(s), n) 对所有 n?
【发布时间】:2018-12-14 14:53:23
【问题描述】:

我需要将任意 JavaScript 数字转换为包含 JavaScript 表达式的字符串,这些表达式的值保证与原始数字相同。

一般来说,String() 对大多数值都适用,但值得注意的是 String(-0) 返回 '0',尽管 0 === -0Object.is(0, -0) 返回 false。

是否还有其他数字值n eval(String(n)) 不返回值 n?我特别考虑浮点数不能以十进制精确表示的情况,并且由于舍入/精度不足,String() 选择的表示形式会评估为附近但不同的浮点数。

如果是这样,我如何获得这些数字的eval-able 字符串表示?

【问题讨论】:

  • 你必须照顾-0InfinityNaN。注意后两者是全局对象的属性,理论上可以被遮蔽。当心{ let Infinity = 0; console.log(eval(Infinity)); } 之类的场景(例如,当您仍然使用它时,通过间接的eval 调用访问全局对象)。我认为其他值不会有问题,但我超级累,因此无法保证任何事情。
  • 你关于阴影的观点是很好的,但Infinity-InfinityNaN 都被String() 处理得很好。我担心的值是 eval(String(x)) !== x 的浮点值(如果存在的话)。
  • 明确一点:这个问题主要是关于Number.prototype.toStringeval 使用的算法的准确性/可逆性。
  • 请参阅7.1.12.1 NumberToString 上的“注 1”。我还没有弄清楚在解析文字和将字符串解析为数字之间是否存在隐藏的陷阱,但我非常怀疑。我几乎可以得出结论,除了-0(如注释中所述)和阴影问题或相关问题之外,它应该可以工作。

标签: javascript floating-point type-conversion numbers language-lawyer


【解决方案1】:

带有数字功能

例如:

Number('0') === 0 // true

【讨论】:

  • 我正在尝试将数字转换为字符串。 Number 则相反。
【解决方案2】:

-0 是唯一的例外。引用the spec(注1):

如果 x 是 -0 以外的任何 Number 值,则 ToNumber(ToString(x)) 与 x 完全相同。

请注意,String(x) 的行为是在 x 不是符号 (spec) 时简单地调用 ToString(x)

将数字转换为字符串时不会丢失任何精度。它可能与原始格式不同,但始终代表相同的数字:

console.log( String(1e2) );
console.log( Object.is(1e2,100) );

正如@ASDFGerte 提到的,InfinityNaN 可能会被屏蔽。因此,您可能还想为Infinity-InfinityNaN 添加例外。可能是这样的:

function reversibleNumberToString( x ) {
  if ( Object.is( -0, x ) )
    return '-0';
  const str = String(x);
  switch ( str ) {
    case 'Infinity':
      return '1/0';
    case '-Infinity':
      return '-1/0';
    case 'NaN':
      return '0/0';
    default:
      return str;
  }
}

// Tests
[ 0, 1, Math.random( ), -Infinity, Infinity, NaN ].forEach( x => {
  const Infinity = 'shadowed';
  console.log( Object.is( x, eval( reversibleNumberToString( x ) ) ) );
} );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    相关资源
    最近更新 更多