Как преобразовать плавания в человекочитаемые части?

Я понимаю, что это очень старое сообщение и уже есть отличные ответы, но я хотел сделать простой MCVE, чтобы продемонстрировать один такой подход и позволить новым кодеру быстро увидеть концепцию в действии.

В этом примере мы будем использовать 5 файлов:

  1. Main.java - просто используется для запуска приложения и вызова первого контроллера.
  2. Controller1.java - контроллер для первого макета FXML.
  3. Controller2.java - контроллер для второго макета FXML.
  4. Layout1.fxml - макет FXML для первого сцена.
  5. Layout2.fxml - макет FXML для второй сцены.

Все файлы перечислены полностью в нижней части этого сообщения.

Цель: показать переданные значения от Controller1 до Controller2 и наоборот.

Поток программы:

  • Первая сцена содержит TextField, Button и Label. Когда щелчок Button щелкнут, второе окно загружается и отображается, включая текст, введенный в TextField.
  • Внутри второй сцены есть также TextField, Button , и Label. Label отобразит текст, введенный в TextField на первой сцене.
  • При вводе текста во второй сцене TextField и нажатии Button первая сцена Label сцены обновлен, чтобы показать введенный текст.

Это очень простая демонстрация и, безусловно, может означать некоторое улучшение, но должна сделать концепцию очень понятной.

Сам код также комментируется некоторые детали того, что происходит и как.

КОД

Main.java:

import javafx.application.Application;
import javafx.stage.Stage;

public class Main extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        // Create the first controller, which loads Layout1.fxml within its own constructor
        Controller1 controller1 = new Controller1();

        // Show the new stage
        controller1.showStage();

    }
}

Controller1.java:

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

import java.io.IOException;

public class Controller1 {

    // Holds this controller's Stage
    private final Stage thisStage;

    // Define the nodes from the Layout1.fxml file. This allows them to be referenced within the controller
    @FXML
    private TextField txtToSecondController;
    @FXML
    private Button btnOpenLayout2;
    @FXML
    private Label lblFromController2;

    public Controller1() {

        // Create the new stage
        thisStage = new Stage();

        // Load the FXML file
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Layout1.fxml"));

            // Set this class as the controller
            loader.setController(this);

            // Load the scene
            thisStage.setScene(new Scene(loader.load()));

            // Setup the window/stage
            thisStage.setTitle("Passing Controllers Example - Layout1");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Show the stage that was loaded in the constructor
     */
    public void showStage() {
        thisStage.showAndWait();
    }

    /**
     * The initialize() method allows you set setup your scene, adding actions, configuring nodes, etc.
     */
    @FXML
    private void initialize() {

        // Add an action for the "Open Layout2" button
        btnOpenLayout2.setOnAction(event -> openLayout2());
    }

    /**
     * Performs the action of loading and showing Layout2
     */
    private void openLayout2() {

        // Create the second controller, which loads its own FXML file. We pass a reference to this controller
        // using the keyword [this]; that allows the second controller to access the methods contained in here.
        Controller2 controller2 = new Controller2(this);

        // Show the new stage/window
        controller2.showStage();

    }

    /**
     * Returns the text entered into txtToSecondController. This allows other controllers/classes to view that data.
     */
    public String getEnteredText() {
        return txtToSecondController.getText();
    }

    /**
     * Allows other controllers to set the text of this layout's Label
     */
    public void setTextFromController2(String text) {
        lblFromController2.setText(text);
    }
}

Controller2.java:

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

import java.io.IOException;

public class Controller2 {

    // Holds this controller's Stage
    private Stage thisStage;

    // Will hold a reference to the first controller, allowing us to access the methods found there.
    private final Controller1 controller1;

    // Add references to the controls in Layout2.fxml
    @FXML
    private Label lblFromController1;
    @FXML
    private TextField txtToFirstController;
    @FXML
    private Button btnSetLayout1Text;

