Odd results with basic math

Hi, I’m very new to Sonic Pi and loving it.

However, I’ve come across some unusual behaviour with basic math which has me stumped:

Firstly, whenever I try to divide a small number with a larger number, which should yield a result lower than 1, I get 0 - for example:

puts 1/2 = 0

but

puts 2/1 = 2

That’s the first. Secondly, and odd thing occurs when a subtraction gives a result close to 0, from around 0.3 - for example:

puts 1-0.8 = 0.19999…6
puts 2-1.8 = 0.19999…6

but

puts 0+0.2 = 0.2

Does anyone else find this or is it a quirk of my system?

Many thanks, Paul.

Try 1 / 2.0 as opposed to 1 / 2
If integers are used in calculations ,
then results are integers .
A ’ float ’ ( decimal ) in the equation
will give decimal results …

Awesome, that sorted out the division issue, huge thanks!

However, I’m still getting the strange recurring decimals, even with 1.0 - 0.8 - however, this isn’t causing any problems for me at the moment, and judging by how close they are to the true value, it may never be an issue.

Hi there, what’s you’re running into here is caused by the fact that floating point numbers are inaccurate by design. This is due to them occupying a limited size in memory, so they can’t represent every possible decimal number and therefore have limited precision.

For more background Google for “issues with floating point numbers” which will return a number of articles explaining this situation in varying detail. For example: Losing My Precision: Tips For Handling Tricky Floating Point Arithmetic | SOA

Thanks for the advice and link, this was not something I was aware of before.

I’m really enjoying using Sonic Pi and have signed up on Patreon. Keep up the good work!

Paul.

1 Like

As @samaaron explains, all computer floating point numbers have a finite precision. The default Float is not decimal— it is binary— and has a precision of 53 bits (nearly 16 decimal digits). That should really be enough for our purposes, but it is still possible to manipulate them incorrectly in a calculation, causing loss of precision, or make invalid comparisons like

a = 0.15 + 0.15
b = 0.1 + 0.2
if a==b
  puts "yea"
else
  puts "nope"
end

It is not a problem with the numbers; you just have to use them correctly.

If you really need decimal numbers instead of binary, you can do something like

require 'bigdecimal'
puts BigDecimal("1")-BigDecimal("0.8")

but you probably don’t. Try something (depending on what you are trying to do!!!) like

a = 1 - 0.8
b = 2 - 1.8
puts (a-b).abs < 0.00001

That will not make any computer scientists happy, but it’s OK since your music should usually not care about 0.00001 beats or anything below a few milliseconds, humans cannot perceive such intervals.

1 Like