I can either introduce a compiler switch or a # statement at the top of the class. |
Decimal Binary 0.01 0.02 0.0 0.04 0.00 0.08 0.000 0.16 0.0000 0.32 0.00000 0.64 0.000000 1.28(0.28) 0.0000001 0.56 0.00000010 1.12(0.12) 0.000000101 0.24 0.0000001010 0.48 0.00000010100 0.96 0.000000101000 1.92(0.92) 0.0000001010001 1.84(0.84) 0.00000010100011 1.68(0.68) 0.000000101000111 1.36(0.36) 0.0000001010001111 0.72 0.00000010100011110 1.44(0.44) 0.000000101000111101 0.88 0.0000001010001111010 1.76(0.76) 0.00000010100011110101 1.52(0.52) 0.000000101000111101011 1.04(0.04) 0.0000001010001111010111 0.08 0.00000010100011110101110 should repeat from here ^ ^ . | | . start of repeat next repeat . |
The compiler is GNU G++. The switch, or # statement or otherwise, I do not yet quite know. What could one do? |
So, what do these switches do to the example source code? -mpc32, -mpc64, -mfpmath=sse, or -msse2 |
man g++ |
g++ --help |
Are there any source code statements |
it's mathematically impossible with float or double. |
-mpc32
-mpc64
-mpc80 Set 80387 floating-point precision to 32, 64 or 80 bits. When -mpc32 is specified, the significands of results of floating-point operations are rounded to 24 bits (single precision); -mpc64 rounds the significands of results of floating-point operations to 53 bits (double precision) and -mpc80 rounds the significands of results of floating-point operations to 64 bits (extended double precision), which is the default. When this option is used, floating-point operations in higher precisions are not available to the programmer without setting the FPU control word explicitly. Setting the rounding of floating-point operations to less than the default 80 bits can speed some programs by 2% or more. Note that some mathematical libraries assume that extended-precision (80-bit) floating-point operations are enabled by default; routines in such libraries could suffer significant loss of accuracy, typically through so-called "catastrophic cancellation", when this option is used to set the precision to less than extended precision. |
-msse2 This switch enables the use of instructions in the SSE2 extended instruction set. GCC depresses SSEx instructions when -mavx is used. Instead, it generates new AVX instructions or AVX equivalence for all SSEx instructions when needed. These options enable GCC to use these extended instructions in generated code, even without -mfpmath=sse. |
To generate SSE/SSE2 instructions automatically from floating-point code (as opposed to 387 instructions), see -mfpmath=sse. |
-mfpmath=unit Generate floating-point arithmetic for selected unit unit. The choices for unit are: 387 Use the standard 387 floating-point coprocessor present on the majority of chips and emulated otherwise. Code compiled with this option runs almost everywhere. The temporary results are computed in 80-bit precision instead of the precision specified by the type, resulting in slightly different results compared to most of other chips. See -ffloat-store for more detailed description. This is the default choice for i386 compiler. sse Use scalar floating-point instructions present in the SSE instruction set. This instruction set is supported by Pentium III and newer chips, and in the AMD line by Athlon-4, Athlon XP and Athlon MP chips. The earlier version of the SSE instruction set supports only single-precision arithmetic, thus the double and extended-precision arithmetic are still done using 387. A later version, present only in Pentium 4 and AMD x86-64 chips, supports double-precision arithmetic too. For the i386 compiler, you must usdouble x = a*b;e -march=cpu-type, -msse or -msse2 switches to enable SSE extensions and make this option effective. Fordouble x = a*b; the x86-64 compiler, these extensions are enabled by default. The resulting code should be considerably faster in the majority of cases and avoid the numerical instability problems of 387 code, but may break some existing code that expects temporaries to be 80 bits. This is the default choice for the x86-64 compiler. sse,387 sse+387 both Attempt to utilize both instruction sets at once. This effectively doubles the amount of available registers, and on chips with separate execution units for 387 and SSE the execution resources too. Use this option with care, as it is still experimental, because the GCC register allocator does not model separate functional units well, resulting in unstable performance. |
double x = a*b;
a*b
does use 80 bit registers in x87_FPU (vs 64 bit ? registers in SSE), the temporary value is probably transferred and truncated to double
in RAM.
std::cout
the value with the normal 6 dp output, do you get the expected answer?double
s, but the usual question is: Is my variable close enough to a certain value or within some precision value. This is easy to test with a simple if statement:
|
|