For some reason unknown to me, the SIFT descriptor implemented in OpenCV converts the final values to uchar
(0 - 255) and has always done so since I remember. It is a waste of space, since the resulting values are stored in a float descriptor, and it also hinders matching.
What I do is compile my own version of SIFT where I just leave out the conversion to bytes (in the link), and I get nice floating point values.