    public Controller2(Controller1 controller1) {
        // We received the first controller, now let's make it usable throughout this controller.
        this.controller1 = controller1;

        // Create the new stage
        thisStage = new Stage();

        // Load the FXML file
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Layout2.fxml"));

            // Set this class as the controller
            loader.setController(this);

            // Load the scene
            thisStage.setScene(new Scene(loader.load()));

            // Setup the window/stage
            thisStage.setTitle("Passing Controllers Example - Layout2");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Show the stage that was loaded in the constructor
     */
    public void showStage() {
        thisStage.showAndWait();
    }

    @FXML
    private void initialize() {

        // Set the label to whatever the text entered on Layout1 is
        lblFromController1.setText(controller1.getEnteredText());

        // Set the action for the button
        btnSetLayout1Text.setOnAction(event -> setTextOnLayout1());
    }

    /**
     * Calls the "setTextFromController2()" method on the first controller to update its Label
     */
    private void setTextOnLayout1() {
        controller1.setTextFromController2(txtToFirstController.getText());
    }

}

Layout1.fxml:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<AnchorPane xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
    <VBox alignment="CENTER" spacing="10.0">
        <padding>
            <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
        </padding>
        <Label style="-fx-font-weight: bold;" text="This is Layout1!"/>
        <HBox alignment="CENTER_LEFT" spacing="10.0">
            <Label text="Enter Text:"/>
            <TextField fx:id="txtToSecondController"/>
            <Button fx:id="btnOpenLayout2" mnemonicParsing="false" text="Open Layout2"/>
        </HBox>
        <VBox alignment="CENTER">
            <Label text="Text From Controller2:"/>
            <Label fx:id="lblFromController2" text="Nothing Yet!"/>
        </VBox>
    </VBox>
</AnchorPane>

Layout2.fxml:

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<AnchorPane xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
    <VBox alignment="CENTER" spacing="10.0">
        <padding>
            <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
        </padding>
        <Label style="-fx-font-weight: bold;" text="Welcome to Layout 2!"/>
        <VBox alignment="CENTER">
            <Label text="Text From Controller1:"/>
            <Label fx:id="lblFromController1" text="Nothing Yet!"/>
        </VBox>
        <HBox alignment="CENTER_LEFT" spacing="10.0">
            <Label text="Enter Text:"/>
            <TextField fx:id="txtToFirstController"/>
            <Button fx:id="btnSetLayout1Text" mnemonicParsing="false" text="Set Text on Layout1"/>
        </HBox>
    </VBox>
</AnchorPane>
100
задан George Stocker 9 December 2008 в 02:51
поделиться

17 ответов

Я нашел, что David Eppstein находит, что рациональное приближение к данному коду вещественного числа C точно, что Вы просите. На основе теории непрерывных дробей и очень быстрый и довольно компактный.

я использовал версии настроенного для определенного числителя и пределов знаменателя.

/*
** find rational approximation to given real number
** David Eppstein / UC Irvine / 8 Aug 1993
**
** With corrections from Arno Formella, May 2008
**
** usage: a.out r d
**   r is real number to approx
**   d is the maximum denominator allowed
**
** based on the theory of continued fractions
** if x = a1 + 1/(a2 + 1/(a3 + 1/(a4 + ...)))
** then best approximation is found by truncating this series
** (with some adjustments in the last term).
**
** Note the fraction can be recovered as the first column of the matrix
**  ( a1 1 ) ( a2 1 ) ( a3 1 ) ...
**  ( 1  0 ) ( 1  0 ) ( 1  0 )
** Instead of keeping the sequence of continued fraction terms,
** we just keep the last partial product of these matrices.
*/

#include <stdio.h>

main(ac, av)
int ac;
char ** av;
{
    double atof();
    int atoi();
    void exit();

    long m[2][2];
    double x, startx;
    long maxden;
    long ai;

    /* read command line arguments */
    if (ac != 3) {
        fprintf(stderr, "usage: %s r d\n",av[0]);  // AF: argument missing
        exit(1);
    }
    startx = x = atof(av[1]);
    maxden = atoi(av[2]);

    /* initialize matrix */
    m[0][0] = m[1][1] = 1;
    m[0][1] = m[1][0] = 0;

    /* loop finding terms until denom gets too big */
    while (m[1][0] *  ( ai = (long)x ) + m[1][1] <= maxden) {
        long t;
        t = m[0][0] * ai + m[0][1];
        m[0][1] = m[0][0];
        m[0][0] = t;
        t = m[1][0] * ai + m[1][1];
        m[1][1] = m[1][0];
        m[1][0] = t;
        if(x==(double)ai) break;     // AF: division by zero
        x = 1/(x - (double) ai);
        if(x>(double)0x7FFFFFFF) break;  // AF: representation failure
    } 

    /* now remaining x is between 0 and 1/ai */
    /* approx as either 0 or 1/m where m is max that will fit in maxden */
    /* first try zero */
    printf("%ld/%ld, error = %e\n", m[0][0], m[1][0],
           startx - ((double) m[0][0] / (double) m[1][0]));

    /* now try other possibility */
    ai = (maxden - m[1][1]) / m[1][0];
    m[0][0] = m[0][0] * ai + m[0][1];
    m[1][0] = m[1][0] * ai + m[1][1];
    printf("%ld/%ld, error = %e\n", m[0][0], m[1][0],
           startx - ((double) m[0][0] / (double) m[1][0]));
}
67
ответ дан mpen 5 November 2019 в 11:55
поделиться

Поскольку многие люди заявили, что Вы действительно не можете преобразовать плавающую точку назад в часть (если его чрезвычайно точное как.25). Конечно, Вы могли создать некоторый тип, ищут большой массив частей и используют своего рода нечеткую логику для приведения к результату, который Вы ищете. Снова это не было бы точно, хотя и необходимо будет определить нижние границы как большой Ваш хотеть, чтобы знаменатель пошел.

.32 < x <.34 = 1/3 или что-то как этот.

0
ответ дан Tim 5 November 2019 в 11:55
поделиться

Вы собираетесь иметь две основных проблемы, которые сделают это трудно:

1) Плавающая точка не является точным представлением, что означает, что, если у Вас есть часть "x/y", который приводит к значению "z", Ваш дробный алгоритм может возвратить результат кроме "x/y".

2) существует бесконечность намного больше иррациональных чисел, чем рациональный. Рациональное число является тем, которое может быть представлено как часть. Неразумного существа, которые не могут.

