takes me to put a fun, which takes a value, doubled, logs and value back to the original type Is put on For the purpose of this question, the original and output type is float. Here is the basic C ++ code:
return static_cast & lt; TOutput & gt; (Std :: log (static_cast & lt; double & gt; (a)))
When I compile in debug mode, everything is expected and GCC is built in Logs as a call
function:
51: /myfile.h **** return static_cast & lt; Dangerous & gt; (Std :: log (static_cast & lt; double> gt; (a)); 219,133 .loc 112 51 0 219,134 0010 488B45F0 movq -16 (% RBP),% Rax # A, tmp64 219,135 0014 F30F1000 movss (% Rax),% xmm0 # * A_1 (D), D.237346 219,136 0018 0F14C0 unpcklps% xmm0 ,% Xmm0 # D.237346, D.237346 219,137 001b 0F5AC0 cvtps2pd% xmm0,% xmm0 # D.237346, D.237347 219,138 001e E8000000 Call Log # 219,138 00 219,139 0023 660F14C0 unpcklpd% xmm0,% xmm0 # D.237347 219,140 0027 660F5AC0 cvtpd2ps% xmm0,% xmm0 # D.237347, D.237346 219,141 002B F30F1145 movss% xmm0, -20 (% RBP) # D.237346,% SFP 219,141 EC 219,142 0030 8B45EC movl -20 (% RBP), % Ex #% sfp, & lt; Rival & gt;
However, when I optimize on (-O2 -ggdb3 -DNDEBUG), this call logf
(???) function:
51: /myfile.h **** Return static_cast & lt; Dangerous & gt; (Std :: log (static_cast & lt; double> gt; (a)); 145,171 .loc 64 51 0 145172 01a0 F30F1004 in movss (% RDX,% Rax, 4),% xmm0 # member [(const float & amp;) _ 84], Member [(const float & amp;) _ 84] 145172 82 145,173 01a5 E8000000 Call Logf #
Does this give a different output? Is this normal? Am i wrong It seems that the GCC is taking a very generous interpretation of my code, which I do not have to expect in the absence of the -based mathematics
option.
This double < To change the conversion in / code> there is a borderline optimization to float into an application of a single exact log
, but it can be considered acceptable.
Assume that logf
is rounded accurately and that double-precision logs
is also correctly or rounded Sincerely round, both computations can rarely be different, they may vary due to (for some rare inputs) (in which "double" means "twice" and does not refer to this type). Double-rounding is all statistically statistically less important that there is additional points in the importance of intermediate type and compared to the last type of significance (and this statistical argument is a little trash from a mathematical perspective, but it works for "work in practice" Is "not designed to be a counter-example). For evangelistic reasons, people (or Wikipedia) explain it with one or two extra points to clarify it, but when you have 53 - 24 = 29 additional binary numbers, then it can be expected to be as much 2 29 at a time.
I am shocked by the optimization, and if I wrote the code myself for a complete search of double-ferining problems with the log
, then it would be disturbing, But considering that C ++ does not mandate the accuracy of any level from standard std :: log
, it is possible to consider "no bug".
If, instead of logs
, we were talking about one of the basic tasks (like *
), then a compiler change claim to provide the IEEE, which is wrong for every 754 words, when it introduces a visible change from the original operation, is assigned indirectly accuracy IEEE 754, and no change in specification There is no space.
The basic operations that occurs when floatOP (gives flux, fly) change
to (float) Dblopi (double) flux, (double) Fly)
(This shows in Chapter 6), but can be visible when type double
and are long double
This exact bug is done by Stephen Canon Was there.
Comments
Post a Comment