【问题标题】:What is the safest way to split a "Floating Point Number String" into its Whole and Fractional Parts将“浮点数字符串”拆分为其整数和小数部分的最安全方法是什么
【发布时间】:2020-09-18 06:23:55
【问题描述】:

我开发了以下简短函数,将传递给它的数字以字符串格式拆分为 WholeFractional 部分(也输出为字符串)。

注意1:数字的整数部分可以变成大数字(超过50位)。

注意 2:输出结果(整数和分数字符串)不会被转换为整数或浮点数,但由于 Javascript 对大数字的舍入,将仅作为字符串进一步操作.所以回到数字不是问题

因为函数会自动检测机器的区域设置,因此希望用户在其本地机器的区域设置中输入(传递)数字,否则该数字会以编程方式生成并传递给功能。

由于长度非常大,并且没有处理以指数 (e) 格式传递的数字,因此预计该数字将作为“字符串”传递。

该函数使用 toLocaleString() 来检测小数和千位分隔符。

我已经用主要数字系统(.,'空格)测试了这个函数,到目前为止,一切都很好。

问题是,这段代码的安全性如何,是否有其他更好、更安全的方法来执行此操作或进行必要的更正/更改?

谢谢

 function splitFloatString(NumString) {
    var decimalSeparator  = (1.1).toLocaleString().substring(1,2);  // Get Decimal Separator
    var thousandSeparator = (1000).toLocaleString().substring(1,2); // Get Thousands Separator
    NumString += "";                                                // ensure a string
    var fraction ="0";                                              // default no fractional part
    NumString = NumString.replace(RegExp("\\"+thousandSeparator,"g"),"");   //remove thousand separators if any

    if (RegExp("\\"+decimalSeparator,"g").test(NumString)) {        // test for decimal separator
       var n = NumString.split(decimalSeparator);                   // Split at Decimal Seprator
       NumString = n[0];                                            // The Whole part
       if (n.length==2) fraction = n[1];                            // The Fractional part
       if (fraction=="") fraction ="0";
       }

  console.log("Whole: ("+NumString+"), Fraction: ("+fraction+")");  // added for testing
  //return n=[NumString,fraction];                                  // normal return uncomment
}

 //------------------------------------------------------------------------------------
 // Tests assuming user's machine and user enters/passes US-EN separators as an example
 //------------------------------------------------------------------------------------
        splitFloatString("123456789123456699999887788812340786.45678907656912574321115194123123456789");
        splitFloatString("1,234,567,891,234,566,999,998,888,812,340.456520754186789075194123123456789");
        splitFloatString("200")
        splitFloatString("0.")
        splitFloatString(123456.2349999)
        splitFloatString("")
        splitFloatString()

【问题讨论】:

  • 输入来自什么环境?如果也来自 JavaScript,我建议您遇到指数数字 3.51e+41 例如。
  • @AhmedHammad 同意。但这需要添加代码以将指数数字转换为完整的字符串等价物。这是可能的。谢谢

标签: javascript floating-point numbers rounding


【解决方案1】:

在我看来,你只是让整个事情变得不必要地复杂化了。这是实现相同结果的简单方法。

function getLocaleSeparators() {
  const testNumber = 1000.1.toLocaleString()
  return [testNumber.substring(1,2), testNumber.substring(5,6)]
}

function splitFloatString(number) {
  const numberString = number.toString()
  const [thousandSeparator, decimalSeparator] = getLocaleSeparators()
  let [wholePart, fractionPart] = numberString.replace(new RegExp(thousandSeparator, 'g'), '').split(decimalSeparator)
  wholePart = wholePart || "0"
  fractionPart = fractionPart || "0"
  console.log(`Whole: ${wholePart}, Fraction: ${fractionPart}`);
}

function getLocaleSeparators() {
  const testNumber = 1000.1.toLocaleString()
  return [testNumber.substring(1,2), testNumber.substring(5,6)]
}

function splitFloatString(number) {
  const numberString = number.toString()
  const [thousandSeparator, decimalSeparator] = getLocaleSeparators()
  let [wholePart, fractionPart] = numberString.replace(new RegExp(thousandSeparator, 'g'), '').split(decimalSeparator)
  wholePart = wholePart || "0"
  fractionPart = fractionPart || "0"
  console.log(`Whole: ${wholePart}, Fraction: ${fractionPart}`);
}

splitFloatString("123456789123456699999887788812340786.45678907656912574321115194123123456789");
splitFloatString("1,234,567,891,234,566,999,998,888,812,340.456520754186789075194123123456789");
splitFloatString("200")
splitFloatString("0.")
splitFloatString(123456.2349999)
splitFloatString("")

【讨论】:

  • 但是您在这里假设逗号和点是“始终”的分隔符。
  • @MohsenAlyafei 更新了答案。
  • 谢谢。语言环境字符串检测在一条指令中完成。
  • 您可以做的最好的事情是,将参数设置为默认为"",这将返回为0。基本上,function splitFloatString(number = "") 在定义上。
  • 目前的解决方案是处理所有情况。 Ergo,将是当时使用的最安全的部件。
【解决方案2】:

请试试这个。可能会帮助你。

number = "21212.32323";
var numberString = number + ''; // converts into string
var index = numberString.lastIndexOf("."); // get the index
var strFloat, wholeStr;
if(index === -1) {
  strFloat = '';
  wholeStr = numberString.replace(/[^\w\s]/gi, '').replace(/ /g,'')
} else {
 strFloat = numberString.substring(index + 1); // get the decimal part
 var strWhole = numberString.substring(0, index); // get the number
 wholeStr = strWhole.replace(/[^\w\s]/gi, '').replace(/ /g,'') // remove spcl character
}

console.log(`Whole: ${wholeStr}, Fraction: ${strFloat}`);

是的,您不能在 javascript 中超过 MAX_SAFE_INTEGER,即 32 位。 What is JavaScript's highest integer value that a number can go to without losing precision?

【讨论】:

  • 对于输入number = "212122121",输出为:"Whole: , Fraction: 212122121"。即整数被视为分数。
  • 更新答案请查收。
【解决方案3】:

终于可以得到我想要的最终答案了。

感谢大家的帮助和想法:

function numberSplit (NumString) {
  var decimalSep  = 1.1.toLocaleString().substring(1,2),  // Get Deciaml Separator
      thousandSep = 1e3.toLocaleString().substring(1,2),  // Get Thousand Separator
      fraction    = "0",                                  // Default "0"
      n = (NumString = (NumString +="").replace(RegExp("\\"+thousandSep,"g"),"")).split(decimalSep);
  NumString = n[0] ;                              // Get Whole Part
  NumString == "" && (NumString = undefined);     // Whole = undefined if empty
  n.length  == 2  && (fraction  = n[1]);          // Get Fractional part (only if 1 decimal place)
  fraction  == "" && (fraction  = "0");           // Fraction = 0 if empty

console.log("Whole: ("+NumString+"), Fraction: ("+fraction+")")
}
  
//-----------------------------------------------------------
// Ttests assuming user enters US-EN separators as an example
//-----------------------------------------------------------
numberSplit("123456789123456699999887788812340786.45678907656912574321115194123123456789");
numberSplit("1,234,567,891,234,566,999,998,888,812,340.456520754186789075194123123456789");
numberSplit("200")
numberSplit("0.")
numberSplit(123456.2349999)
numberSplit("1.2.3");           // Fractional part ignored as invalid
numberSplit("")                 // Return undefined
numberSplit()                   // Return undefined
numberSplit(NaN)                // Return NaN
numberSplit(undefined)          // Return undefined

【讨论】:

    【解决方案4】:

    我建议您将math.floor 函数用于此类目的。

    它将作为参数传递的数字向下舍入到最接近的整数:

    另外,Math.ceil() 函数将数字向上舍入为下一个最大的整数或整数。

    对于其他方便的选项,您可以查看此https://www.w3docs.com/snippets/javascript/how-to-convert-a-float-number-to-whole-number-in-javascript.html

    【讨论】:

    • 但这会四舍五入,大量的分数会丢失
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多