What happens when we assign a float value to a double variable?

Asked

Viewed 443 times

4

class Test {
    public static void main (String[] args){
        double pi = 3.1415f;
        System.out.println(pi);
    }
}

When compiling and executing the above code, I got the return: 3.1414999961853027
This is not a question to solve a problem.
I just wish I could understand what’s going on here...

2 answers

5


No magic is happening here. It is only the way the information is being displayed that ends up confusing the user (developer). That’s the way the float is implemented when you write 3.1415f this is not the real value that will be applied to the variable, this is not exactly the value found in memory as the implementation of float. You can perform some tests:

float a = 3.1415f;
float b = 3.1414999961853027f;

System.out.println("a = " + a); // a = 3.1415
System.out.println("b = " + b); // b = 3.1415
System.out.println(a == b); // true

The value displayed for both cases receives a "rounding", but the actual value found in the variable is not 3.1415f. This "problem" is not very common to find when working only with floats, but when there is the value coercion of a float for a double people notice this difference because the double ends up displaying all the information, thus appearing that the values are different (when in fact they are not).

double c = a;
System.out.println("c = " + c); // c = 3.1414999961853027

You can see here a few more tests proving that both values are exactly the same.

NOTE: This is not something characteristic only of Java, Several languages implement this standard and developers often struggle with it when they need a lot of precision. C# implements the same standards for float and the double, when something needs a lot of precision like monetary values they have an implementation decimal to meet these demands. Other languages such as JavaScript have only one implementation to represent numbers, and end suffering from it, from problems with precision to the representation of large numbers, requiring libraries to solve the problem.

  • "but when there is value coercion from a float to a double" - I think you meant "conversion," that would be?

  • @diegofm "coercion" is implicit conversion, which is the case with the question. Of course, using the term "conversion" makes it more comprehensive, but I find it strange that people want to perform an explicit conversion (cast) between "float" and "double".

  • Oh yes, it was only for "conscience disenchantment" even :) By the way, good answer, took away the doubt too +1

  • 1

    @diegofm Yes, you are completely correct in questioning. If you think there is something wrong always question. ;)

  • 1

    @Bacco reply edits, thanks for the link ;)

0

Turns out the variables have different sizes:

Float Represents numbers in standard floating point notation in simple precision of 32 bits in accordance with IEEE 754-1985. The lowest repressable positive value for this type is 1.40239846e-46 and the highest is 3.40282347e+38

Double Represents numbers in standard floating point notation in double precision of 64 bits in accordance with IEEE 754-1985. The lowest representative positive value is 4.94065645841246544e-324 and the highest is 1.7976931348623157e+308

When you make the assignment of a value double in float it truncates the value to the supported size, half the size, decreasing the accuracy of the value. Only this.

See more information on: http://www.dm.ufscar.br/~Waldeck/curso/java/part22.html

  • But double is bigger than float, as it "trunca" if it makes float cast for double?

  • 2

    He doesn’t trump the value, that’s wrong. Implicit conversions (coercion) are known as widening conversions, where there is no loss of information.

  • @diegofm meant otherwise. I’ve corrected.

  • @Gabrielkatakura as I mentioned, he diminishes accuracy, did not say that he loses information.

  • @Gabrielkatakura this truncation should occur in the inverse ne(a double too large for a float)

  • Celso, in question, is assigning to a double variable, a float value, and not the inverse one. If float is 'less' than double, as it loses precision?

  • 2

    Simply do not take advantage of the higher precision in the assignment. But lose nothing. If there was loss occurred before, at the time of putting the value in the float.

  • "Decrease accuracy" in the case of double for float can rather cause information loss. Precisely because of this narrowing conversions are made explicitly (casting).

  • @Gabrielkatakura precisely, but the question is from float to double, I think that’s what’s causing all the confusion.

  • @Bacco I’m aware, it was only an answer regarding "it decreases accuracy, did not say that it loses information"

  • It is true that the accuracy was lost, but a double variable should be able to store a float value without problems.. I believe it was at the time of converting the float value < 3.1415f > to double, that precision was lost. What I really wanted to understand was why the machine can’t simply assign the value 3.1415 (from float 3.1415f) to the variable.

  • I tried to compile using casting 'double pi = (double) 3.1415f;' But there was the same loss in accuracy. (I’m really curious to understand what happens here)

  • 1

    @This does not happen in the conversion. It is the way floating point numbers work. They do not "round" to decimal http://answall.com/questions/5642/resultado-impreciso-em-c%C3%a1lculo-com-n%C3%bameros-broken

Show 8 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.