To have pixel perfect movements, I use movement loops, but this only lets you move in integers unless you store the speed remainder.
ySpeedRemainder = frac(ySpeedRemainder) + ySpeed;
repeat(abs(ySpeedRemainder))
{
if place_meeting(x, y + sign(ySpeedRemainder), objSolid)
ySpeed = 0;
else y +=...