库/编程语言如何将浮点数转换为字符串 [英] How do libraries/programming languages convert floats to strings

查看:83
本文介绍了库/编程语言如何将浮点数转换为字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我想找出15岁那年的谜,但我失败了.我仍然不知道答案.

This is a mystery that I was trying to figure out when I was 15, but I failed. I still don't know the answer.

这是一个幼稚且有缺陷的解决方案(就像我在Stack Overflow上看到的其他一些失败的尝试一样):

Here's a naive and flawed solution (like some other failed attempts I've seen here on Stack Overflow):

const numberToString = number => {
  let result = '';
  let multiplier = Math.floor(Math.log10(number));
  while (number > 0) {
    const currentDigit = Math.floor(number / 10 ** multiplier);
    if (multiplier === -1) result += '.';
    result += `${currentDigit}`;
    number -= 10 ** multiplier * currentDigit;
    multiplier -= 1;
  }

  if (multiplier >= 0) {
    result += Array(multiplier + 1)
      .fill('0')
      .join('');
  }
  return result;
};

numberToString(0.3) //.29999999999999998010382707025852380980776467160900842259699366886095386217478302201335914442574948883370288946713085380211028267974348864228883494754227105763273602317743416839701366257194448416238466245093684421946526875873398794558223163136792877759774069929483218021428696258138483228158055137040848084556063610493291767

此处的语言为Javascript,但问题是与语言无关.但是,请尽可能对现有代码进行改进.

The language here is in Javascript, but the question is language agnostic. However, feel free to improve the existing code if it's possible.

如果该方法的工作方式取决于语言,那么我将对一些见解在各种编程语言(例如Javascript)中的外观有所了解.

If the way this works is language dependent, I would appreciate some insights how this might look in various programming languages, for example Javascript.

推荐答案

(我没有足够的声誉来发表评论,所以诉诸于使用答案...)

(I don't have enough reputation to comment, so am resorting to using an answer...)

我注意到您将精度扩展到300位数以上,远远超出了浮点数的精度,因此结果不准确.如果您正在寻找一种可以进行高精度计算的方法,则可以使用BigInt,并相应地扩展数字.(我之所以说是可能的",是因为BigInt可以强制执行固定精度的计算,而不是浮点运算,因此,取决于一个人的目标,BigInt可能无法满足要求.)

I notice that you ran the precision out to 300+ digits, well beyond the precision of the floating point numbers, hence the imprecise result. If you're looking for a means to have high precision calculations, you can probably resort to BigInt, and scale up the numbers accordingly. (I say "probably", because BigInt can be coerced into fixed precision calculations, not floating point, and thus depending on one's goal, BigInt might not meet the requirement.)

例如,可以通过以下函数来处理1000/17到100个有效数字的计算,该功能实质上将1000和17放大以确保100个有效数字.(请注意,这只是一个用于处理两个整数之间的高精度除法的概念函数,但可以通过按比例缩放 dividend divisor 直到它们成为非整数的基础)是整数,并相应地调整数字.此外,您可能需要弄乱一些额外的隐藏"数字精度来处理舍入).

Eg, calculating 1000 / 17 to 100 significant digits can be handled via the following function, which essentially scales up 1000 and 17 to ensure 100 significant digits. (Note that this is just a concept function for handling high precision division between two integers, but can be the basis for non-integers by scaling up the dividend and divisor until they're integers, and adjusting digits accordingly. Plus you might need to fudge in some extra "hidden" digits of precision to handle rounding)...

function divideN(dividend, divisor, digits) {
  dividend = dividend * 10n ** (BigInt(digits) * 2n);
  divisor = divisor * 10n ** BigInt(digits);
  var s = (dividend/divisor).toString();
  if (s.length < digits) {
    s = "0".repeat(digits - s.length) + s;
  }
  s = s.slice(0, s.length - digits) + "." + s.slice(-digits);
  return s;
}

BigInt要求数字以"n"结尾,因此需要按以下方式调用该函数...

BigInt requires numbers to end in "n", so the function needs to be called as follows...

divideN(1000n,17n,100)

...在这种情况下返回...

...which in this case returns...

"58.8235294117647058823529411764705882352941176470588235294117647058823529411764705882352941176470588235"

请注意,在这种情况下,由于除数(1000)对除数(17)的相对大小,返回的精度是102位而不是100位.

Note in this case, 102 digits of precision are returned rather than 100 because of the relative size of the dividend (1000) to the divisor (17).

这篇关于库/编程语言如何将浮点数转换为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