Однако в дешевом виде пути, так как плавающая точка имеет предельную точность, тогда можно всегда представлять его как некоторую форму фракции. (Я думаю...)

1
ответ дан Torlack 5 November 2019 в 11:55
поделиться

Можно сделать это на любом языке программирования с помощью следующих шагов:

  1. Умножаются и Делятся на 10^x, где x является питанием 10 требуемых удостовериться, что число не имеет никаких остающихся десятичных разрядов. Пример: Умножьтесь 0.33 10^2 = 100 для создания его 33, и разделиться это на то же для получения 33/100
  2. Уменьшает числитель и знаменатель получающейся части факторизацией, пока Вы больше не можете получать целые числа из результата.
  3. получающаяся уменьшенная часть должна быть Вашим ответом.

Пример: 0,2 =0.2 x 10^1/10^1 =2/10 =1/5

Так, которые могут быть считаны как '1 часть из 5'

2
ответ дан Pascal 5 November 2019 в 11:55
поделиться

Одно решение состоит в том, чтобы просто сохранить все числа как рациональные числа во-первых. Существуют библиотеки для арифметики рационального числа (например, GMP). При использовании языка OO можно быть в состоянии просто использовать библиотеку классов рационального числа для замены класса числа.

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

, Конечно, это будет намного медленнее, таким образом, это не сможет быть практично для Вас. Зависит от того, сколько вычислений необходимо сделать, и насколько важный точность для Вас.

a = rational(1);
b = rational(3);
c = a / b;

print (c.asFraction)  --->  "1/3"
print (c.asFloat) ----> "0.333333"
2
ответ дан robottobor 5 November 2019 в 11:55
поделиться

"Скажем, мы имеем 0.33, мы должны произвести "1/3"".

, Какую точность Вы ожидаете "решение" иметь? 0.33 не равно 1/3. Как Вы распознаете "пользу" (легкий читать) ответ?

, Неважно, каков, возможный алгоритм мог быть:

, Если Вы ожидаете находить самую близкую часть в форме X/Y, где Y является менее тогда 10, тогда можно циклично выполниться, хотя все 9 возможных Ys, для каждого Y вычисляют X, и затем выбирают самый точный.

