jmoenig / Snap

a visual programming language inspired by Scratch
http://snap.berkeley.edu
GNU Affero General Public License v3.0
1.52k stars 749 forks source link

Possible round-off error #348

Closed vshi closed 10 years ago

vshi commented 10 years ago

i am changing a variable x by a number n.

x is a random number up to two decimal places (rounded to the hundredth).

n is the result of multiplying an integer entered by the the user and one of the entries of a list of decimal numbers (all entries in the list are rounded to the hundredth digit).

sometimes, this results in x being changed by a number very very slightly bigger or smaller than n.

this error does not show up consistently.

for example of the error, see picture below.

i am not sure if this is an issue with the change block, the way snap reads in user input, the way list entries are interpreted, the "random" block, or something else entirely.

please fix! it'd be much appreciated :]

roundoff_error

cycomachead commented 10 years ago

In this example, do you know what x was previously, and what the answer provided was?

vshi commented 10 years ago

it seems to happen randomly. i can't remember what it was for the picture i provided, but i tried it again and it happened with x = 96.12, answer = 4, and item i of list = 0.1. this resulted in x = 96.520000000001

vshi commented 10 years ago

both these code snippets reliably produce the error. it looks like it might have something to do with the "ask" block. roundoff_error_2

cycomachead commented 10 years ago

Unfortunately, this is a problem with the way computers do math, and not with Snap itself. (I used specific numbers to confirm that there wasn't anything funky happening in Snap.)

The short (and simplified) answer is that when working with decimals computers always need to round numbers, and there are certain cases where it's hard to be precise. If you're curious and want to learn more, the system is called Floating Point. Some more details can be found here: http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

So, unfortunately, I don't think there's anything we can really do in Snap.

vshi commented 10 years ago

ah, i kind of suspected that... okay, i'll pass the word along. thanks.

brianharvey commented 10 years ago

We /could/ convert numbers to the simplest rational form within some epsilon of the given number. See the RATIONALIZE function here, for example: https://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Numerical-operations.html. (Note: Numerical analysts such as Prof. Kahan would be very upset by this; there are good reasons why it's a bad idea if several transcendental functions are composed and you simplify in the middle. But for kids, or even BJC students, it might still be desirable.)

cycomachead commented 10 years ago

Numerical analysts such as Prof. Kahan would be very upset by this;

Heh, I bet they would be.

Yeah, the thought of doing something similar did occur to me, but I've not had enough experience with floating point to know if that'd cause more trouble than it's worth. I did just test with scratch and it seems to be rounding off for some cases, and I do agree that for BJC students that it's an acceptable practice. However, I do think it should be worth carefully considering since if students start to use Snap for more advanced projects, or data analysis (very real possibly given AP CSP) then would we see too many ill side-effects? You'd have a much better answer / guess than I would.

xtitter commented 10 years ago

Or, better in this case, use a scheme-number-in-javascript implementation (e.g., http://john-edwin-tobey.org/Scheme/javascript-bignum/docs/files/schemeNumber-js.html, https://github.com/dyoo/js-numbers) and keep numbers 'exact' where we can. I wonder how many projects would noticeably slow down with this?