简体   繁体   English

将分数字符串转换为十进制?

[英]Convert Fraction String to Decimal?

I'm trying to create a javascript function that can take a fraction input string such as '3/2' and convert it to decimal—either as a string '1.5' or number 1.5我正在尝试创建一个 javascript function 可以采用分数输入字符串(例如'3/2'并将其转换为十进制 - 作为字符串'1.5'或数字1.5

function ratio(fraction) {
    var fraction = (fraction !== undefined) ? fraction : '1/1',
    decimal = ??????????;
    return decimal;
});

Is there a way to do this?有没有办法做到这一点?

Since no one has mentioned it yet there is a quick and dirty solution:由于没有人提到它,因此有一个快速而肮脏的解决方案:

var decimal = eval(fraction); 

Which has the perks of correctly evaluating all sorts of mathematical strings.它具有正确评估各种数学字符串的好处。

eval("3/2")    // 1.5
eval("6")      // 6
eval("6.5/.5") // 13, works with decimals (floats)
eval("12 + 3") // 15, you can add subtract and multiply too

People here will be quick to mention the dangers of using a raw eval but I submit this as the lazy mans answer.这里的人们会很快提到使用原始 eval 的危险,但我将此作为懒人的答案提交。

Here is the bare bones minimal code needed to do this:这是执行此操作所需的最少代码:

var a = "3/2";
var split = a.split('/');
var result = parseInt(split[0], 10) / parseInt(split[1], 10);
alert(result); // alerts 1.5

JsFiddle: http://jsfiddle.net/XS4VE/ JsFiddle: http : //jsfiddle.net/XS4VE/

Things to consider:需要考虑的事项:

  • division by zero被零除
  • if the user gives you an integer instead of a fraction, or any other invalid input如果用户给你一个整数而不是一个分数,或者任何其他无效的输入
  • rounding issues (like 1/3 for example)舍入问题(例如 1/3)

I created a nice function to do just that, everything was based off of this question and answers but it will take the string and output the decimal value but will also output whole numbers as well with out errors我创建了一个很好的函数来做到这一点,一切都基于这个问题和答案,但它会接受字符串并输出十进制值,但也会输出整数而没有错误

https://gist.github.com/drifterz28/6971440 https://gist.github.com/drifterz28/6971440

function toDeci(fraction) {
    fraction = fraction.toString();
    var result,wholeNum=0, frac, deci=0;
    if(fraction.search('/') >=0){
        if(fraction.search('-') >=0){
            wholeNum = fraction.split('-');
            frac = wholeNum[1];
            wholeNum = parseInt(wholeNum,10);
        }else{
            frac = fraction;
        }
        if(fraction.search('/') >=0){
            frac =  frac.split('/');
            deci = parseInt(frac[0], 10) / parseInt(frac[1], 10);
        }
        result = wholeNum+deci;
    }else{
        result = fraction
    }
    return result;
}

/* Testing values / examples */
console.log('1 ',toDeci("1-7/16"));
console.log('2 ',toDeci("5/8"));
console.log('3 ',toDeci("3-3/16"));
console.log('4 ',toDeci("12"));
console.log('5 ',toDeci("12.2"));

Something like this:像这样的东西:

bits = fraction.split("/");
return parseInt(bits[0],10)/parseInt(bits[1],10);

I have a function I use to handle integers, mixed fractions (including unicode vulgar fraction characters), and decimals.我有一个用于处理整数、带分数(包括 unicode 粗略分数字符)和小数的函数。 Probably needs some polishing but it works for my purpose (recipe ingredient list parsing).可能需要一些改进,但它适用于我的目的(配方成分列表解析)。

Inputs "2 1/2" , "2½" , "2 ½" , and "2.5" will all return 2.5 .输入"2 1/2""2½""2 ½""2.5"都将返回2.5 Examples:例子:

var numQty = require("numeric-quantity");

numQty("1 1/4") === 1.25;  // true
numQty("3 / 4") === 0.75;  // true
numQty("¼" ) === 0.25;     // true
numQty("2½") === 2.5;      // true
numQty("¾") === 0.75;      // true
numQty("⅓") === 0.333;     // true
numQty("⅔") === 0.667;     // true

