QuakeIII: Fast Inverse of Sqrt in C (float to long)
-
Watched video Fast Inverse Square Root — A Quake III Algorithm - YouTube[^] It's a long video about how Quake III dev created a fast inverse of sqrt for 3D transforms. Yes, I watched the video but I don't understand it completely. :rolleyes: First the Source Code Here's my source code I used to confirm this weird syntax which... Makes C Think the Address Contains a Long Even Though It's a Float This is not a cast of a float value to long -- which would truncate decimal portion. This is a conversion of the float bits to an address which is a long. The bits stay in tact. !!!! :cool: I hope this gets your attention. Third Line Syntax Is WEIRD Really look at the third line below.
float fVal = 13.3892F;
printf("Float value ==> fVal :%f\n",fVal);
long lVal = * (long *) &fVal;
printf("float as long ==> lVal: %ld\n", lVal);That 3rd line takes the address of the float
&fVal
and what!?! multiplies it times a long pointer? or something?!? :confused: The Point But the point is, that after you do that, C compiler believes that you've converted the bits that represented the float value into a long. CRAZY!!! :wtf: I've never seen that syntax before. :wtf: Here's the output:Float value ==> fVal :13.389200
float as long ==> lVal: 5391137322Here's a snapshot of what the narrator in the video says. Really funny (read the caption in the snapshot explaining how/why C convert float bits to long). https://i.stack.imgur.com/YHyR5.png[^] PS - If you already knew this, you are a freaking C genius. Seriously. Or, you've been completely tortured by C. :laugh: EDIT / UPDATE Oh, the syntax is easier than I thought. It casts the float address as a long* and then gets the value stored at (*) that address and stores it at the address of the long -- which is actually the original address of the float (but now converted to a long). WHAT?!
-
Watched video Fast Inverse Square Root — A Quake III Algorithm - YouTube[^] It's a long video about how Quake III dev created a fast inverse of sqrt for 3D transforms. Yes, I watched the video but I don't understand it completely. :rolleyes: First the Source Code Here's my source code I used to confirm this weird syntax which... Makes C Think the Address Contains a Long Even Though It's a Float This is not a cast of a float value to long -- which would truncate decimal portion. This is a conversion of the float bits to an address which is a long. The bits stay in tact. !!!! :cool: I hope this gets your attention. Third Line Syntax Is WEIRD Really look at the third line below.
float fVal = 13.3892F;
printf("Float value ==> fVal :%f\n",fVal);
long lVal = * (long *) &fVal;
printf("float as long ==> lVal: %ld\n", lVal);That 3rd line takes the address of the float
&fVal
and what!?! multiplies it times a long pointer? or something?!? :confused: The Point But the point is, that after you do that, C compiler believes that you've converted the bits that represented the float value into a long. CRAZY!!! :wtf: I've never seen that syntax before. :wtf: Here's the output:Float value ==> fVal :13.389200
float as long ==> lVal: 5391137322Here's a snapshot of what the narrator in the video says. Really funny (read the caption in the snapshot explaining how/why C convert float bits to long). https://i.stack.imgur.com/YHyR5.png[^] PS - If you already knew this, you are a freaking C genius. Seriously. Or, you've been completely tortured by C. :laugh: EDIT / UPDATE Oh, the syntax is easier than I thought. It casts the float address as a long* and then gets the value stored at (*) that address and stores it at the address of the long -- which is actually the original address of the float (but now converted to a long). WHAT?!
Inverse of square root? Just square it. ;P
-
Watched video Fast Inverse Square Root — A Quake III Algorithm - YouTube[^] It's a long video about how Quake III dev created a fast inverse of sqrt for 3D transforms. Yes, I watched the video but I don't understand it completely. :rolleyes: First the Source Code Here's my source code I used to confirm this weird syntax which... Makes C Think the Address Contains a Long Even Though It's a Float This is not a cast of a float value to long -- which would truncate decimal portion. This is a conversion of the float bits to an address which is a long. The bits stay in tact. !!!! :cool: I hope this gets your attention. Third Line Syntax Is WEIRD Really look at the third line below.
float fVal = 13.3892F;
printf("Float value ==> fVal :%f\n",fVal);
long lVal = * (long *) &fVal;
printf("float as long ==> lVal: %ld\n", lVal);That 3rd line takes the address of the float
&fVal
and what!?! multiplies it times a long pointer? or something?!? :confused: The Point But the point is, that after you do that, C compiler believes that you've converted the bits that represented the float value into a long. CRAZY!!! :wtf: I've never seen that syntax before. :wtf: Here's the output:Float value ==> fVal :13.389200
float as long ==> lVal: 5391137322Here's a snapshot of what the narrator in the video says. Really funny (read the caption in the snapshot explaining how/why C convert float bits to long). https://i.stack.imgur.com/YHyR5.png[^] PS - If you already knew this, you are a freaking C genius. Seriously. Or, you've been completely tortured by C. :laugh: EDIT / UPDATE Oh, the syntax is easier than I thought. It casts the float address as a long* and then gets the value stored at (*) that address and stores it at the address of the long -- which is actually the original address of the float (but now converted to a long). WHAT?!
Classic C bit-banging. How we used to do arithmetic before we could afford an 8087. The "kosher" version looks like this:
union
{
float f;
long n; /* don't use "l", for readability */
} mixup;mixup.f = floatval;
longval = mixup.n;Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
-
Watched video Fast Inverse Square Root — A Quake III Algorithm - YouTube[^] It's a long video about how Quake III dev created a fast inverse of sqrt for 3D transforms. Yes, I watched the video but I don't understand it completely. :rolleyes: First the Source Code Here's my source code I used to confirm this weird syntax which... Makes C Think the Address Contains a Long Even Though It's a Float This is not a cast of a float value to long -- which would truncate decimal portion. This is a conversion of the float bits to an address which is a long. The bits stay in tact. !!!! :cool: I hope this gets your attention. Third Line Syntax Is WEIRD Really look at the third line below.
float fVal = 13.3892F;
printf("Float value ==> fVal :%f\n",fVal);
long lVal = * (long *) &fVal;
printf("float as long ==> lVal: %ld\n", lVal);That 3rd line takes the address of the float
&fVal
and what!?! multiplies it times a long pointer? or something?!? :confused: The Point But the point is, that after you do that, C compiler believes that you've converted the bits that represented the float value into a long. CRAZY!!! :wtf: I've never seen that syntax before. :wtf: Here's the output:Float value ==> fVal :13.389200
float as long ==> lVal: 5391137322Here's a snapshot of what the narrator in the video says. Really funny (read the caption in the snapshot explaining how/why C convert float bits to long). https://i.stack.imgur.com/YHyR5.png[^] PS - If you already knew this, you are a freaking C genius. Seriously. Or, you've been completely tortured by C. :laugh: EDIT / UPDATE Oh, the syntax is easier than I thought. It casts the float address as a long* and then gets the value stored at (*) that address and stores it at the address of the long -- which is actually the original address of the float (but now converted to a long). WHAT?!
Now you are ready to read this: Bit Twiddling Hacks[^]
-
Now you are ready to read this: Bit Twiddling Hacks[^]
-
Watched video Fast Inverse Square Root — A Quake III Algorithm - YouTube[^] It's a long video about how Quake III dev created a fast inverse of sqrt for 3D transforms. Yes, I watched the video but I don't understand it completely. :rolleyes: First the Source Code Here's my source code I used to confirm this weird syntax which... Makes C Think the Address Contains a Long Even Though It's a Float This is not a cast of a float value to long -- which would truncate decimal portion. This is a conversion of the float bits to an address which is a long. The bits stay in tact. !!!! :cool: I hope this gets your attention. Third Line Syntax Is WEIRD Really look at the third line below.
float fVal = 13.3892F;
printf("Float value ==> fVal :%f\n",fVal);
long lVal = * (long *) &fVal;
printf("float as long ==> lVal: %ld\n", lVal);That 3rd line takes the address of the float
&fVal
and what!?! multiplies it times a long pointer? or something?!? :confused: The Point But the point is, that after you do that, C compiler believes that you've converted the bits that represented the float value into a long. CRAZY!!! :wtf: I've never seen that syntax before. :wtf: Here's the output:Float value ==> fVal :13.389200
float as long ==> lVal: 5391137322Here's a snapshot of what the narrator in the video says. Really funny (read the caption in the snapshot explaining how/why C convert float bits to long). https://i.stack.imgur.com/YHyR5.png[^] PS - If you already knew this, you are a freaking C genius. Seriously. Or, you've been completely tortured by C. :laugh: EDIT / UPDATE Oh, the syntax is easier than I thought. It casts the float address as a long* and then gets the value stored at (*) that address and stores it at the address of the long -- which is actually the original address of the float (but now converted to a long). WHAT?!
raddevus wrote:
C++
Copy Code
float fVal = 13.3892F;
printf("Float value ==> fVal :%f\n",fVal);
long lVal = * (long *) &fVal;
printf("float as long ==> lVal: %ld\n", lVal);That 3rd line takes the address of the float
&fVal
and what!?! multiplies it times a long pointer? or something?!? :confused:That's not what it does. It casts the address of fVal to a pointer to a long, and then dereferences that pointer. It's completely unnecessary code. All he had to do was cast the fVal to long and then assign that.
The difficult we do right away... ...the impossible takes slightly longer.
-
raddevus wrote:
C++
Copy Code
float fVal = 13.3892F;
printf("Float value ==> fVal :%f\n",fVal);
long lVal = * (long *) &fVal;
printf("float as long ==> lVal: %ld\n", lVal);That 3rd line takes the address of the float
&fVal
and what!?! multiplies it times a long pointer? or something?!? :confused:That's not what it does. It casts the address of fVal to a pointer to a long, and then dereferences that pointer. It's completely unnecessary code. All he had to do was cast the fVal to long and then assign that.
The difficult we do right away... ...the impossible takes slightly longer.
Richard Andrew x64 wrote:
cast the fVal to long and then assign that.
NO!!! Casting involves arithmetic conversion, whereas what we are talking about involves treating the data as a bit pattern.
(long)2.0 == 2
but the bit patterns are wildly different.Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
-
Watched video Fast Inverse Square Root — A Quake III Algorithm - YouTube[^] It's a long video about how Quake III dev created a fast inverse of sqrt for 3D transforms. Yes, I watched the video but I don't understand it completely. :rolleyes: First the Source Code Here's my source code I used to confirm this weird syntax which... Makes C Think the Address Contains a Long Even Though It's a Float This is not a cast of a float value to long -- which would truncate decimal portion. This is a conversion of the float bits to an address which is a long. The bits stay in tact. !!!! :cool: I hope this gets your attention. Third Line Syntax Is WEIRD Really look at the third line below.
float fVal = 13.3892F;
printf("Float value ==> fVal :%f\n",fVal);
long lVal = * (long *) &fVal;
printf("float as long ==> lVal: %ld\n", lVal);That 3rd line takes the address of the float
&fVal
and what!?! multiplies it times a long pointer? or something?!? :confused: The Point But the point is, that after you do that, C compiler believes that you've converted the bits that represented the float value into a long. CRAZY!!! :wtf: I've never seen that syntax before. :wtf: Here's the output:Float value ==> fVal :13.389200
float as long ==> lVal: 5391137322Here's a snapshot of what the narrator in the video says. Really funny (read the caption in the snapshot explaining how/why C convert float bits to long). https://i.stack.imgur.com/YHyR5.png[^] PS - If you already knew this, you are a freaking C genius. Seriously. Or, you've been completely tortured by C. :laugh: EDIT / UPDATE Oh, the syntax is easier than I thought. It casts the float address as a long* and then gets the value stored at (*) that address and stores it at the address of the long -- which is actually the original address of the float (but now converted to a long). WHAT?!
Unfortunately... ['type punning' (which is the name for casting pointers to pointers of different types) is considered undefined behavior in C and C++](https://blog.regehr.org/archives/959) and so frowned upon these days... Instead, you can use a good old `memcpy`, which usually gets generated to the same code as the type punning case: ```C++ float fVal = 13.3892F; printf("Float value ==> fVal :%f\n",fVal); long lVal; memcpy(&lVal, &fVal, sizeof(fVal)); printf("float as long ==> lVal: %ld\n", lVal); ``` This sort of thing is often done when you need to get to the individual bits and bytes of a variable, rather than the quantity it represents. For example, [a software implementation of floating point arithmetic](http://www.jhauser.us/arithmetic/SoftFloat.html) would do this.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
Unfortunately... ['type punning' (which is the name for casting pointers to pointers of different types) is considered undefined behavior in C and C++](https://blog.regehr.org/archives/959) and so frowned upon these days... Instead, you can use a good old `memcpy`, which usually gets generated to the same code as the type punning case: ```C++ float fVal = 13.3892F; printf("Float value ==> fVal :%f\n",fVal); long lVal; memcpy(&lVal, &fVal, sizeof(fVal)); printf("float as long ==> lVal: %ld\n", lVal); ``` This sort of thing is often done when you need to get to the individual bits and bytes of a variable, rather than the quantity it represents. For example, [a software implementation of floating point arithmetic](http://www.jhauser.us/arithmetic/SoftFloat.html) would do this.
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
-
Now you are ready to read this: Bit Twiddling Hacks[^]
..yes you can..il send you my pp acct.🤪🤪🤪🤪