Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Calculation\Engineering;
4
 
5
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
6
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
7
 
8
class ConvertBinary extends ConvertBase
9
{
10
    /**
11
     * toDecimal.
12
     *
13
     * Return a binary value as decimal.
14
     *
15
     * Excel Function:
16
     *        BIN2DEC(x)
17
     *
18
     * @param array|bool|float|int|string $value The binary number (as a string) that you want to convert. The number
19
     *                                cannot contain more than 10 characters (10 bits). The most significant
20
     *                                bit of number is the sign bit. The remaining 9 bits are magnitude bits.
21
     *                                Negative numbers are represented using two's-complement notation.
22
     *                                If number is not a valid binary number, or if number contains more than
23
     *                                10 characters (10 bits), BIN2DEC returns the #NUM! error value.
24
     *                      Or can be an array of values
25
     *
26
     * @return array|string Result, or an error
27
     *         If an array of numbers is passed as an argument, then the returned result will also be an array
28
     *            with the same dimensions
29
     */
30
    public static function toDecimal($value)
31
    {
32
        if (is_array($value)) {
33
            return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value);
34
        }
35
 
36
        try {
37
            $value = self::validateValue($value);
38
            $value = self::validateBinary($value);
39
        } catch (Exception $e) {
40
            return $e->getMessage();
41
        }
42
 
43
        if (strlen($value) == 10 && $value[0] === '1') {
44
            //    Two's Complement
45
            $value = substr($value, -9);
46
 
47
            return '-' . (512 - bindec($value));
48
        }
49
 
50
        return (string) bindec($value);
51
    }
52
 
53
    /**
54
     * toHex.
55
     *
56
     * Return a binary value as hex.
57
     *
58
     * Excel Function:
59
     *        BIN2HEX(x[,places])
60
     *
61
     * @param array|bool|float|int|string $value The binary number (as a string) that you want to convert. The number
62
     *                                cannot contain more than 10 characters (10 bits). The most significant
63
     *                                bit of number is the sign bit. The remaining 9 bits are magnitude bits.
64
     *                                Negative numbers are represented using two's-complement notation.
65
     *                                If number is not a valid binary number, or if number contains more than
66
     *                                10 characters (10 bits), BIN2HEX returns the #NUM! error value.
67
     *                      Or can be an array of values
68
     * @param null|array|float|int|string $places The number of characters to use. If places is omitted, BIN2HEX uses the
69
     *                                minimum number of characters necessary. Places is useful for padding the
70
     *                                return value with leading 0s (zeros).
71
     *                                If places is not an integer, it is truncated.
72
     *                                If places is nonnumeric, BIN2HEX returns the #VALUE! error value.
73
     *                                If places is negative, BIN2HEX returns the #NUM! error value.
74
     *                      Or can be an array of values
75
     *
76
     * @return array|string Result, or an error
77
     *         If an array of numbers is passed as an argument, then the returned result will also be an array
78
     *            with the same dimensions
79
     */
80
    public static function toHex($value, $places = null): array|string
81
    {
82
        if (is_array($value) || is_array($places)) {
83
            return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places);
84
        }
85
 
86
        try {
87
            $value = self::validateValue($value);
88
            $value = self::validateBinary($value);
89
            $places = self::validatePlaces($places);
90
        } catch (Exception $e) {
91
            return $e->getMessage();
92
        }
93
 
94
        if (strlen($value) == 10 && $value[0] === '1') {
95
            $high2 = substr($value, 0, 2);
96
            $low8 = substr($value, 2);
97
            $xarr = ['00' => '00000000', '01' => '00000001', '10' => 'FFFFFFFE', '11' => 'FFFFFFFF'];
98
 
99
            return $xarr[$high2] . strtoupper(substr('0' . dechex((int) bindec($low8)), -2));
100
        }
101
        $hexVal = (string) strtoupper(dechex((int) bindec($value)));
102
 
103
        return self::nbrConversionFormat($hexVal, $places);
104
    }
105
 
106
    /**
107
     * toOctal.
108
     *
109
     * Return a binary value as octal.
110
     *
111
     * Excel Function:
112
     *        BIN2OCT(x[,places])
113
     *
114
     * @param array|bool|float|int|string $value The binary number (as a string) that you want to convert. The number
115
     *                                cannot contain more than 10 characters (10 bits). The most significant
116
     *                                bit of number is the sign bit. The remaining 9 bits are magnitude bits.
117
     *                                Negative numbers are represented using two's-complement notation.
118
     *                                If number is not a valid binary number, or if number contains more than
119
     *                                10 characters (10 bits), BIN2OCT returns the #NUM! error value.
120
     *                      Or can be an array of values
121
     * @param null|array|float|int|string $places The number of characters to use. If places is omitted, BIN2OCT uses the
122
     *                                minimum number of characters necessary. Places is useful for padding the
123
     *                                return value with leading 0s (zeros).
124
     *                                If places is not an integer, it is truncated.
125
     *                                If places is nonnumeric, BIN2OCT returns the #VALUE! error value.
126
     *                                If places is negative, BIN2OCT returns the #NUM! error value.
127
     *                      Or can be an array of values
128
     *
129
     * @return array|string Result, or an error
130
     *         If an array of numbers is passed as an argument, then the returned result will also be an array
131
     *            with the same dimensions
132
     */
133
    public static function toOctal($value, $places = null): array|string
134
    {
135
        if (is_array($value) || is_array($places)) {
136
            return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $places);
137
        }
138
 
139
        try {
140
            $value = self::validateValue($value);
141
            $value = self::validateBinary($value);
142
            $places = self::validatePlaces($places);
143
        } catch (Exception $e) {
144
            return $e->getMessage();
145
        }
146
 
147
        if (strlen($value) == 10 && $value[0] === '1') { //    Two's Complement
148
            return str_repeat('7', 6) . strtoupper(decoct((int) bindec("11$value")));
149
        }
150
        $octVal = (string) decoct((int) bindec($value));
151
 
152
        return self::nbrConversionFormat($octVal, $places);
153
    }
154
 
155
    protected static function validateBinary(string $value): string
156
    {
157
        if ((strlen($value) > preg_match_all('/[01]/', $value)) || (strlen($value) > 10)) {
158
            throw new Exception(ExcelError::NAN());
159
        }
160
 
161
        return $value;
162
    }
163
}