There is a code:

const double Pi = 3.14; double a = Pi; double b = Pi; 

Type Code:

 double x = 3.; double b = (4.0 - x) * Pi; 

There can be no program, i.e. always assignment var = Pi .

Is it correct in this (and only in this) case to compare a == b ?

Just add. The assignment of a constant in a program might look something like this:

 double b = some_expression; if (b < Pi + epsilon && Pi - epsilon < b) b = Pi; 

And nothing else.

P.S. Ispolzvanie numbers, similar to the mathematical "pi" - for example only, to reality has nothing to do.

Let's try to formulate the question more widely. There are two lines of code coming in a row.

 double x = some_value; double y = x; // not double y = some_expression_that_equal_to_x; 

Types x , y same, this is important. Is the same binary representation of x and y guaranteed?

  • Sorry sealed, corrected - andy.37
  • And how can you guarantee that b will never be equal to Pi as a result of any other actions? - Kromster
  • but an interesting version of ideone.com/EOmPrO :) - KoVadim
  • one
    Hmm, I wonder, how do you imagine the work of a computer that does not guarantee an exact binary representation when copying? : D - Petr Abdulin
  • one
    @PetrAbdulin, it's just a matter of a different number of digits in memory (double - 64bit) and the FPU register (80bit) - avp

2 answers 2

The answer to a wider question. Yes, the same binary representation is guaranteed. No options. Otherwise (besides just absurdity) any interesting things would be possible, for example, with:

 double a = 3.14; 

operation

 a = a; 

would change the binary representation a .

  • Again, if possible, reference to proof. Simply, if this is the case, then a=x; b=x a=x; b=x guarantees the same binary representation of a and b , and this seems to be the answer to the first question, isn't it? - andy.37
  • @ andy.37, in the form in which the code in the question is written (that is, there are no calculations with a and b and the constant is not a constant expression (that is, it is not calculated)), you can safely compare them. - avp
  • @ andy.37 is not entirely clear what you need as proof. Those. It is difficult to search for evidence of near-axiom things. Those. a similar statement for int does not seem to be disputable, but for double it seems. I do not see the difference between them. Give proof for int , I think proof for double will be somewhere nearby. And yes, it is logical that the answer to a wider question confirms a special case. - Petr Abdulin
  • one
    @PetrAbdulin, if you compare values in memory , then there is no difference. And if the result of calculations with memory, that is, since the size of the integer registers coincides with the size of these variables in memory, but there are no floating point registers. Those. it is possible that the compiler sees that one of the comparison operands is still in the register and does not reload the value from the memory into it (in fact, several bits have been truncated when writing to memory). Therefore, there is a problem about which here and talking. - avp
  • @avp I do not see how the size of the register affects the two numbers loaded from memory. If I understand everything correctly, the question is not about the calculated values. - Petr Abdulin

If the compiler accidentally substitutes a constant in an expression like a long double , and the variable is double , then suddenly it turns out that they are not equal. So it is better not to, unless you are absolutely sure that your constant is exactly representable in type double.

  • But after all type conversion will be performed one time or another, when defining const , isn't it? Further, Pi has a well-defined (and unchanged in the future) binary representation, yes, depending on the architecture of the machine and, possibly, on the compiler, but the same everywhere in the compiled program. Or I'm wrong? - andy.37
  • one
    @ andy.37, google the code where there is a variable double x with a certain value and the code if (sin(x) != sin(x)) - there with the assembler listing you can see that the left sin after the calculation is from long double to double , and the right one remains in long double , after which, when compared, it turns out that the values ​​are not equal. If the compiler follows the same logic as a constant in a constant, and in a long double , then it may no longer be equal to its rounded to double value. - Qwertiy
  • Thanks for the valuable (without irony) comments. Those. You want to say that in my example, sizeof Pi should not be equal to sizeof(double) ? Once again, I never compare sin(Pi) == sin(Pi) , I only compare var == Pi and only after explicit var=Pi . - andy.37
  • one
    @ andy.37, there was a chip in that the compiler, for some reason, missed the cast - some kind of optimization. I do not know how it is a constant constant. In theory, for the code, what the compiler does should not be visible. But you never know what happens there. If your constant is 2 or even 11111.875 - compare how much you want. If 3.1 - I just in case would not. - Qwertiy
  • one
    If you compare var == Pi and only after explicit var = Pi, then most likely you have a problem in the design of the code - you need to use the Bulenovsky variable. And no problems. - KoVadim