If so .. there is your problem. vector2d_length may be using a very poor square root ...
I think it's not the square root that's the problem, it's the quadratation of the components before doing the square root that causes trouble. A float has an 8-bit exponent ranging from -127 to 128. Squaring values between 0 and 1 effectively halves the exponent, so as soon as the values get smaller than around 2-64 (\~1e-20) you're in trouble.
If you want to be able to normalize vectors with such small components, first scale them up, then normalize them.
vector normalize(vector v)
const float smallvalue = 1.0e-20f;
const float largevalue = 1.0e20f;
if ((abs(v.x) < smallvalue && abs(v.y) < largevalue) ||
(abs(v.y) < smallvalue && abs(v.x) < largevalue))
v.x *= smallvalue;
v.y *= smallvalue;
// do the rest of the normalization here
.edit: made it somewhat more robust.