ext-decimal
ext-decimal copied to clipboard
TypeError: Decimal\Decimal::add() expected parameter 1 to be a string, integer, or decimal
Why Decimal does not accept float? It is a nuisance to make use of strval() or (string) in addition to checking that it is not NULL or empty.
use Decimal\Decimal;
class ModDecimal {
public $decimal;
function __construct($val = '') {
$var = strval(empty(trim($val))?'0':trim($val));
$this->decimal = new Decimal($var);
}
function get_decimal() {
return $this->decimal;
}
}
$ok = (new ModDecimal(" 5.05"))->get_decimal()->add(20);
print_r($ok);
Decimal\Decimal Object ( [value] => 25.05 [precision] => 28 )
Given that this is a library for accurate decimal arithmetic and floats use inaccurate decimal representations (eg. 0.1), the decision to disallow float was to encourage an avoidance of float entirely. If a float is on hand, such as one returned by another library or legacy component, the responsibility to convert to string is placed on the caller as an explicit decision.
Could you please share some examples where you find it a nuisance? I am open to relaxing this.
<?php
use Decimal\Decimal;
use Decimal\Decimal;
class ModDecimal {
public $decimal;
function __construct($val = '') {
$this->decimal = new Decimal($this->filter($val));
}
function __call($name, $arguments) {
$args2;
if (in_array($name, ['add','sub']) && empty($arguments))
$arguments = array(0);
else if (in_array($name, ['mul','div']) && empty($arguments))
$arguments = array(1);
foreach($arguments as $args)
$args2[] = $this->filter($args);
if (empty($args2))
$run_decimal = $this->decimal->$name();
else
$run_decimal = $this->decimal->$name(...$args2);
if (in_array($name, ['toFixed','toInt','toFloat','toString']))
return $run_decimal;
else
return new ModDecimal($run_decimal);
}
function filter($val = '') {
if (is_object($val) && get_class($val)=='ModDecimal')
return $val->decimal;
else if (is_object($val) && get_class($val)=='Decimal\Decimal')
return $val;
return strval(empty(trim($val))?'0':trim($val));
}
function get_decimal() {
return $this->decimal;
}
// operator - The operator. Valid options are ==, <=, <, >=, >, <>, eq, lt, lte, gt, gte, ne
function Mcompare($val = '', $operator='==') {
$val = $this->filter($val);
switch ($operator) {
// equal
case "==":
case "eq": {
if ($this->decimal->compareTo($val)==0) {
return true;
}
break;
}
// less than
case "<":
case "lt": {
if ($this->decimal->compareTo($val)==-1) {
return true;
}
break;
}
// less than or equal
case "<=":
case "lte": {
if ($this->Mcompare($val, '<') || $this->Mcompare($val, '==')) {
return true;
}
break;
}
// greater than
case ">":
case "gt": {
if ($this->decimal->compareTo($val)==1) {
return true;
}
break;
}
// greater than or equal
case ">=":
case "gte": {
if ($this->Mcompare($val, '>') || $this->Mcompare($val, '==')) {
return true;
}
break;
}
case "<>":
case "!=":
case "ne": {
if ($this->decimal->compareTo($val)!=0) {
return true;
}
break;
}
default: {
die("Operador desconccido '".$operator."' en Mcompare()");
}
}
return false;
}
}
$data1=0.00054;
$data2=" 2";
echo (New Decimal((string)$data1))->mul((string)trim($data2))->toString();
echo (New ModDecimal($data1))->add($data2)->toString();
With this I no longer have to worry about whether the data is NULL, float or has spaces.