Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
比较Javascript中的十进制字符串_Javascript_Node.js_String_Floating Point_Numbers - Fatal编程技术网

比较Javascript中的十进制字符串

比较Javascript中的十进制字符串,javascript,node.js,string,floating-point,numbers,Javascript,Node.js,String,Floating Point,Numbers,我有两个字符串的输入,每个字符串表示十进制格式的非负有理数 给定这两个字符串x和y,我想检查x表示的数值是否大于y表示的数值 这两个值可以非常大,也可以扩展到非常高的精度(即小数点后的许多数字) 因此,我不能依靠Number(x)>Number(y)来完成这项工作 相反,我实现了以下功能: function isLarger(x, y) { const xParts = x.split(".").concat(""); const yParts = y.split(".").co

我有两个字符串的输入,每个字符串表示十进制格式的非负有理数

给定这两个字符串
x
y
,我想检查
x
表示的数值是否大于
y
表示的数值

这两个值可以非常大,也可以扩展到非常高的精度(即小数点后的许多数字)

因此,我不能依靠
Number(x)>Number(y)
来完成这项工作

相反,我实现了以下功能:

function isLarger(x, y) {
    const xParts = x.split(".").concat("");
    const yParts = y.split(".").concat("");
    xParts[0] = xParts[0].padStart(yParts[0].length, "0");
    yParts[0] = yParts[0].padStart(xParts[0].length, "0");
    xParts[1] = xParts[1].padEnd  (yParts[1].length, "0");
    yParts[1] = yParts[1].padEnd  (xParts[1].length, "0");
    return xParts.join("").localeCompare(yParts.join("")) == 1;
}
我进行了广泛的测试,通过生成随机输入
x
y
,并将
isLarger(x,y)
的结果与表达式
Number(x)>Number(y)
的值进行比较

当然,出于上述原因,我不能依赖表达式
Number(x)>Number(y)
的值来纠正每个可能的输入
x
y

因此,我想就上述功能获得一些反馈:

  • 里面有什么警告吗
  • 有没有更简单的方法来实现这一点

    • 我看不出您的解决方案中有任何警告,但最后一行不必要地复杂。而不是

      返回xParts.join(“”).localeCompare(yParts.join(“”))==1

      您可以简单地使用以下内容:

      返回xParts.join(“”)>yParts.join(“”)

      对输入值有一些限制的更简单的解决方案 如果您可以绝对确定您的输入永远不会包含不必要的前导零的数字(例如
      001
      而不是
      1
      )或以点开头的十进制数字(例如
      .1
      而不是
      0.1
      )通过首先比较整数部分中的位数,可以显著简化比较

      整数部分的位数越多表示数字越大,位数越少表示数字越小

      当整数位数相同时,简单的字符串比较基本上就足够了。如果
      x
      等于
      y
      ,但包含更多的尾随零(因为
      '211.00'>'211.0'
      true
      ),则只需要一个填充操作-
      y
      需要用尾随零填充,以避免得到真实的结果


      我对你的测试方法有个警告。根据我对问题和评论的理解,我实施了它。为了测试测试方法,我在
      isLarger
      中引入了一个严重错误,完全忽略了小数点后的部分

      即使有如此严重的错误,我在10000000次运行中也有5次失败,相当于每百万次运行中有0.5次失败

      我认为你需要一个测试方法,在更多的情况下,部分数字匹配

      这是我的节目:

      function isLarger(x, y) {
          const xParts = x.split(".").concat("");
          const yParts = y.split(".").concat("");
          xParts[0] = xParts[0].padStart(yParts[0].length, "0");
          yParts[0] = yParts[0].padStart(xParts[0].length, "0");
          xParts[1] = xParts[1].padEnd(yParts[1].length, "0");
          yParts[1] = yParts[1].padEnd(xParts[1].length, "0");
          xParts[1] = "";
          yParts[1] = "";
          return xParts.join("").localeCompare(yParts.join("")) == 1;
      }
      
      function testIt(x, y) {
          const actual = isLarger(x, y);
          const expected = Number(x) > Number(y);
          if (actual != expected) {
              console.log("x=" + x + " y=" + y + " actual " + actual + " expected "
                      + expected);
          }
      }
      
      function randAsString() {
          return (Math.random() * 1000000).toString();
      }
      
      testIt("3.3", "3.2");
      for (var i = 0; i < 10000000; i++) {
          testIt(randAsString(), randAsString());
      }
      
      函数isLarger(x,y){
      const xParts=x.split(“.”)。concat(“”);
      const yParts=y.split(“.”)。concat(“”);
      xParts[0]=xParts[0]。焊盘起始(yParts[0]。长度,“0”);
      yParts[0]=yParts[0]。焊盘起始(xParts[0]。长度,“0”);
      xParts[1]=xParts[1]。焊盘端(yParts[1]。长度,“0”);
      yParts[1]=yParts[1]。焊盘端(xParts[1]。长度,“0”);
      xParts[1]=“”;
      yParts[1]=“”;
      返回xParts.join(“”).localeCompare(yParts.join(“”)==1;
      }
      功能测试(x,y){
      实际常数=isLarger(x,y);
      预期常数=数量(x)>数量(y);
      如果(实际!=预期){
      console.log(“x=“+x+”y=“+y+”实际值“+实际值+”预期值”
      +预期);
      }
      }
      函数randaString(){
      return(Math.random()*1000000.toString();
      }
      测试(“3.3”、“3.2”);
      对于(变量i=0;i<10000000;i++){
      testIt(randaString(),randaString());
      }
      
      你有一些关于结果的例子吗?@NinaScholz:我多次调用它,将
      x
      y
      设置为
      (Math.random()*1000000)。toString()
      。然后将其输出与
      Number(x)>Number(y)
      进行比较。结果似乎总是成立的,但就像我说的-我怎么能相信编号(x)>编号(y)
      ?另外,正如您所看到的,我生成的输入没有包含非常大的值。我没有看到任何即时的警告。有一些库可以处理大小数,比如,但不知道它们在性能上与您的实现相比如何。@RobbyCornelissen:谢谢。我试图避免使用
      BigNumber.js
      Decimal.js
      ,并将其保存在“原生”js中。您肯定可以稍微优化一下实现。例如,仅比较整数部分的长度可能会消除许多后续的填充和字符串比较。谢谢。是否确定
      返回xParts.join(“”>yParts.join(“”)?@goodvibration是的,我确信这一点。请参阅JS中字符串的简单比较。(如果不信任随机源,请参阅。)
      localeCompare
      用于对字符串进行特殊的区域设置感知字母顺序比较(以确保例如
      a
      位于
      b
      之前,即使其代码点值不在前面)@goodvibration我已编辑代码,以说明y不包含小数点的可能性。(我的原始代码返回了
      x=20.1
      y=20
      的错误结果,因为y被填充到
      2000
      ,而不是
      20.0
      小于
      '0'
      )。谢谢。我只修改了您的
      xParts.join(“”>yParts.join(“”)建议,因为如果我的原始代码中没有任何警告,那么我希望尽可能简单(如果需要,在性能方面)。谢谢
      
      function isLarger(x, y) {
          const xParts = x.split(".").concat("");
          const yParts = y.split(".").concat("");
          xParts[0] = xParts[0].padStart(yParts[0].length, "0");
          yParts[0] = yParts[0].padStart(xParts[0].length, "0");
          xParts[1] = xParts[1].padEnd(yParts[1].length, "0");
          yParts[1] = yParts[1].padEnd(xParts[1].length, "0");
          xParts[1] = "";
          yParts[1] = "";
          return xParts.join("").localeCompare(yParts.join("")) == 1;
      }
      
      function testIt(x, y) {
          const actual = isLarger(x, y);
          const expected = Number(x) > Number(y);
          if (actual != expected) {
              console.log("x=" + x + " y=" + y + " actual " + actual + " expected "
                      + expected);
          }
      }
      
      function randAsString() {
          return (Math.random() * 1000000).toString();
      }
      
      testIt("3.3", "3.2");
      for (var i = 0; i < 10000000; i++) {
          testIt(randAsString(), randAsString());
      }