Есть ли функция JavaScript, которая уменьшает дробь

скажем, у нас есть дробь 2/4, ее можно сократить до 1/2.

Есть ли функция JavaScript, которая может выполнять сокращение?


person dave    schedule 10.01.2011    source источник


Ответы (8)



Чтобы уменьшить дробь, разделите числитель и знаменатель на наибольший общий делитель. Фрогз и Дэвид уже предоставили исходный код.

Однако, если вы ищете библиотеки javascript для обработки дробей, вот несколько на выбор.

  1. Fraction.js
  2. Math.Rational
  3. Ratio.js
  4. Rational.js

Вот пример использования Ratio.js.

var a = Ratio(2,4);

a.toString() == "2/4";
a.simplify().toString() == "1/2";    // reduce() returns a clone of the Ratio()
a.toString() == "2/4"; // Ratio functions are non-destructive.
person Larry Battle    schedule 13.06.2012
comment
Полезно, спасибо. Я разместил вопрос об относительной эффективности этих библиотек здесь: ?noredirect=1#comment22538987_15840390" title="какая самая эффективная библиотека дробей в javascript"> stackoverflow.com/questions/15840390/ - person Omn; 05.04.2013
comment
@Omn Итак, вы уже профилировали производительность с помощью jsperf.com? Если вы видите какие-либо проблемы с Ratio.js, просто откройте тикет, и я постараюсь это исправить. github.com/LarryBattle/Ratio.js - person Larry Battle; 12.04.2013
comment
У меня нет опыта создания и запуска тестов. В итоге я просто зашел в код и посмотрел на то, что, казалось, имело лучший код, комментарии и реализованные функции. Я перестал работать с Ratio.js, но с тех пор у меня не было возможности много работать над этим проектом. Я обязательно дам вам знать, если обнаружу какие-либо проблемы, и я могу просто внести исправления ошибок, если сам увижу проблему. - person Omn; 13.04.2013

Я знаю, что ответ уже есть, но я хочу поделиться библиотекой JS, которую я нашел, когда искал что-то для преобразования десятичных чисел в дроби и сокращения дробей.

Библиотека вызывает Fraction.js, что очень помогло мне и сэкономило мне много времени и работы. . Надеюсь, это может быть очень полезно для кого-то еще!

person Jabel Márquez    schedule 21.10.2014

Я знаю, что это старый пост, но я преобразовал принятый ответ в решение цикла вместо рекурсивной функции. Это было бы намного эффективнее с точки зрения памяти и, вероятно, намного быстрее (не требуются операции стека памяти и вызовы выполнения).

function reduce(numerator, denominator) {
    var a = numerator;
    var b = denominator;
    var c;
    while (b) {
        c = a % b; a = b; b = c;
    }
    return [numerator / a, denominator / a];
}

Объем памяти составляет всего 5 числовых структур и простой цикл.

person flamewave000    schedule 27.01.2021

Вот рекурсивная функция, использующая сокращение ECMAScript 6. Он работает для большинства дробей, если остаток не слишком мал. 0 был переопределен, чтобы он работал с такими массивами, как [1.2, 2.4, 12, 24]. Я тестировал в Chrome и IE Edge, поэтому он может вести себя по-разному в других браузерах или обновлениях. Так что он должен работать с массивом поплавков.

 Array.prototype.gcd = function () {
   if (this.length === 0)
     return null;
   return this.reduce((prev, curr) => {
     if (curr <= 1.00000000001e-12)
       return prev
     else
       return [curr, prev % curr].gcd();
    });
  }

  var reducedValueGCD = [1.2, 2.4, 12, 24, 240].gcd();

Найдите сокращение MDN или дополнительную информацию здесь .

person RetroCoder    schedule 25.09.2016

Сократите строковую дробь, например «2/4», и выведите в виде строковой дроби.

function reduce([numerator, denominator]){
  for (let i = numerator; i > 0; i--) {
    if(!(numerator % i) && !(denominator % i)){
      return [(numerator / i), (denominator / i)];
    }
  }
}

function reduceFraction(string){
  return reduce(string.split('/').map(n => +n)).join('/');
}

one = '2/4';
two = '20/200';
three = '330/2050';

console.log('2/4 reduced to', reduceFraction(one));
console.log('20/200 reduced to', reduceFraction(two));
console.log('330/2050 reduced to', reduceFraction(three));

person SoEzPz    schedule 17.01.2020

В дополнение к Яну я бы изменил его функцию на:

function reduce(numerator,denominator){
var roundNr = 0

if(numerator >= denominator) {
    roundNr = Math.floor(numerator / denominator);
    numerator -= (roundNr * denominator);
}

var gcd = function gcd(a,b){
        return b ? gcd(b, a%b) : a;
};
gcd = gcd(numerator,denominator);
return {roundNr: roundNr, numerator: numerator/gcd, denominator:        denominator/gcd};              }

Это также вернет круглое число, когда числитель ›= знаменатель.

person Andries van Weeren    schedule 12.12.2020

person    schedule
comment
Это очень элегантная gcd функция. Единственное изменение, которое я бы предложил, - это некоторая форма проверки ввода для NaN, поскольку gcd(NaN, 1) выдает 1, где я ожидал бы NaN или ошибку. - person zzzzBov; 09.11.2012
comment
@zzzzBov Интересный крайний случай. Конечно, можно было бы добавить if (isNaN(numerator) || isNaN(denominator)) return NaN; в качестве первой строки. - person Phrogz; 08.01.2013
comment
забавный факт, это решение использует алгоритм Евклида для поиска НОД: en.wikipedia.org/wiki/Euclidean_algorithm - person pgarciacamou; 01.07.2017
comment
Полезный! Обратите внимание, что вы можете захотеть округлить числитель, чтобы получить дроби, которые не превышают знаменатель: reduce(Math.round(.25 * 4), 4)) это сохранит небольшие (оценочные) значения, привязанные к максимальному знаменателю, который вы ему даете. - person dmarr; 16.10.2018
comment
Отлично работает, но зачем дважды указывать имя функции gcd, а затем присваивать числовой результат той же переменной? Это плохой этикет JavaScript. - person Rudey; 21.12.2020