[JS] float precission , number division
Hello .
Im feeling stupid . Please look at the code and explain to my wonky head why i cant get the same division result of every cycle ?
function msg_int(n){
var div = 1/4 ;
var result = (n*div)/1.5
/* filter test output
every "1" of 6 steps
triggers result of a division
to the max window */
var m = n % 6 ;
if(m === 1){
post(result.toFixed(64));
post();
}
}
for example :
when i send " 1 " through the inlet , what im getting in 64bit bit precision is :
0.1666666666666666574148081281236954964697360992431640625000000000
but when " 7 " is sent :
1.1666666666666667406815349750104360282421112060546875000000000000
why is that happening ? what is going on with the decimals ?
edit :
0.1666666666666666574148081281236954964697360992431640625000000000
1.1666666666666667406815349750104360282421112060546875000000000000
2.1666666666666665186369300499791279435157775878906250000000000000
3.1666666666666665186369300499791279435157775878906250000000000000
4.1666666666666669627261399000417441129684448242187500000000000000
5.1666666666666669627261399000417441129684448242187500000000000000
6.1666666666666669627261399000417441129684448242187500000000000000
7.1666666666666669627261399000417441129684448242187500000000000000
Floating-point is only finite accuracy. If you want infinite accuracy, you need an infinite number of bits.
I've written about this hundreds of times on the list. Find and read Peter Elsea's tutorial on floating point, or get the full dope on IEEE 754. Wikipedia is, as usual, not a bad place to start http://en.wikipedia.org/wiki/Ieee_floating_point.
Faster than you can say, "Cue Peter." :)
yes i see , thank you . Do you know where can i find Peter's tutorial on floats ? i found some pdf link but its gone actually
Try Max&Numbers.pdf and go to the "The Lowdown on Floats" section. It's pretty short and covers most of the gotchas you'll come across.
Hope this helps.
Yes thank you ,its very informative . unfortunately it doesnt help me too much . Understanding of the problematics not always guarantees of solving the problem (i might be not capable), not sure for what i should aim for now :/ really . Now i just seeing how floats work ,but no way to get around it . Or there is hidden message "you need to live with it " ? . Its not clear . im still stupid
Do I dare ask? What problem are you trying to solve for which 15 decimal digits of precision is not sufficient?
0.1666........... represents triplet bar division . its used to calculate position ,distances ,durations of notes , its used to compute other crucial measurements , this way im always in offset . it would not be a problem if this would be used for representation , the problem is that i need to do operations on distances against positions etc . when adding ,multiplying i will not be able to "place" notes in a appropriate "time" unit :/
Sorry, I don't understand your last post. Perhaps if you post a short example that shows why 64-bit precision is inadequate for a specific task, someone will be able to suggest a solution to you.
For working with musical time units (bar divisions) you could use rational numbers and rational arithmetic as provided by the "bach" externals.
If your smallest note value is, say, a triplet eighth note, then count triplet eighth notes:
0 - first beat (quarter) of bar
1 - second triplet eighth
2 - third triplet eighth
3 - second quarter
etc.
If you're mixing triplets with straight eighths, then count the largest common subdivision, in this case, triplet sixteenths (2 of those equal a triplet eigth; 3 make a straight eighth).
And so on. Most MIDI sequencers used some fairly small subdivision of the quarter note and hope that the granularity is small enough to support every rhythmic unit that's likely to be used. If you know what rhythmic units you want to use, then just pick something sufficiently small to cover all of them in integer combinations.
You can use floats if you really feel obliged to and you'll never hear the difference. At a moderately slow tempo, say quarter = 40, the inaccuracy you're worrying about is in the area of one millionth of a nanosecond. Yes, of course errors can add up. But with these numbers, your patch could have been running since the Big Bang and you'd still be accurate to within a single sample.
So, unless I've misunderstood you, what are you worrying about exactly?
(Caveat: back-of-the-envelope calculations here, I might be off by a decimal place or two. Still.)
Thank you guys for your effort and patience !
@Peter
yes , thats very convenient and smart convention .
That scenario im struggling with is based on the same sort of bar division as Ableton guys invented/used . If i want 16th triplets i need to divide bar on 24 steps which is very natural for me . and this is why i ended up with floats as time index for note representation in bar range . I did it because im working with API where im getting notes from ableton clips (the same time index) ,so this way i dont need to make any TIME conversion . Im working on that notes within my JSUI clip representation and those changes are reflected back to ableton clip .
I wouldnot affraid if i have tiny offset at notees . For a part of manipulation maybe i can compare small differences to SNAP in a right position (but i cant be sure what is a real division result actually ) .So i think that when it comes to note selection ,duplication or other note operations then there might be some surprises . Maybe i should not care too much there but if i offset my BAR RANGE selection to a triplet time then perhaps i will end up with shorter or longer bar length when i back to ableton clip (in result my clip may get off-synced after some time ). Beside other struggles this might be important one .
Even if i will find the other way for math within my code ,at some point i will be forced to convert my time index to ableton time index ,which is represented in floats :/ so i will need to divide 1 anyway :/
SO dividing quarters may help me still there ?