Руководство немного тонкое, но параметры должны быть строками.Если вы сделаете их строками, они будут работать.
bcscale(8);
$x1 = bcsub('0.04217' ,'0.00007', 8);
$x2 = 0.04217 - 0.00007 ;
echo 'x1 = '. $x1 . PHP_EOL;
echo 'x2 = '. $x2;
РЕЗУЛЬТАТ
x1 = 0.04210000
x2 = 0.0421
Также из руководства
Внимание! Передача значений типа float в BCMathфункция, которая ожидает строку как операнд, может не иметь желаемого эффекта из-за способа, которым PHP преобразует значения с плавающей запятой в строку, а именно, что строка может быть в экспоненциальной записи (что не поддерживается BCMath), и что десятичный разделитель зависит от локали(в то время как BCMath всегда ожидает десятичную точку).
Что касается точности,
bcscale(8);
$x1 = bcsub('0.04217' ,'0.00007', 6);
// ^
$x2 = 0.04217 - 0.00007 ;
echo 'x1 = '. $x1 . PHP_EOL;
echo 'x2 = '. $x2;
РЕЗУЛЬТАТ
x1 = 0.042100
x2 = 0.0421
И
bcscale(8);
$x1 = bcsub('0.04217' ,'0.00007', 4);
// ^
$x2 = 0.04217 - 0.00007 ;
echo 'x1 = '. $x1 . PHP_EOL;
echo 'x2 = '. $x2;
РЕЗУЛЬТАТ
x1 = 0.0421
x2 = 0.0421