java 将分数转换为十进制数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4538872/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 06:50:41  来源:igfitidea点击:

Convert fraction to decimal number

javafloating-pointinteger

提问by Racket

i'm doing some exercises in my Java book. I'm very new to programming. Therefore, notice (in the code) that i'm still on Chapter one. Now I already did everything, I just want a confirmation if this is legitimate so I can feel free to move on next.

我正在我的 Java 书中做一些练习。我对编程很陌生。因此,请注意(在代码中)我仍在学习第一章。现在我已经做了所有的事情,我只想确认这是否合法,这样我就可以继续下一步了。

If not, I would sincerely appreciate to notdo my code for me; I want advice.

如果没有,我会衷心感谢以为我做我的代码; 我想要建议。

Here's the question written in the book, "Write an application that prompts/reads the numerator and denominator of a fraction as integers, then prints the decimal equivalent of the fraction."

这是书中写的问题“编写一个应用程序,提示/读取分数的分子和分母为整数,然后打印分数的十进制等价物。”

I'll illustrate this sentence with my code:

我将用我的代码来说明这句话:

I did a revision here. Is this one OK?..

我在这里做了修改。这个好吗?...

import java.util.*;
public class ExerciseEleven {
public static void main (String[] args) {
Scanner sc = new Scanner (System.in);

    double fraction;
    int fractionValue;
    int decimal;
    double value;

    System.out.println("Enter Numerator: ");
    int numerator = sc.nextInt();
    System.out.println("Enter Denominator: ");
    int denominator = sc.nextInt();

    fraction = (double) numerator / denominator;
    fractionValue = (int) (fraction * 10);
    decimal = fractionValue % 10;
    value = decimal * 0.1;


    System.out.println(value);
}
}

It compiles and works fine. Thank you.

它编译并运行良好。谢谢你。

回答by Vladimir Ivanov

It doesn't do what task says it should. You read doubles instead of integers, and the decimal equivalent is not what you print out. Decimal equivalent for 1/2 is 0.5. And you print 5.

它没有执行任务所说的应该执行的操作。您读取的是双精度数而不是整数,而十进制数不是您打印出来的。1/2 的十进制等效值为 0.5。然后你打印 5。

Also, you can pay attention to your code style: variable names are usually written in lowerCamelCase, like that : simpleVariable.

另外,您可以注意您的代码风格:变量名称通常以小驼峰命名,例如 : simpleVariable

Update

更新

now it prints what you need. However you do it not in the very right way and your indentation can still be improved.

现在它会打印您需要的内容。但是,您这样做的方式并不正确,您的缩进仍然可以改进。

回答by T.J. Crowder

It's fine(I didn't read the assignment very well, did I? Kudos to Vladimir.)...but some comments:

没关系(我没有很好地阅读作业,是吗?向Vladimir 致敬。)...但有些评论:

  • Usually you want to indent methods within the class.
  • Standard practice is to use initial caps (Numerator) only for types (e.g., classes, interfaces, enums). Variable, field, and method names should start with a lower-case letter. Now, you're free to ignore standard practice, but if you do people will have a lotof trouble reading your code. :-)
  • For rounding, you probably want to look at Math.roundrather than truncating with a cast. But the assignment didn't say anything about rounding.
  • You might want to handle the case where denominatoris zero.
  • 通常你想在类中缩进方法。
  • 标准做法是Numerator仅对类型(例如,类、接口、枚举)使用首字母大写 ( )。变量、字段和方法名称应以小写字母开头。现在,您可以随意忽略标准实践,但如果您这样做,人们在阅读您的代码时会遇到很多麻烦。:-)
  • 对于四舍五入,您可能想要查看Math.round而不是使用强制转换进行截断。但作业并没有说明四舍五入。
  • 您可能想要处理denominator零的情况。

So keeping those in mind:

所以要记住这些:

import java.util.*;

public class ExcerciseEleven  {

    public static void main (String[] args) {
        Scanner sc = new Scanner (System.in);

        System.out.println("Enter Numerator: ");
        int numerator = sc.nextInt();
        System.out.println("Enter Denominator: ");
        int denominator = sc.nextInt();
        if (denominator == 0) {
            System.out.println("Can't divide by zero");
        }
        else {
            double fraction = (double)numerator / denominator;
            System.out.println(fraction);
        }
    }
}

回答by FalconBot

Hey I am doing some thinking about this and I have noticed something interesting after looking at this source and here is the Algorithm that I plan on implementing

