How to understand the base case of a recursion

Could you use a helper block?

Also, new users can't have images, but you can use [scratchblocks] (scratchblocks (5)::motion ) [/scratchblocks]

Can you share the project?

Two things:

  1. You are probably overthinking the problem. Once I see your code, I bet we can work out how to organize your program without a "level" variable at all!

  2. It's a really obscure feature, but a procedure can get at its caller's variables:

  1. But, again, I don't suggest going down that rabbit hole yet.

I don’t know your algorithm, but I can think of one that may be close.
Suppose you would like to know the how-maniest digit behind the decimal point is the final non-zero digit:

However … there’s a snake in the grass. It’s called rounding error:

One way to attack this is treating the original number as a text string:

And in this particular case you don’t even need explicit recursion:

BTW the text manipulation blocks are from Snap! libraries:

  • Words, sentences
  • Strings, multi-line input

Does this help you?

This is a separate post, as its subject (rounding errors) is actually off-topic.

I was surprised to find the BIGNUMS library doesn't take care of rounding errors like this:

untitled script pic (59)

There is probably a way around it, but a generally usable approach is not obvious, at least to me. My suggestion for a future version (?) of BIGNUMS is that this kind of rounding error will be prevented as-much-as-reasonably-possible.

Either rounding errors are prevented or they are not - there is no try :slight_smile:

The point of BIGNUMS is to implement Scheme numbers1., allowing infinitely large numbers and precise radicals as numbers. The point of radicals are to reduce the amount of imprecision2 due to the impossibility of storing irrationals.


  1. The Snap! Manual (version 8.0)
  2. The Scheme Programming Language

The imprecision of floating point isn't the fault of IEEE 754. There are only finitely many bits in your computer, and so almost all real numbers are going to be unrepresentable exactly no matter how you slice it. If a number is rational, and non-astronomical, you can represent it exactly using two bignums (exact integers) for numerator and denominator.

You can extend the set of exactly representable numbers if you're willing to use a non-human-readable representation. For example, if you know a Taylor or Fourier series equal to your number, you can represent it exactly as a function that computes the coefficients of the series. But looking at that function won't tell you anything directly about the size of the number. You have to call the function a few hundred times and add up the results (starting with the 400th term and working backward to the first term) to get an approximation to the value.

Every floating point bit pattern represents a range of values. What we could do, and arguably should do, is find the simplest rational number within that range (smallest numerator+denominator) and display the decimal representation of that number. That would solve the 0.141500000000018 problem. (I didn't count the zeros; don't bother telling me I got it wrong.) Or, even more easily, we could look for a string of zeros or nines in the digit string we're about to display and chop them off. That would make y'all happy, and often it'd be the right answer, but sometimes the right answer to your computation really would be 3.000000001, and you'd be misled into thinking the answer was an integer.

IEEE 754 (invented at Berkeley, so I'm defensive about it :~) ) takes pains to give the most accurate answers to actual problems that it can. For example, it denormalizes numbers with the smallest representable exponent field, so that you can have positive numbers closer to zero than you would without that rule.

Oh, well … I guess you (bh) are right.

If one considers e.g. 3.1415 a floating point number - or, as you put it, a representation of a range of numbers (uncountably infinitely many, actually) - then it doesn’t make sense to treat it like an exact rational number (31,415 / 10,000 … or 6,283 / 2,000).

If, OTOH, one considers it an exact rational number, one should have defined it as such in the first place (e.g. 31,415 / 10,000), and when processing it using the BIGNUMS library, the issue wouldn’t have occurred at all.

Thx4 explaining! I rest my case.

This is a well-crafted response. I retract my statement.


yes i can, here's the code

Okay, after a lot of digressions (sorry, but I hope they were interesting) I am finally getting to your original question, now that you've posted the actual project!

@bluebaritone21 gave one answer early on:

Here's how you'd do that:

lowest digit testing script pic

And then, if you want, you can even hide your original two-input block in the palette:
File menu :page_facing_up: > Hide blocks

The two blocks with the same "name" (title text) are distinguished by Snap! because one has 1 input and the other has 2 inputs.

In Snap! version 10, in development, you'll be able to give a block an optional input. Then your block will look like this:
backquote script pic
If you click the arrowhead at the right, it'll look like this:
backquote script pic (1)
This will avoid the need for a separate procedure.

this works perfectly, thank you