> if(mem.readCustomType<double>(start) == d_Y + playerHeight)
The first problem is going to be comparing doubles for equality.
If you're off by even a single bit in the LSB, then "damn close" just becomes "nope, not it".
Even if they are bit-equal in memory, you might still need
-ffloat-store
The following options control compiler behavior regarding floating point arithmetic. These options trade off between speed and correctness. All must be specifically enabled.
-ffloat-store
Do not store floating point variables in registers, and inhibit other options that might change whether a floating point value is taken from a register or memory.
This option prevents undesirable excess precision on machines such as the 68000 where the floating registers (of the 68881) keep more precision than a "double" is supposed to have. Similarly for the x86 architecture. For most programs, the excess precision does only good, but a few programs rely on the precise definition of IEEE floating point. Use -ffloat-store for such programs, after modifying them to store all pertinent intermediate computations into variables. |
> for(start; start <= end; start++)
doubles are not scattered at random addresses in memory. Each type has a minimum alignment.
So perhaps
for(start; start <= end; start += alignof(double))
You should also have < end, not <= end.
A caveat to that would be various attempts to obfuscate the code to make simple memory searches less effective (such as structure packing). But this always comes with a performance cost in the software.
Speaking of which, you might want to benchmark
mem.readCustomType<double>(0xD57AAE00)
against
mem.readCustomType<double>(0xD57AAE01)
A naive pointer cast would just get you a
https://en.wikipedia.org/wiki/Bus_error on most architectures. This should mean your unaligned access is doing a lot more work than the aligned case.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
#include <iostream>
#include <iomanip>
struct foo {
char c;
double d;
};
#pragma pack(push,1)
struct bar {
char c;
double d; // trying to be sneaky by hiding double in an odd place
};
#pragma pack(pop)
void show(const double f) {
std::cout << std::fixed << std::setprecision(15) << f
<< " = " << std::hexfloat << f
<< std::endl;
}
int main() {
double a = 1.7999999523163;
double b = 73 + a;
double c = 74.7999999523163;
show(a);
show(b);
show(c);
std::cout << "Double alignment=" << alignof(double) << std::endl;
std::cout << sizeof(foo) << std::endl;
std::cout << sizeof(bar) << std::endl;
}
$ g++ -std=c++11 foo.cpp
$ ./a.out
1.799999952316300 = 0x1.cccccc0000047p+0
74.799999952316298 = 0x1.2b33333000001p+6
74.799999952316298 = 0x1.2b33333000001p+6
Double alignment=8
16
9
|