Skip to content

Fractions and Units in PHP

For the bililite webservices, I kept all the data in what I would call "standard" American medical units, centimeters for height, kilograms for weight, mmHg for blood pressure, mg/dl for bilirubin. But lots of doctors use pounds and inches, and it would be nice to allow those as well. I could have separate data entry forms for different units, but I decided it would be easier and more useful to allow units on the numbers. I could allow fractions as well (which some of my medical assistants still insist on recording; 21 5/8 instead of 21.625. My EMR blows a gasket with that, but my program would do better). And then, I could allow mixed units, like a weight of "6 pounds 5 1/2 ounces".

I didn't find anything exactly right on the web, but symcbean on stackoverflow had a clever idea for evaluating fractions: turn "2 1/2" into "2+1/2" then use eval.

Try the code.

function convertCK($usIn){
	// convert input numbers with optional units (pounds, inches etc.) to centimeters and kilograms
	$factors = array(
		'f' => 30.48, // feet
		"'" => 30.48,
		'i' => 2.54, // inches
		'"' => 2.54,
		'p' => 0.45359237, // pounds
		'l' => 0.45359237, // lb
		'#' => 0.45359237,
		'o' => 0.0283495231, // ounces
		'g' => 0.001 // grams
	$usIn = trim($usIn);
	// turn spaces in mixed numbers to pluses, for the eval hack
	$usIn = preg_replace ('%(\d)\s+(\d)%', '$1+$2', $usIn);
	preg_match_all('%(?<num>[0-9./+]+)\s*(?<unit>\D*)%', $usIn, $values, PREG_SET_ORDER);
	$ret = 0;
	foreach ($values as $value){
		$unit = strtolower($value['unit']{0});
		$factor = isset($factors[$unit]) ? $factors[$unit] : 1;
		$ret += $factor*eval("return $value[num];");
	return $ret;

The code above is simplified by the fact that all the units I care about have unique first letters, but if you wanted more units you could simply add more entries in the factors array and make the $unit = strtolower($value['unit']{0}); line more sophisticated. usIn is used as a variable name to remind me that it is unsafe—it may come from user input and has to be sanitized with the regexp before it can be trusted.

It allows the American notation for tic marks for feet and inches, since getting that wrong can be disastrous.

Post a Comment

Your email is never published nor shared. Required fields are marked *