This works correctly in my fork without changing price decimals. I fixed this bug a few years ago and I think the fix was rather obscure. I think this was it:
Change the includes/current_user.inc function to:
function price_decimal_format($number, &$dec)
{
$dec = user_price_dec();
$str = strval($number);
$pos = strpos($str, '.');
if ($pos !== false)
{
$len = strlen(substr($str, $pos + 1));
if ($len > ini_get('precision')-3)
$len = ini_get('precision')-3;
if ($len > $dec)
$dec = $len;
}
return number_format2($number, $dec);
}
from the base
function price_decimal_format($number, &$dec)
{
$dec = user_price_dec();
$str = strval($number);
$pos = strpos($str, '.');
if ($pos !== false)
{
$len = strlen(substr($str, $pos + 1));
if ($len > $dec && $len < ini_get('precision')-3)
$dec = $len;
}
return number_format2($number, $dec);
I think the base code sees the desired precision ($len > $dec) but only sets $dec to $len if $len happens to be less than the php.ini precision. It usually isn't so it uses the user decimals (which is probably 2, which causes the rounding problem you describe).
In my code, the desired precision is tested against the php.ini precision and truncates if necessary. Then if the result is greater than user decimals, it uses that. I think this is what the base coder wanted but just didn't code it right.
If that doesn't fix your problem, I will have to look deeper into how I fixed it.