How to handle different data types (uint8, uint16, float) in Volume Datasets? So I've written a personal volume renderer which currently visualizes datasets (CT-Scans mostly) that have a .raw extension and the values are in the range 0-255 or uint8.

Now I searched the net and found some datasets that had uint16 (ranging from 0-4095) and float which was arbitrary but went from like 0-20 or something. I think the uint16 dataset corresponds to values in Hounsfield scale but I'm unsure of how do I map these to 0-255.

I haven't implemented any fancy transfer functions currently. For the uint8 datasets I just read the isovalues from the dataset and use that value for all the channels (r,g,b) as it is giving me a grayscale image.

EDIT:- To clarify further, I have implemented a gpu based ray marching algorithm taking help from this site here, I'm taking the datasets from here, As mentioned in the comments I don't really know how you should interpret these values, but a quick read shows that normally the CT data is based on Hounsfield units which represents density afaik.
Ok after searching a whole lot on the internet I found a slide which answered most of my questions and doubts. I'm dumping it here in-case anybody else is curious what these datasets usually contain and what should be (in my opinion) the correct way to handle mappings.

So apparently the CT scanner always records the densities of the substances in Hounsfield Scale. The Hounsfield Scale itself is a little interesting. For body organs and stuff, the scale has the range from -1024 to 3000. This was the scale I talked about earlier as when normalized the values usually lie between 0-4096. However metals usually go past this 3k boundary and some metals like stainless steel and gold having HU number as high as 13k and 30k respectively. This is usually called the "extended" Hounsfield Scale.
Some volumetric datasets contain data for computer simulations mostly fluids etc. For these type of datasets either density or flow velocity is captured. Precision is important for these datasets hence float is used.

Hence the uint8 datasets are probably grey-scale data converted from the original HU units. uint16 datasets contain the original Hounsfield data while float may contain density or velocity. 

Now for the mapping part, as others stated one way might be to just divide by the max value of the data type or the max value of the data itself, to get the uint16 or float data in 0-1 range then multiply by 255 to get a grey-scale image. However doing so may lower the contrast and hide minute details. For example, dividing a uint16 dataset that contained only HU units in range 300-2000 with the $2^{16}$ will map the HU units to only a small range of grey values. Dividing by 2000 in this case is surely better. However after reading how CT-scanners work, it's better to let the user set the minimum and maximum range of Hounsfield units they wish to observe. This is usually called the window width. And then map this window width to the whole 0-255 range of grey levels as YardenJ2R mentioned in his second formula. This is more in line with how radiologists visualise the data. 

For fancy transfer functions which I haven't implemented yet, we might have to convert the Hounsfield units to opacity or grey scale as mentioned above then map that opacity to color or there might be a way to directly map it to colors using a LUT as defined by the user's control point settings.