Difference between revisions of "Main Page"
DirkMittler (talk | contribs) m |
DirkMittler (talk | contribs) m |
||
Line 39: | Line 39: | ||
What the reader may already have noticed is, that if he or she tries to implement this with C++2017 or later, the standard method of type-punning no longer works... |
What the reader may already have noticed is, that if he or she tries to implement this with C++2017 or later, the standard method of type-punning no longer works... |
||
− | <syntaxhighlight lang="cpp" |
+ | <syntaxhighlight lang="cpp" highlight="3"> |
float64_t Q_failed_pun(const float64_t number) { |
float64_t Q_failed_pun(const float64_t number) { |
||
uint64_t *temp1 = (uint64_t *) &number; |
uint64_t *temp1 = (uint64_t *) &number; |
Revision as of 09:14, 31 August 2024
This is a personal MediaWiki.
The User's Guide will explain how to use the WiKi software, to Dirk.
Getting started
- Configuration settings list
- MediaWiki FAQ
- MediaWiki release mailing list
- Localise MediaWiki for your language
- Learn how to combat spam on your wiki
Eq 1: [math]\displaystyle{ y=\pm\sqrt{1-x^{2}} }[/math] (Equation for circle.)
The following is a hypothetical exercise...

This example is supposed to show how thumbnails can be made to display by default, as well as how inter-WiKi links work.
The following is some (C++) code which has been suggested, to compute the reciprocal square root using a trick. It may not be helpful, because this code requires that the language implementation can already perform multiplication and subtraction in double-precision, floating-point representation, as well as to access such numbers as though they were integers. The fact that so-called 'doubles' have 11 most significant bits that state their power of 2 means that for most purposes, this sort of type-punning computes their logarithm very quickly, which, in turn, is useful to produce a first approximation of their reciprocal square root, of the form...
Eq 2: [math]\displaystyle{ \ln\left(\frac{1}{\sqrt{x}}\right)-\frac{1}{2}\ln\left(x\right) }[/math]
Why, exactly, the constants are used as starting values, from which half the punned value of (x) is to be subtracted, is not clear to most people, including This Author. This may have more to do with the binary floating-point format than with the square root of (x). Yet, the fact that Matthew Robertson was able to derive the double-precision version suggests that he knows. What's being computed more closely resembles...
Eq 3: [math]\displaystyle{ C-\frac{1}{2}\ln\left(x\right) }[/math]
What the reader may already have noticed is, that if he or she tries to implement this with C++2017 or later, the standard method of type-punning no longer works...
float64_t Q_failed_pun(const float64_t number) {
uint64_t *temp1 = (uint64_t *) &number;
uint64_t temp2 = 0x5FE6EB50C7B537A9 - (*temp1 >> 1);
float64_t *out = (float64_t *) temp2;
return *out;
}
Because of how efficiently the compilers optimize the code, line 3 becomes equivalent to...
uint64_t temp2 = 0x5FE6EB50C7B537A9 - ((uint64_t) number / 2);
The rest of the (working) computation applies Newton's Method 4 extra times, resulting in precision which reaches the limit of the double-precision floating-point format.
/* Fast Inverse Square Root, using Matthew Robertson's
* Magic Number for double-precision floating-point.
*
* Implemented August 2, 2024
* by Dirk Mittler
*
*/
#include <cstring>
#include <cstdint>
typedef double float64_t;
float64_t Q_rsqrt(const float64_t number) noexcept {
const float64_t threehalfs = 1.5;
const float64_t halfnum = 0.5 * number;
uint64_t temp;
float64_t y;
static_assert(sizeof(uint64_t) == sizeof(number),
"`double` has a weird size.");
memcpy(&temp, &number, sizeof(float64_t));
// temp = 0x5f3759df - (temp >> 1); // Original 32-bit fr Quake III
temp = 0x5FE6EB50C7B537A9 - (temp >> 1); // Matthew Robertson's
memcpy(&y, &temp, sizeof(float64_t));
y *= (threehalfs - (halfnum * y * y));
y *= (threehalfs - (halfnum * y * y));
y *= (threehalfs - (halfnum * y * y));
return y * (threehalfs - (halfnum * y * y));
}