4
ответ дан Suma 5 November 2019 в 11:55
поделиться

Часть проблемы - то, что столько частей на самом деле легко не истолковано как части. Например, 0.33 не 1/3, это - 33/100. Но если Вы помните свое обучение начальной школы, тогда существует процесс преобразования десятичных значений в части, однако это вряд ли даст Вам, что Вы хотите, так как большинство десятичных чисел времени не хранится в 0,33, но 0.329999999999998 или некоторые такой.

Делают себе одолжение и не беспокоятся этим, но если Вы должны тогда, можно сделать следующее:

Умножают исходное значение на 10, пока Вы не удаляете дробную часть. Сохраните то число и используйте его в качестве делителя. Тогда сделайте ряд упрощений путем поиска общих знаменателей.

Так 0.4 был бы 4/10. Вы тогда искали бы общие делители, запускающиеся с низких значений, вероятно, простые числа. Начиная с 2, Вы видели бы, делит ли 2 и числитель и знаменатель равномерно путем проверки, совпадает ли этаж подразделения с самим подразделением.

floor(5/2) = 2
5/2 = 2.5

Так 5 не делится 2 равномерно. Таким образом Вы проверяете следующее число, говорите 3. Вы делаете это, пока Вы не нападаете или выше квадратного корня меньшего числа.

После того, как Вы сделаете это тогда, Вам нужно

5
ответ дан Orion Adrian 5 November 2019 в 11:55
поделиться

Строгое-Brocot Дерево вызывает довольно естественный способ приблизить вещественные числа частями с простыми знаменателями.

7
ответ дан Doug McClean 5 November 2019 в 11:55
поделиться

Вы могли бы хотеть считать , Что Каждый Программист Должен Знать об Арифметике С плавающей точкой .

необходимо будет определить некоторую точность путем умножения большим количеством:

3.141592 * 1000000 = 3141592

тогда можно сделать часть:

3 + (141592 / 1000000)

и уменьшают через GCD...

3 + (17699 / 125000)

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

10
ответ дан nlucaroni 5 November 2019 в 11:55
поделиться

Вот ссылка, объясняя математику позади преобразования десятичного числа к части:

http://www.webmath.com/dec2fract.html

И вот является функцией в качестве примера для того, как на самом деле сделать это с помощью VB (с www.freevbcode.com/ShowCode.asp?ID=582):

Public Function Dec2Frac(ByVal f As Double) As String

   Dim df As Double
   Dim lUpperPart As Long
   Dim lLowerPart As Long

   lUpperPart = 1
   lLowerPart = 1

   df = lUpperPart / lLowerPart
   While (df <> f)
      If (df < f) Then
         lUpperPart = lUpperPart + 1
      Else
         lLowerPart = lLowerPart + 1
         lUpperPart = f * lLowerPart
      End If
      df = lUpperPart / lLowerPart
   Wend
Dec2Frac = CStr(lUpperPart) & "/" & CStr(lLowerPart)
End Function

(От поисков Google: преобразуйте десятичное число, чтобы фракционировать, преобразовать десятичное число для фракционирования кода)

16
ответ дан devinmoore 5 November 2019 в 11:55
поделиться

Если вывод должен произвести читателю быстрое впечатление от порядка результата, это не имеет смысла возвратить что-то как "113/211", таким образом, вывод должен ограничить себя использованием однозначных чисел (и возможно 1/10 и 9/10). Если так, можно заметить, что существуют только 27 отличающиеся части.

, Так как базовая математика для генерации вывода никогда не будет изменяться, решением могло быть только к твердому коду дерево двоичного поиска, так, чтобы функция работала в большей части журнала (27) ~ = 4 3/4 сравнения. Вот протестированная версия C кода

