ChatGPT解决这个技术问题 Extra ChatGPT

Integer division: How do you produce a double?

For this code block:

int num = 5;
int denom = 7;
double d = num / denom;

the value of d is 0.0. It can be forced to work by casting:

double d = ((double) num) / denom;

But is there another way to get the correct double result? I don't like casting primitives, who knows what may happen.

casting an 'int' to a double is safe, you will always get the same value without loss of precision.
I would like to know if the following are the correct steps taken by the compiler for the division: 1) cast num to float 2) cast denom to float as well 2) divide num by denom. Please let me know if I'm incorrect.

M
Mindwin
double num = 5;

That avoids a cast. But you'll find that the cast conversions are well-defined. You don't have to guess, just check the JLS. int to double is a widening conversion. From §5.1.2:

Widening primitive conversions do not lose information about the overall magnitude of a numeric value. [...] Conversion of an int or a long value to float, or of a long value to double, may result in loss of precision-that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode (§4.2.4).

5 can be expressed exactly as a double.


+1. Stop being scared of casting. Learn how it works. It's all well-defined.
@FabricioPH This works in every situation, and identically to the *1.0 solution.
@Saposhiente It goes beyond working or not. Changing the type of a variable seems dirty code to me. If you have something that MUST BE an integer and you change the representation for a float just to be able to perform the math operation, you may be risking yourself. Also in some context reading the variable as an integer makes code easier to understand.
@FabricioPH, multiplying by 1.0 still changes the type of the result, just in a different way. 'Seems dirty code to me' does not explain in what scenario(s) you believe multiplying by 1.0 is actually better (or why that might be).
@FabricioPH You and the OP seem to be labouring under the false belief (where you say "Changing the type of the variable") that doing (double)num somehow changes num. It doesn't - it creates a temporary double for the context of the statement.
P
Paul Tomblin

What's wrong with casting primitives?

If you don't want to cast for some reason, you could do

double d = num * 1.0 / denom;

...which does an implicit cast before the multiplication
In most cases this is better than changing the type of other variable.
@FabricioPH Nothing suggests this to be true, unless you have a source to cite.
@Saposhiente replied in your other similar comment
You can also use the "D" postfix (to perform the same implicit cast); -- so for example: double d = num * 1D / denom;
B
Bernhard Barker

I don't like casting primitives, who knows what may happen.

Why do you have an irrational fear of casting primitives? Nothing bad will happen when you cast an int to a double. If you're just not sure of how it works, look it up in the Java Language Specification. Casting an int to double is a widening primitive conversion.

You can get rid of the extra pair of parentheses by casting the denominator instead of the numerator:

double d = num / (double) denom;

you can as well do double d = (double) num / denom;... (OK, this one depends on precedence)
a
alianos-

If you change the type of one the variables you have to remember to sneak in a double again if your formula changes, because if this variable stops being part of the calculation the result is messed up. I make a habit of casting within the calculation, and add a comment next to it.

double d = 5 / (double) 20; //cast to double, to do floating point calculations

Note that casting the result won't do it

double d = (double)(5 / 20); //produces 0.0

M
Minhas Kamal

Type Casting Is The Only Way

May be you will not do it explicitly but it will happen.

Now, there are several ways we can try to get precise double value (where num and denom are int type, and of-course with casting)-

with explicit casting:

double d = (double) num / denom;

double d = ((double) num) / denom;

double d = num / (double) denom;

double d = (double) num / (double) denom;

but not double d = (double) (num / denom);

with implicit casting:

double d = num * 1.0 / denom;

double d = num / 1d / denom;

double d = ( num + 0.0 ) / denom;

double d = num; d /= denom;

but not double d = num / denom * 1.0;
and not double d = 0.0 + ( num / denom );

Now if you are asking- Which one is better? explicit? or implicit?

Well, lets not follow a straight answer here. Simply remember- We programmers don't like surprises or magics in a source. And we really hate Easter Eggs.

Also, an extra operation will definitely not make your code more efficient. Right?


This is valid also if it is with a floating number?
N
Nikhil Kumar

Cast one of the integers/both of the integer to float to force the operation to be done with floating point Math. Otherwise integer Math is always preferred. So:

1. double d = (double)5 / 20;
2. double v = (double)5 / (double) 20;
3. double v = 5 / (double) 20;

Note that casting the result won't do it. Because first division is done as per precedence rule.

double d = (double)(5 / 20); //produces 0.0

I do not think there is any problem with casting as such you are thinking about.


u
ungalcrys

use something like:

double step = 1d / 5;

(1d is a cast to double)


1d is not a cast, it's just a declaration.
A
Alp Altunel

Best way to do this is

int i = 3;
Double d = i * 1.0;

d is 3.0 now.

K
Ken Wayne VanderLinde

You might consider wrapping the operations. For example:

class Utils
{
    public static double divide(int num, int denom) {
        return ((double) num) / denom;
    }
}

This allows you to look up (just once) whether the cast does exactly what you want. This method could also be subject to tests, to ensure that it continues to do what you want. It also doesn't matter what trick you use to cause the division (you could use any of the answers here), as long as it results in the correct result. Anywhere you need to divide two integers, you can now just call Utils::divide and trust that it does the right thing.


F
FelixSFD

just use this.

int fxd=1;
double percent= (double)(fxd*40)/100;

R
Ricardo

Just add "D".

int i = 6;
double d = i / 2D; // This will divide bei double.
System.out.println(d); // This will print a double. = 3D

A fractional suffix .0 is generally clearer for the humans. d is the next best option. I would consider D to be harmful as it looks too much like a digit to be adjacent to digits.