嘿,我正在考虑这个问题,在查看此来源后我注意到一些有趣的事情,这是我计划实施的算法

  1. First I will convert the number from the Metric using the Javax.Measure family of functions and I will get a number like 0.3750
  2. Then I will divide the number by ONE_SIXTEENTH which = 0.0625
    ONE_SIXTEENTH = 0.0625
    The answer 0.3750 / ONE_SIXTEENTH = 6;
  3. So now I know there are 6 sixteenths of the inch
  4. Next I check to see if 6 is divisible by 4, 6/4 = 1.5 ie not a whole number so the fraction is still regarded as 6/16th of an inch for now
  5. Next I check to see if 6 is divisible by 2, 6/2 = 3 This is a whole number so we will use it to reconstitute the fraction
  6. So now that we have divided 6 by 2 and gotten 3 the 16 needs to be divided by 2 and we end up with 8 so 6/16th of an inch becomes 3/8th of an inch.
  1. 首先,我将使用 Javax.Measure 系列函数转换 Metric 中的数字,我将得到一个类似 0.3750 的数字
  2. 然后我将数字除以 ONE_SIXTEENTH = 0.0625
    ONE_SIXTEENTH = 0.0625
    答案 0.3750 / ONE_SIXTEENTH = 6;
  3. 所以现在我知道有六分之六英寸
  4. 接下来我检查 6 是否能被 4 整除,6/4 = 1.5 即不是整数所以现在分数仍然被视为 6/16 英寸
  5. 接下来我检查 6 是否能被 2 整除,6/2 = 3 这是一个整数,所以我们将用它来重组分数
  6. 所以现在我们已经将 6 除以 2 并得到 3,16 需要除以 2,我们最终得到 8,所以 6/16 英寸变成 3/8 英寸。

PS Has anyone noticed that this is similar to a fizz bang program?

PS 有没有人注意到这类似于 fizz bang 程序?

____________________________________________

____________________________________________

Here is the chart which helped me get my head around this

这是帮助我解决这个问题的图表

This is how I worked out how I was going to do this
My workings

这就是我如何确定我将如何做到这一点
我的作品

回答by Saurav Sahu

There are three important parts of division operation :

除法运算的三个重要部分:

  1. Sign of the result.
  2. Integral part
  3. Decimal part
  1. 结果的标志。
  2. 组成部分
  3. 小数部分

Also, there are few corner cases where you need to deal with the fact that Integer.MIN_VALUEis greater than Integer.MAX_VALUEwhen compared in absoluteform.

此外,很少有极端情况需要处理Integer.MIN_VALUE绝对形式Integer.MAX_VALUE比较时更大的事实。

For example : -2147483648/-1can't yield 2147483648when divided in the form of integer types. The reason is simple. The type of the resulting type will be integer type, and the maximum positive value that a integer type variable can hold is +2147483647

例如:以整数类型的形式划分时-2147483648/-1不能产生2147483648。原因很简单。结果类型的类型将是整数类型,整数类型变量可以容纳的最大正值是+2147483647

To mitigate that scenario, we should at first convert both the numerator and denominator into their long positive form. That gives us the integralpart of the answer.

为了缓解这种情况,我们首先应该将分子和分母都转换为它们的长正数形式。这给了我们答案的组成部分。

The XOR of two numbers will have the sign bit as 1only in case they have opposite signs. That solves the first part (signof result) of the problem.

两个数字的 XOR1只有在它们具有相反符号的情况下才会具有符号位。这解决了问题的第一部分(结果的符号)。

For decimalpart, we can employ the general division rule i.e. multiply the remainder with 10and try dividing again and repeat. Keep record of the remainder we have already come across to prevent the loop from going into unbounded iterations.

对于小数部分,我们可以使用一般的除法规则,即将余数乘以10并再次尝试除法并重复。记录我们已经遇到的余数,以防止循环进入无限迭代。

public String fractionToDecimal(int A, int B) {
    StringBuilder sb = new StringBuilder((A^B) < 0 ? "-" : "");
    long a = Math.abs((long)A);
    long b = Math.abs((long)B);
    sb.append(Long.toString(a/b));

    long rem = a % b; 
    sb.append((rem != 0) ? "." : "");
    Map<Long, Integer> remainderMap = new HashMap<>();
    int pos = 0;
    while (rem != 0){
        sb.append(Long.toString((rem*10)/b));
        remainderMap.put(rem, pos++);
        rem = (rem*10) % b;
        if (remainderMap.containsKey(rem)){
            String currNum[] = sb.toString().split("\.");
            return currNum[0] + "." + currNum[1].substring(0, remainderMap.get(rem)) + 
                        "(" + currNum[1].substring(remainderMap.get(rem)) + ")";   
        }
    }
    if (sb.toString().equals("-0")) return "0"; 
    return sb.toString();
}

Sample output :

示例输出:

  • 2/3gives 0.(6)

  • -2147483648/-1gives 2147483648

  • 2/30.(6)

  • -2147483648/-12147483648