Problems scaling a list of integers, inconsistent and inaccurate results

dequalsrxt's icon

I've been playing around with a patch where I run a list of numbers into a slide object, then scale the result to the range of the original list. But I noticed I wasn't getting the results I expected from the scale object, even without the slide object and the scale set 1 to 1 so that it should output the original list unaltered. Everything works as expected if I use floats, but I need the final list to be integers. The problem persists if I convert the list to integers after the scale object, even if the conversion is from e.g. 1.0 to 1 (int).

Max Patch
Copy patch and select New From Clipboard in Max.

Source Audio's icon

run your input through iter or use some different means of

scaling the list.

TFL's icon

iter won't help here, the same happen with single values.
I think it's due to some float to integer conversion issue. When you send a float into a [number] or [t i], the float won't get rounded, but floored. That's why send 0.99999 into an integer number will give you a 0.

I still struggle to perfectly understand that, but in computers, a float number can sometimes not be exactly equal to the number you want to represent. What seems to happen here is that the float representation of some numbers (the 6 that are missing from your 64 items list) is slightly below the integer, while others are slightly above. What makes things even more confusing is that the message object and the float version of [number] seems to account for this and show you the value you are expecting.

I might be wrong here, but this is how I explain it to myself. Better explanations are welcome :)



Max Patch
Copy patch and select New From Clipboard in Max.


EDIT: mmmh it seems that a float32/float64 number can actually accurately represent integers. Things start to become messed up when some calculation is involved (like with the scale object), where some in-between results cannot be exactly represented as float, and the end result suffers from the accumulation of these small errors.

Source Audio's icon

iter would help to work without lists.

if scale is necessary (zmap has no such problems)

then one can tweak output using whatever needed to display

what on wants.

Source Audio's icon

float list can be converted to int using

vexpr int(round($f1))

Max Patch
Copy patch and select New From Clipboard in Max.

dequalsrxt's icon

@Source Audio - that vexpr formula works a treat. iter into round 0, convert to int, then rebuild the list with thresh works too, but vexpr saves all those steps. zmap also sort of works, but still needs that vexpr formula. I tried it with just $i1 and it introduced the same problems on some values. And I'd like to keep scale so I can invert the list if I want.

Max Patch
Copy patch and select New From Clipboard in Max.

EDIT: mmmh it seems that a float32/float64 number can actually accurately represent integers. Things start to become messed up when some calculation is involved (like with the scale object), where some in-between results cannot be exactly represented as float, and the end result suffers from the accumulation of these small errors.

That makes sense.

Roman Thilenius's icon

33 can be represented in float32 and float64 without errors, but that does not explain what the [number] object shows.

the "problem" is the scale object, which actually performs a somewhat strange calculation inside, even though in your mind it should "not do anything" when in and out ranges are the same. :)

the difference is so small that not even printit can print it (7 zeroes behind the comma)

[scale] has had bugs like that since 30 years.

that´s why clever boys use [expr] or math objects, which do not calculate this nonsense.

expr ((($f1-$f2)/($f3-$f2))*($f5-$f4))+$f4