One thing it doesn't handle is decimals within the fraction, eg "2.5 / 5" .它不处理的一件事是分数中的小数,例如"2.5 / 5"

Too late, but can be helpful:为时已晚,但可能会有所帮助:

You can use Array.prototype.reduce instead of eval https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce您可以使用Array.prototype.reduce而不是eval https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

ES6 ES6

const fractionStrToDecimal = str => str.split('/').reduce((p, c) => p / c);
console.log(fractionStrToDecimal('1/4/2')); // Logs 0.125
console.log(fractionStrToDecimal('3/2')); // Logs 1.5

CJS CJS

function fractionStrToDecimal(str) {
  return str.split('/').reduce((p, c) => p / c);
}
console.log(fractionStrToDecimal('1/4')); // Logs 0.25

[EDIT] Removed reducer initial value and now the function works for numerators greater than 1. Thanks, James Furey. [编辑] 删除了减速器初始值,现在该函数适用于大于 1 的分子。谢谢,詹姆斯·弗瑞。

Function (ES6):功能(ES6):

function fractionToDecimal(fraction) {
  return fraction
    .split('/')
    .reduce((numerator, denominator, i) =>
      numerator / (i ? denominator : 1)
    );
}

Function (ES6, condensed):功能(ES6,浓缩):

function fractionToDecimal(f) {
  return f.split('/').reduce((n, d, i) => n / (i ? d : 1));
}

Examples:例子:

fractionToDecimal('1/2');     // 0.5
fractionToDecimal('5/2');     // 2.5
fractionToDecimal('1/2/2');   // 0.25
fractionToDecimal('10/5/10'); // 0.2
fractionToDecimal('0/1');     // 0
fractionToDecimal('1/0');     // Infinity
fractionToDecimal('cat/dog'); // NaN

If you don't mind using an external library, math.js offers some useful functions to convert fractions to decimals as well as perform fractional number arithmetic.如果您不介意使用外部库, math.js提供了一些有用的函数来将分数转换为小数以及执行小数运算。

 console.log(math.number(math.fraction("1/3"))); //returns 0.3333333333333333 console.log(math.fraction("1/3") * 9) //returns 3
 <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.20.1/math.js"></script>

To convert a fraction to a decimal, just divide the top number by the bottom number.要将分数转换为小数,只需将顶部数字除以底部数字即可。 5 divided by 3 would be 5/3 or 1.67. 5 除以 3 就是 5/3 或 1.67。 Much like:很像:

function decimal(top,bottom) {
    return (top/bottom)
}

Hope this helps, haha希望能帮到你,哈哈

It works with eval() method but you can use parseFloat method.它适用于 eval() 方法,但您可以使用 parseFloat 方法。 I think it is better!我觉得这样更好! Unfortunately it will work only with that kind of values - "12.2" not with "5/8", but since you can handle with calculation I think this is good approach!不幸的是,它只适用于那种值——“12.2”而不适用于“5/8”,但由于您可以处理计算,我认为这是一个好方法!

If you want to use the result as a fraction and not just get the answer from the string, a library like https://github.com/infusion/Fraction.js would do the job quite well.如果您想将结果用作分数而不只是从字符串中获取答案,像https://github.com/infusion/Fraction.js这样的库可以很好地完成这项工作。

var f = new Fraction("3/2");
console.log(f.toString()); // Returns string "1.5"
console.log(f.valueOf()); // Returns number 1.5

var g = new Fraction(6.5).div(.5);
console.log(f.toString()); // Returns string "13"

