Difference between revisions of "Main Page"

From Dirks Personal WiKi
m
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" line highlight="3" style="border-color: red red red red;">
+
<syntaxhighlight lang="cpp" line 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:13, 31 August 2024

This is a personal MediaWiki.

The User's Guide will explain how to use the WiKi software, to Dirk.

Getting started

Eq 1:    [math]\displaystyle{ y=\pm\sqrt{1-x^{2}} }[/math]    (Equation for circle.)

Drop-Down Menu
  • [[Plastic Widgets]]
  • [[Framistans]]
  • [[Pet Rocks]]
  • Eq 1
  • Eq 2
  • Eq 3

The following is a hypothetical exercise...

A cartoon centipede reads books and types on a laptop.
The Wikipede edits wikipedia:Myriapoda.

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...

1float64_t Q_failed_pun(const float64_t number) {
2    uint64_t *temp1 = (uint64_t *) &number;
3    uint64_t temp2 = 0x5FE6EB50C7B537A9 - (*temp1 >> 1);
4    float64_t *out = (float64_t *) temp2;
5    return *out;
6}

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));
}