char *userTextForDouble(double d, char *rval)
{
    if (d == 0.0)
        return "0";

    // TODO: negative numbers:if (d < 0.0)...
    if (d >= 1.0)
        sprintf(rval, "%.0f ", floor(d));
    d = d-floor(d); // now only the fractional part is left

    if (d == 0.0)
        return rval;

    if( d < 0.47 )
    {
        if( d < 0.25 )
        {
            if( d < 0.16 )
            {
                if( d < 0.12 ) // Note: fixed from .13
                {
                    if( d < 0.11 )
                        strcat(rval, "1/10"); // .1
                    else
                        strcat(rval, "1/9"); // .1111....
                }
                else // d >= .12
                {
                    if( d < 0.14 )
                        strcat(rval, "1/8"); // .125
                    else
                        strcat(rval, "1/7"); // .1428...
                }
            }
            else // d >= .16
            {
                if( d < 0.19 )
                {
                    strcat(rval, "1/6"); // .1666...
                }
                else // d > .19
                {
                    if( d < 0.22 )
                        strcat(rval, "1/5"); // .2
                    else
                        strcat(rval, "2/9"); // .2222...
                }
            }
        }
        else // d >= .25
        {
            if( d < 0.37 ) // Note: fixed from .38
            {
                if( d < 0.28 ) // Note: fixed from .29
                {
                    strcat(rval, "1/4"); // .25
                }
                else // d >=.28
                {
                    if( d < 0.31 )
                        strcat(rval, "2/7"); // .2857...
                    else
                        strcat(rval, "1/3"); // .3333...
                }
            }
            else // d >= .37
            {
                if( d < 0.42 ) // Note: fixed from .43
                {
                    if( d < 0.40 )
                        strcat(rval, "3/8"); // .375
                    else
                        strcat(rval, "2/5"); // .4
                }
                else // d >= .42
                {
                    if( d < 0.44 )
                        strcat(rval, "3/7"); // .4285...
                    else
                        strcat(rval, "4/9"); // .4444...
                }
            }
        }
    }
    else
    {
        if( d < 0.71 )
        {
            if( d < 0.60 )
            {
                if( d < 0.55 ) // Note: fixed from .56
                {
                    strcat(rval, "1/2"); // .5
                }
                else // d >= .55
                {
                    if( d < 0.57 )
                        strcat(rval, "5/9"); // .5555...
                    else
                        strcat(rval, "4/7"); // .5714
                }
            }
            else // d >= .6
            {
                if( d < 0.62 ) // Note: Fixed from .63
                {
                    strcat(rval, "3/5"); // .6
                }
                else // d >= .62
                {
                    if( d < 0.66 )
                        strcat(rval, "5/8"); // .625
                    else
                        strcat(rval, "2/3"); // .6666...
                }
            }
        }
        else
        {
            if( d < 0.80 )
            {
                if( d < 0.74 )
                {
                    strcat(rval, "5/7"); // .7142...
                }
                else // d >= .74
                {
                    if(d < 0.77 ) // Note: fixed from .78
                        strcat(rval, "3/4"); // .75
                    else
                        strcat(rval, "7/9"); // .7777...
                }
            }
            else // d >= .8
            {
                if( d < 0.85 ) // Note: fixed from .86
                {
                    if( d < 0.83 )
                        strcat(rval, "4/5"); // .8
                    else
                        strcat(rval, "5/6"); // .8333...
                }
                else // d >= .85
                {
                    if( d < 0.87 ) // Note: fixed from .88
                    {
                        strcat(rval, "6/7"); // .8571
                    }
                    else // d >= .87
                    {
                        if( d < 0.88 ) // Note: fixed from .89
                        {
                            strcat(rval, "7/8"); // .875
                        }
                        else // d >= .88
                        {
                            if( d < 0.90 )
                                strcat(rval, "8/9"); // .8888...
                            else
                                strcat(rval, "9/10"); // .9
                        }
                    }
                }
            }
        }
    }

    return rval;
}
21
ответ дан Jon 5 November 2019 в 11:55
поделиться

Необходимо будет выяснить, какой уровень ошибки Вы готовы принять. Не все десятичные дроби уменьшат до простой дроби. Я, вероятно, выбрал бы легко делимое число, как 60, и выяснил бы, сколько 60 тыс является самым близким к значению, затем упростите часть.

2
ответ дан Mark Bessey 5 November 2019 в 11:55
поделиться

Вот Perl и версии JavaScript кода VB, предложенного devinmoore:

Perl:

sub dec2frac {
    my $d = shift;

    my $df  = 1;
    my $top = 1;
    my $bot = 1;

    while ($df != $d) {
      if ($df < $d) {
        $top += 1;
      }
      else {
         $bot += 1;
         $top = int($d * $bot);
      }
      $df = $top / $bot;
   }
   return "$top/$bot";
}