Also a bit late to the party, but an alternative to eval() with less security issues (according to MDN at least) is the Function() factory.聚会也有点晚了,但是eval()的替代方案是Function()工厂,但安全问题较少(至少根据 MDN Function()

var fraction = "3/2";
console.log( Function("return (" + fraction + ");")() );

This would output the result "1.5" in the console.这将在控制台中输出结果“1.5”。

Also as a side note: Mixed fractions like 1 1/2 will not work with neither eval() nor the solution with Function() as written as they both stumble on the space.另外作为旁注:像 1 1/2 这样的混合分数不适用于eval()Function()的解决方案,因为它们都偶然发现了空间。

safer eval() according to MDN根据 MDN 更安全的 eval()

const safeEval = (str) => {
   return Function('"use strict";return (' + str + ")")();
}

safeEval("1 1/2") // 1.5

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Do_not_ever_use_eval ! https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Do_not_ever_use_eval

This too will work:这也将起作用:

let y = "2.9/59"
let a = y.split('')
let b = a.splice(a.indexOf("/"))
console.log(parseFloat(a.join('')))
a = parseFloat(a.join(''))
console.log(b)
let c = parseFloat(b.slice(1).join(''))
let d = a/c
console.log(d) // Answer for y fraction

 const fractionStringToNumber = s => s.split("/").map(s => Number(s)).reduce((a, b) => a / b); console.log(fractionStringToNumber("1/2")); console.log(fractionStringToNumber("1/3")); console.log(fractionStringToNumber("3/2")); console.log(fractionStringToNumber("3/1")); console.log(fractionStringToNumber("22/7")); console.log(fractionStringToNumber("355 / 113")); console.log(fractionStringToNumber("8/4/2")); console.log(fractionStringToNumber("3")); // => 3, not "3"

From a readability, step through debugging perspective, this may be easier to follow:从可读性,逐步调试的角度来看,这可能更容易遵循:

// i.e. '1/2' -> .5
// Invalid input returns 0 so impact on upstream callers are less likely to be impacted
function fractionToNumber(fraction = '') {
    const fractionParts = fraction.split('/');
    const numerator = fractionParts[0] || '0';
    const denominator = fractionParts[1] || '1';
    const radix = 10;
    const number = parseInt(numerator, radix) / parseInt(denominator, radix);
    const result = number || 0;

    return result;
}

I developed a function to convert a value using a factor that may be passed as a fraction of integers or decimals.我开发了一个函数来使用可以作为整数或小数的分数传递的因子来转换值。 The user input and conversion factor might not be in the correct format, so it checks for the original value to be a number, as well as that the conversion can be converted to a fraction assuming that /number means 1/number, or there are a numerator and a denominator in the format number/number.用户输入和转换因子的格式可能不正确,因此它会检查原始值是否为数字,以及假设 /number 表示 1/number,或者可以将转换转换为分数数字/数字格式的分子和分母。

/**
 * Convert value using conversion factor
 * @param {float} value - number to convert
 * @param {string} conversion - factor
 * @return {float} converted value
 */
function convertNumber(value, conversion) {
  try {
    let numberValue = eval(value);
    if (isNaN(numberValue)) {
      throw value + " is not a number.";
    }
    let fraction = conversion.toString();
    let divider = fraction.indexOf("/");
    let upper = 1;
    let denominator = 1;
    if (divider == -1) {
      upper = eval(fraction);
    } else {
      let split = fraction.split("/");
      if (split.length > 2) {
        throw fraction + " cannot be evaluated to a fraction.";
      } else {
        denominator = eval(split[1]);
        if (divider > 0) {
          upper = eval(split[0]);
        }
      }
    }
    let factor = upper/denominator;
    if (isNaN(factor)) {
      throw fraction + " cannot be converted to a factor.";
    }
    let result = numberValue * factor;
    if (isNaN(result)) {
      throw numberValue + " * " + factor + " is not a number.";
    }
    return result
  } catch (err) {
    let message = "Unable to convert '" + value + "' using '" + conversion + "'. " + err;
    throw message;
  }
}

You can use eval() with regex to implement a secure method to calculate fraction您可以使用 eval() 和正则表达式来实现计算分数的安全方法

var input = "1/2";
return input.match(/^[0-9\/\.]+$/) != null ? eval(input) : "invalid number";

With modern destructuring syntax, the best/safest answer can be simplified to:使用现代解构语法,最好/最安全的答案可以简化为:

const parseFraction = fraction => {
  const [numerator, denominator] = fraction.split('/').map(Number);
  return numerator / denominator;
}

// example
parseFraction('3/2'); // 1.5

In other words, split the faction by its / symbol, turn both resulting strings into numbers, then return the first number divided by the second...换句话说,通过/符号拆分派系,将两个结果字符串转换为数字,然后返回第一个数字除以第二个数字......

... all with only two (very readable) lines of code. ...全部只有两行(非常易读)代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM