• 0

Recursion


Question

Hi guys. Learning some Java and came across the subject of recursion. There was a snippet of code here which is basically recursion at play:

 

 
public class main {
public static void main(String[] args) {
 
long num;
 
num = fact(5);
 
System.out.println(num);
 
}
 
public static long fact(long n) {
if(n <= 1) 
return 1;
else
return n * fact(n-1);
}
}
Link to comment
https://www.neowin.net/forum/topic/1167889-recursion/
Share on other sites

11 answers to this question

Recommended Posts

  • 0

The running total is held on the stack. Every time a function is called, it pushes a new "frame" on the stack (memory region holding its parameters and local variables), and every time a function returns, it pops its frame from the stack. A simple program like this:

void sayHello() { System.out.println("Hello"!); }

void main() { SayHello(); }
Executes like so:
main()
     -> sayHello()
              -> System.out.println("Hello");
                     -> (... unknown implementation of println ...)

Your function fact() calls itself until the value passed is 1, so it executes like so:

fact(5)
    -> fact(4)
           -> fact(3)
                  -> fact(2)
                         -> fact(1)

fact(1) evaluates to 1 and returns.

fact(2) evaluates to 2 * fact(1), which is now 2 * 1. It returns 2. 

fact(3) evaluates to 3 * fact(2), which is now 3 * 2. It returns 6.

etc.

hence fact(5) evaluates to 120.

 

As you can see, there is no variable in the program that explicitely holds the running total; rather it is an implicit variable held on each stack frame representing the return value of each function call. It is a bit hard to understand until you do some assembly and see how this happens under the hood.

 

The stack is a very limited memory region - typically 1MB. Abusing recursion is the most typical way of blowing up the stack, a bug referred to as a stack overflow.

  • Like 2
Link to comment
https://www.neowin.net/forum/topic/1167889-recursion/#findComment-595849741
Share on other sites

  • 0

 

Hi guys. Learning some Java and came across the subject of recursion. There was a snippet of code here which is basically recursion at play:

 
public class main {
public static void main(String[] args) {
 
long num;
 
num = fact(5);
 
System.out.println(num);
 
}
 
public static long fact(long n) {
if(n <= 1) 
return 1;
else
return n * fact(n-1);
}
}

Stop repeating yourself....

Not sure if there is a question in here.. but basically recursion is the act of repeating..

so like

private void main()
{
   minusTo1(100);
}


private void minusTo1(int num)
{
  //Check if num - 1 == 1. 
  if (--num != 1)
    return minusTo1(num);
  else
    return 1;
}

 

Link to comment
https://www.neowin.net/forum/topic/1167889-recursion/#findComment-595848245
Share on other sites

  • 0

did ask for an explantion (apparently, it decided to delete that massive paragraph I wrote for some strange reason) on how this code actually works as I wasn't sure how exactly the method managed to return 120 as I couldn't see where the multiplication was actually happening, even in the debugger I couldn't see a hidden variable holding the total figure as it went around. Also, I wasn't entirely sure how exactly it worked. 

 

I believe Firey's example helps me get the concept of recusion better, but I still don't understand where exactly it did the multiplication or where the variable was held?

Link to comment
https://www.neowin.net/forum/topic/1167889-recursion/#findComment-595848269
Share on other sites

  • 0

did ask for an explantion (apparently, it decided to delete that massive paragraph I wrote for some strange reason) on how this code actually works as I wasn't sure how exactly the method managed to return 120 as I couldn't see where the multiplication was actually happening, even in the debugger I couldn't see a hidden variable holding the total figure as it went around. Also, I wasn't entirely sure how exactly it worked. 

 

I believe Firey's example helps me get the concept of recusion better, but I still don't understand where exactly it did the multiplication or where the variable was held?

Recursion is basically the act of repeating a function until a desired result is met.  I personally use it for retries.  Instead of having to duplicate code.  I will re-call a function (that I am in) to preform a retry.  Kind of like:

int retries = 1;

SendMyData(string data)

{

    //try to send data

    

    //if it fails, check if retries > 0, if so -1 from retries

   //and call SendMyData() passing in the data we got the first time

   

   //if retries is 0, then don't do anything

}

Because reties will already be set to 0, we will not run the function again after it is called the second time.

And because we don't have any code at the bottom to run, it won't duplicate anything.

Link to comment
https://www.neowin.net/forum/topic/1167889-recursion/#findComment-595848295
Share on other sites

  • 0

all lies in this line :

return n * fact(n-1);

return will be done when "all" calculation on the right will be finished, as it's a recursive function that "terminates" (and returns 1) when n is lower or equal than 1. The actual calculation is this one :

 

fact(5) => return ((((5 * fact(4)) * fact(3)) * fact(2)) * 1;

 

As everything is a multiplication in this case, it's equal to 5 * 4 * 3 * 2 * 1 = 120 

 

Hope it helps :) (and that i didn't get anything wrong :P...)

  • Like 2
Link to comment
https://www.neowin.net/forum/topic/1167889-recursion/#findComment-595848309
Share on other sites

  • 0

fact(5) => return ((((5 * fact(4)) * fact(3)) * fact(2)) * 1;

Well technically this is not correct. The calculation is 5 * 4 * 3 * 2 * 1, not 5 * fact(4) * fact(3) * fact(2) * 1, which would give a much larger number.

 

A more correct and graphical way of putting it would be:

fact(5) = 5 * fact(4)
              fact(4) = 4 * fact(3)
                            fact(3) = 3 * fact(2)
                                          fact(2) = 2 * fact(1)
                                                        fact(1) = 1
Link to comment
https://www.neowin.net/forum/topic/1167889-recursion/#findComment-595850333
Share on other sites

This topic is now closed to further replies.
  • Posts

    • Astra 0.6.1 Beta by Razvan Serea Astra is an audiophile music player designed for local music libraries, supporting MP3, FLAC, WAV, AAC, OGG, M4A, OPUS, WMA, AIFF, and more via FFmpeg. It offers gapless playback with pre-buffering, multichannel audio remapping, and Dolby Atmos decoding, ensuring albums play seamlessly while maintaining high-fidelity sound. Astra features real-time DSP visualizers powered by a native C++ engine, including an oscilloscope, spectrum analyzer, and vectorscope. A fully parametric 10-band EQ with live frequency response, built-in presets, and AutoEQ headphone calibration import lets you precisely shape your sound. Playback controls include shuffle, repeat, and drag-and-drop queue management, while the library automatically extracts metadata, album artwork, and supports global search, favorites, and recently played tracking. Additional features include output device selection, delay calibration, customizable themes, fullscreen and mini-player modes, Discord Rich Presence, optional Last.fm scrobbling, and an opt-in local API for integrations. Astra delivers a complete, high-quality desktop audio experience with no telemetry, accounts, or streaming. Astra 0.6.1 Beta changelog: Lyrics Initial XLRC support via @boof2015/xlrc 0.2.0 (#131) XLRC sidecar scanning, manual import, and renderer support Word timing, furigana, translations, voice labels, and translation-priority controls for XLRC Fullscreen lyrics overhaul with additional layout polish Manual lyrics editor with LRC, XLRC, and plain-text modes Drag-and-drop lyrics import plus sync offset controls Clickable synced lyrics for seeking, with popout and transport lyrics updates (#138) Fixed lyrics info sidebar scrolling (#138) Added a workaround for LRCLIB instability Metadata & Library Metadata editor rebuilt as a side panel Virtual DB metadata overrides and optional direct file tag writing Bulk metadata editing for title, artist, album, album artist, genre, year, track/disc numbers, and artwork Undo/redo support for virtual metadata edits Clear overrides action and default save-mode preference Artist page grid view added, with later design and sizing refinements Improved Jump to Playing with smart source, queue, album, artist, and library track targets Fixed smart source jump behavior Playlists Fixed VLC-style M3U import failures (#127) Added playlist export to M3U/M3U8 (#118) Improved imported playlist path resolution and missing-entry preservation Shuffle added to playlist pages (#121) Remove tracks directly from playlist views (#128) Fixed create-playlist-from-track modal closing when clicking inside it (#137) Multi-select quality-of-life fixes Right-click context menus no longer clear multiselections UI & Navigation Fixed UI scaling regressions in sidebar and home surfaces (#122, #123) Fixed transport bar regression (#126) Fixed horizontal scrolling on Home and Library rails Fixed artist grid sizing while searching Updated playlist action buttons and related layout polish Additional fullscreen lyrics visual adjustments Visualization Scopes and visualizers now respect UI scaling settings (#155) Added shared canvas sizing logic for correct DPR/backing-store behavior Canvas sizing tests added for visualizer scaling regressions Discord RPC Discord Rich Presence activity structure refactored Compact status can prioritize title or artist Profile info line can show file info or album Title and artist links can target YouTube Music, Last.fm, or be disabled Optional small Astra badge for cover-art presence Configurable “clear when paused” timing Added Discord activity tests Scrobbling Fixed custom Last.fm2 API profiles being accidentally blocked Expanded scrobbler profile protocol handling coverage Stability & Tests Added/expanded tests for XLRC parsing, lyrics presentation, metadata editor state, playlist import/export path handling, artist grid layout, horizontal scrolling, canvas sizing, and Discord RPC activity building Download: Astra 0.6.1 Beta | 138.0 MB (Open Source) View: Astra Home Page | Github | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • How does it compare to the "SeeStar S30 Pro" and the "Vespera PRO 2"?
    • Indeed. And note that those units are MUCH cheaper than this new Steam Machine...ahem.
    • Microsoft have found a way to convert RAM and SSDs into water.
  • Recent Achievements

    • Week One Done
      Almohandis earned a badge
      Week One Done
    • Rookie
      dorf went up a rank
      Rookie
    • First Post
      mike_rumble earned a badge
      First Post
    • Dedicated
      tuben earned a badge
      Dedicated
    • Week One Done
      mnsgroup earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      502
    2. 2
      +Edouard
      209
    3. 3
      PsYcHoKiLLa
      100
    4. 4
      Michael Scrip
      85
    5. 5
      neufuse
      69
  • Tell a friend

    Love Neowin? Tell a friend!