И почти идентичный JavaScript:

function dec2frac(d) {

    var df = 1;
    var top = 1;
    var bot = 1;

    while (df != d) {
        if (df < d) {
            top += 1;
        }
        else {
            bot += 1;
            top = parseInt(d * bot);
        }
        df = top / bot;
    }
    return top + '/' + bot;
}
9
ответ дан mivk 24 November 2019 в 04:51
поделиться

Это не «алгоритм», а просто решение Python: http://docs.python.org/library/fractions.html

>>> from fractions import Fraction
>>> Fraction('3.1415926535897932').limit_denominator(1000)
Fraction(355, 113)
5
ответ дан 24 November 2019 в 04:51
поделиться

На Python 2.6 есть модуль фракций .

(Цитата из документов)

>>> from fractions import Fraction
>>> Fraction('3.1415926535897932').limit_denominator(1000)
Fraction(355, 113)

>>> from math import pi, cos
>>> Fraction.from_float(cos(pi/3))
Fraction(4503599627370497, 9007199254740992)
>>> Fraction.from_float(cos(pi/3)).limit_denominator()
Fraction(1, 2)
25
ответ дан 24 November 2019 в 04:51
поделиться

Завершил приведенный выше код и преобразовал его в as3

public static function toFrac(f:Number) : String
    {
        if (f>1)
        {
            var parte1:int;
            var parte2:Number;
            var resultado:String;
            var loc:int = String(f).indexOf(".");
            parte2 = Number(String(f).slice(loc, String(f).length));
            parte1 = int(String(f).slice(0,loc));
            resultado = toFrac(parte2);
            parte1 *= int(resultado.slice(resultado.indexOf("/") + 1, resultado.length)) + int(resultado.slice(0, resultado.indexOf("/")));
            resultado = String(parte1) +  resultado.slice(resultado.indexOf("/"), resultado.length)
            return resultado;
        }
        if( f < 0.47 )
            if( f < 0.25 )
                if( f < 0.16 )
                    if( f < 0.13 )
                        if( f < 0.11 )
                            return "1/10";
                        else
                            return "1/9";
                    else
                        if( f < 0.14 )
                            return "1/8";
                        else
                            return "1/7";
                else
                    if( f < 0.19 )
                        return "1/6";
                    else
                        if( f < 0.22 )
                            return "1/5";
                        else
                            return "2/9";
            else
                if( f < 0.38 )
                    if( f < 0.29 )
                        return "1/4";
                    else
                        if( f < 0.31 )
                            return "2/7";
                        else
                            return "1/3";
                else
                    if( f < 0.43 )
                        if( f < 0.40 )
                            return "3/8";
                        else
                            return "2/5";
                    else
                        if( f < 0.44 )
                            return "3/7";
                        else
                            return "4/9";
        else
            if( f < 0.71 )
                if( f < 0.60 )
                    if( f < 0.56 )
                        return "1/2";
                    else
                        if( f < 0.57 )
                            return "5/9";
                        else
                            return "4/7";
                else
                    if( f < 0.63 )
                        return "3/5";
                    else
                        if( f < 0.66 )
                            return "5/8";
                        else
                            return "2/3";
            else
                if( f < 0.80 )
                    if( f < 0.74 )
                        return "5/7";
                    else
                        if(f < 0.78 )
                            return "3/4";
                        else
                            return "7/9";
                else
                    if( f < 0.86 )
                        if( f < 0.83 )
                            return "4/5";
                        else
                            return "5/6";
                    else
                        if( f < 0.88 )
                            return "6/7";
                        else
                            if( f < 0.89 )
                                return "7/8";
                            else
                                if( f < 0.90 )
                                    return "8/9";
                                else
                                    return "9/10";
    }
1
ответ дан 24 November 2019 в 04:51
поделиться

Вот реализация для ruby ​​ http : //github.com/valodzka/frac

Math.frac(0.2, 100)  # => (1/5)
Math.frac(0.33, 10)  # => (1/3)
Math.frac(0.33, 100) # => (33/100)
0
ответ дан 24 November 2019 в 04:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: