Here is a procedure I wrote to apply a greek prefix to a value so that the coefficient lies between 1 and 1000.

 

applyGreekPrefix := proc(x)
	description
		"Accepts a number, and if it has units, a Greek prefix is added so that the coefficient is between 1 and 1000",
		"Values without units or a unit of muliple units are returned as-is"
	;
	local prefixes, powers, value, unit, exponent, new_value, idx, prefix, strUnit, new_unit, i, SIx, returnval;
	
	if Units:-Split(x)[2] = 1 or numelems(indets(op(2, x), 'name')) > 1 then	
		# Value has no units or consists of multiple units
		returnval := x;
	else
		# Define the SI prefixes and their corresponding powers of 10
		prefixes := ["q", "r", "y", "z", "a", "f", "p", "n", "μ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q"];
		powers := [seq(i, i = -30 .. 30, 3)];
		
		# Convert to SI unit w/o prefix
		SIx := convert(x, 'system', 'SI');		
		# Separate the value and the unit
		value := evalf(op(1, SIx));
		unit := op(2, SIx);
		strUnit := convert(unit, string);  # Convert the unit to a string representation
		
		# Calculate the exponent of 10 for the value
		exponent := floor(log10(abs(value)));
		
		# Find the closest power of 10 that makes the coefficient between 1 and 1000
		idx := 0;
		for i from 1 to nops(powers) do
		   if exponent >= powers[i] then
		       idx := i;
		   end if;
		end do;
		
		# Adjust the value based on the selected prefix
		new_value := value / 10^powers[idx];
		prefix := prefixes[idx];
		# Construct the new unit using Units:-Unit if a prefix is needed
		if prefix = "" then
		   new_unit := unit; # No prefix needed, use the original unit
		else
		   new_unit := parse(StringTools:-Substitute(strUnit, "Units:-Unit(", cat("Units:-Unit(", prefix))); # Construct a new unit with the prefix
		end if;
		
		# Return the adjusted value with the new unit
		returnval := new_value * new_unit;
	end if;	
	return returnval;
end proc:
list_tests:=[0.0001*Unit('kV'), 10000*Unit('V'), 10*Unit('V'/'us'), 12334];
for test in list_tests do
	print (test, "becomes", applyGreekPrefix(test));
end do;

 


Please Wait...