Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. The Weird and The Wonderful
  4. QuakeIII: Fast Inverse of Sqrt in C (float to long)

QuakeIII: Fast Inverse of Sqrt in C (float to long)

Scheduled Pinned Locked Moved The Weird and The Wonderful
comalgorithmsdata-structuresquestionannouncement
10 Posts 7 Posters 60 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • raddevusR Offline
    raddevusR Offline
    raddevus
    wrote on last edited by
    #1

    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: 5391137322

    Here'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?!

    P P 1 Richard Andrew x64R S 5 Replies Last reply
    0
    • raddevusR raddevus

      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: 5391137322

      Here'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?!

      P Offline
      P Offline
      PIEBALDconsult
      wrote on last edited by
      #2

      Inverse of square root? Just square it. ;P

      1 Reply Last reply
      0
      • raddevusR raddevus

        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: 5391137322

        Here'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?!

        P Offline
        P Offline
        Peter_in_2780
        wrote on last edited by
        #3

        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

        1 Reply Last reply
        0
        • raddevusR raddevus

          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: 5391137322

          Here'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?!

          1 Offline
          1 Offline
          11917640 Member
          wrote on last edited by
          #4

          Now you are ready to read this: Bit Twiddling Hacks[^]

          raddevusR K 2 Replies Last reply
          0
          • 1 11917640 Member

            Now you are ready to read this: Bit Twiddling Hacks[^]

            raddevusR Offline
            raddevusR Offline
            raddevus
            wrote on last edited by
            #5

            That is a truly amazing resource. Thanks! :thumbsup:

            1 Reply Last reply
            0
            • raddevusR raddevus

              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: 5391137322

              Here'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?!

              Richard Andrew x64R Offline
              Richard Andrew x64R Offline
              Richard Andrew x64
              wrote on last edited by
              #6

              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.

              P 1 Reply Last reply
              0
              • Richard Andrew x64R Richard Andrew x64

                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.

                P Offline
                P Offline
                Peter_in_2780
                wrote on last edited by
                #7

                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

                1 Reply Last reply
                0
                • raddevusR raddevus

                  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: 5391137322

                  Here'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?!

                  S Offline
                  S Offline
                  Stuart Dootson
                  wrote on last edited by
                  #8

                  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

                  raddevusR 1 Reply Last reply
                  0
                  • S Stuart Dootson

                    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

                    raddevusR Offline
                    raddevusR Offline
                    raddevus
                    wrote on last edited by
                    #9

                    Ah, good to have a name for the thing. Thanks for providing more insight. :thumbsup:

                    1 Reply Last reply
                    0
                    • 1 11917640 Member

                      Now you are ready to read this: Bit Twiddling Hacks[^]

                      K Offline
                      K Offline
                      kapalmuks 3
                      wrote on last edited by
                      #10

                      ..yes you can..il send you my pp acct.🤪🤪🤪🤪

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups