1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; |
4
|
|
|
|
5
|
|
|
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; |
6
|
|
|
use PhpOffice\PhpSpreadsheet\Calculation\Exception; |
7
|
|
|
|
8
|
|
|
class Trunc |
9
|
|
|
{ |
10
|
|
|
use ArrayEnabled; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* TRUNC. |
14
|
|
|
* |
15
|
|
|
* Truncates value to the number of fractional digits by number_digits. |
16
|
|
|
* This will probably not be the precise result in the unlikely |
17
|
|
|
* event that the number of digits to the left of the decimal |
18
|
|
|
* plus the number of digits to the right exceeds PHP_FLOAT_DIG |
19
|
|
|
* (or possibly that value minus 1). |
20
|
|
|
* Excel is unlikely to do any better. |
21
|
|
|
* |
22
|
|
|
* @param array|float $value Or can be an array of values |
23
|
|
|
* @param array|int $digits Or can be an array of values |
24
|
30 |
|
* |
25
|
|
|
* @return array|float|string Truncated value, or a string containing an error |
26
|
30 |
|
* If an array of numbers is passed as an argument, then the returned result will also be an array |
27
|
5 |
|
* with the same dimensions |
28
|
|
|
*/ |
29
|
|
|
public static function evaluate(array|float|string|null $value = 0, array|int|string $digits = 0): array|float|string |
30
|
|
|
{ |
31
|
30 |
|
if (is_array($value) || is_array($digits)) { |
32
|
28 |
|
return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $digits); |
33
|
3 |
|
} |
34
|
3 |
|
|
35
|
|
|
try { |
36
|
|
|
$value = Helpers::validateNumericNullBool($value); |
37
|
27 |
|
$digits = Helpers::validateNumericNullSubstitution($digits, null); |
38
|
|
|
} catch (Exception $e) { |
39
|
|
|
return $e->getMessage(); |
40
|
27 |
|
} |
41
|
|
|
|
42
|
27 |
|
if ($value == 0) { |
43
|
2 |
|
return $value; |
44
|
|
|
} |
45
|
|
|
|
46
|
25 |
|
if ($value >= 0) { |
47
|
|
|
$minusSign = ''; |
48
|
|
|
} else { |
49
|
|
|
$minusSign = '-'; |
50
|
|
|
$value = -$value; |
51
|
|
|
} |
52
|
|
|
$digits = (int) floor($digits); |
53
|
|
|
if ($digits < 0) { |
54
|
|
|
$power = (int) (10 ** -$digits); |
55
|
|
|
$result = intdiv((int) floor($value), $power) * $power; |
56
|
|
|
|
57
|
|
|
return ($minusSign === '') ? $result : -$result; |
58
|
|
|
} |
59
|
|
|
$decimals = PHP_FLOAT_DIG - strlen((string) (int) $value); |
60
|
|
|
$resultString = ($decimals < 0) ? sprintf('%F', $value) : sprintf('%.' . $decimals . 'F', $value); |
61
|
|
|
$regExp = '/([.]\\d{' . $digits . '})\\d+$/'; |
62
|
|
|
$result = $minusSign . (preg_replace($regExp, '$1', $resultString) ?? $resultString); |
63
|
|
|
|
64
|
|
|
return (float) $result; |
65
|
|
|
} |
66
|
|
|
} |
67
|
|
|
|