Subversion Repositories Sites.tela-botanica.org

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
540 jpm 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4: */
3
// +----------------------------------------------------------------------+
4
// | PHP version 4                                                        |
5
// +----------------------------------------------------------------------+
6
// | Copyright (c) 1997-2003 The PHP Group                                |
7
// +----------------------------------------------------------------------+
8
// | This source file is subject to version 3.0 of the PHP license,       |
9
// | that is bundled with this package in the file LICENSE, and is        |
10
// | available through the world-wide-web at                              |
11
// | http://www.php.net/license/3_0.txt.                                  |
12
// | If you did not receive a copy of the PHP license and are unable to   |
13
// | obtain it through the world-wide-web, please send a note to          |
14
// | license@php.net so we can mail you a copy immediately.               |
15
// +----------------------------------------------------------------------+
16
// | Authors: Kouber Saparev <kouber@php.net>                             |
17
// +----------------------------------------------------------------------+
18
//
19
// $Id: lang.fr.php,v 1.4 2004/10/22 18:22:52 kouber Exp $
20
 
21
/**
22
 * Include needed files
23
 */
24
require_once("Numbers/Words.php");
25
 
26
/**
27
 * Class for translating numbers into French.
28
 *
29
 * @author Kouber Saparev <kouber@php.net>
30
 * @package Numbers_Words
31
 */
32
class Numbers_Words_fr extends Numbers_Words
33
{
34
 
35
    // {{{ properties
36
 
37
    /**
38
     * Locale name.
39
     * @var string
40
     * @access public
41
     */
42
    var $locale      = 'fr';
43
 
44
    /**
45
     * Language name in English.
46
     * @var string
47
     * @access public
48
     */
49
    var $lang        = 'French';
50
 
51
    /**
52
     * Native language name.
53
     * @var string
54
     * @access public
55
     */
56
    var $lang_native = 'Français';
57
 
58
    /**
59
     * The words for some numbers.
60
     * @var string
61
     * @access private
62
     */
63
    var $_misc_numbers = array(
64
        10=>'dix',      // 10
65
            'onze',     // 11
66
            'douze',    // 12
67
            'treize',   // 13
68
            'quatorze', // 14
69
            'quinze',   // 15
70
            'seize',    // 16
71
        20=>'vingt',    // 20
72
        30=>'trente',   // 30
73
        40=>'quarante', // 40
74
        50=>'cinquante',// 50
75
        60=>'soixante', // 60
76
       100=>'cent'      // 100
77
    );
78
 
79
 
80
    /**
81
     * The words for digits (except zero).
82
     * @var string
83
     * @access private
84
     */
85
    var $_digits = array(1=>"un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf");
86
 
87
    /**
88
     * The word for zero.
89
     * @var string
90
     * @access private
91
     */
92
    var $_zero = 'zéro';
93
 
94
    /**
95
     * The word for infinity.
96
     * @var string
97
     * @access private
98
     */
99
    var $_infinity = 'infini';
100
 
101
    /**
102
     * The word for the "and" language construct.
103
     * @var string
104
     * @access private
105
     */
106
    var $_and = 'et';
107
 
108
    /**
109
     * The word separator.
110
     * @var string
111
     * @access private
112
     */
113
    var $_sep = ' ';
114
 
115
    /**
116
     * The dash liaison.
117
     * @var string
118
     * @access private
119
     */
120
    var $_dash = '-';
121
 
122
    /**
123
     * The word for the minus sign.
124
     * @var string
125
     * @access private
126
     */
127
    var $_minus = 'moins'; // minus sign
128
 
129
    /**
130
     * The plural suffix (except for hundred).
131
     * @var string
132
     * @access private
133
     */
134
    var $_plural = 's'; // plural suffix
135
 
136
    /**
137
     * The suffixes for exponents (singular).
138
     * @var array
139
     * @access private
140
     */
141
    var $_exponent = array(
142
 
143
        3 => 'mille',
144
        6 => 'million',
145
        9 => 'milliard',
146
       12 => 'trillion',
147
       15 => 'quadrillion',
148
       18 => 'quintillion',
149
       21 => 'sextillion',
150
       24 => 'septillion',
151
       27 => 'octillion',
152
       30 => 'nonillion',
153
       33 => 'decillion',
154
       36 => 'undecillion',
155
       39 => 'duodecillion',
156
       42 => 'tredecillion',
157
       45 => 'quattuordecillion',
158
       48 => 'quindecillion',
159
       51 => 'sexdecillion',
160
       54 => 'septendecillion',
161
       57 => 'octodecillion',
162
       60 => 'novemdecillion',
163
       63 => 'vigintillion',
164
       66 => 'unvigintillion',
165
       69 => 'duovigintillion',
166
       72 => 'trevigintillion',
167
       75 => 'quattuorvigintillion',
168
       78 => 'quinvigintillion',
169
       81 => 'sexvigintillion',
170
       84 => 'septenvigintillion',
171
       87 => 'octovigintillion',
172
       90 => 'novemvigintillion',
173
       93 => 'trigintillion',
174
       96 => 'untrigintillion',
175
       99 => 'duotrigintillion',
176
      102 => 'trestrigintillion',
177
      105 => 'quattuortrigintillion',
178
      108 => 'quintrigintillion',
179
      111 => 'sextrigintillion',
180
      114 => 'septentrigintillion',
181
      117 => 'octotrigintillion',
182
      120 => 'novemtrigintillion',
183
      123 => 'quadragintillion',
184
      126 => 'unquadragintillion',
185
      129 => 'duoquadragintillion',
186
      132 => 'trequadragintillion',
187
      135 => 'quattuorquadragintillion',
188
      138 => 'quinquadragintillion',
189
      141 => 'sexquadragintillion',
190
      144 => 'septenquadragintillion',
191
      147 => 'octoquadragintillion',
192
      150 => 'novemquadragintillion',
193
      153 => 'quinquagintillion',
194
      156 => 'unquinquagintillion',
195
      159 => 'duoquinquagintillion',
196
      162 => 'trequinquagintillion',
197
      165 => 'quattuorquinquagintillion',
198
      168 => 'quinquinquagintillion',
199
      171 => 'sexquinquagintillion',
200
      174 => 'septenquinquagintillion',
201
      177 => 'octoquinquagintillion',
202
      180 => 'novemquinquagintillion',
203
      183 => 'sexagintillion',
204
      186 => 'unsexagintillion',
205
      189 => 'duosexagintillion',
206
      192 => 'tresexagintillion',
207
      195 => 'quattuorsexagintillion',
208
      198 => 'quinsexagintillion',
209
      201 => 'sexsexagintillion',
210
      204 => 'septensexagintillion',
211
      207 => 'octosexagintillion',
212
      210 => 'novemsexagintillion',
213
      213 => 'septuagintillion',
214
      216 => 'unseptuagintillion',
215
      219 => 'duoseptuagintillion',
216
      222 => 'treseptuagintillion',
217
      225 => 'quattuorseptuagintillion',
218
      228 => 'quinseptuagintillion',
219
      231 => 'sexseptuagintillion',
220
      234 => 'septenseptuagintillion',
221
      237 => 'octoseptuagintillion',
222
      240 => 'novemseptuagintillion',
223
      243 => 'octogintillion',
224
      246 => 'unoctogintillion',
225
      249 => 'duooctogintillion',
226
      252 => 'treoctogintillion',
227
      255 => 'quattuoroctogintillion',
228
      258 => 'quinoctogintillion',
229
      261 => 'sexoctogintillion',
230
      264 => 'septoctogintillion',
231
      267 => 'octooctogintillion',
232
      270 => 'novemoctogintillion',
233
      273 => 'nonagintillion',
234
      276 => 'unnonagintillion',
235
      279 => 'duononagintillion',
236
      282 => 'trenonagintillion',
237
      285 => 'quattuornonagintillion',
238
      288 => 'quinnonagintillion',
239
      291 => 'sexnonagintillion',
240
      294 => 'septennonagintillion',
241
      297 => 'octononagintillion',
242
      300 => 'novemnonagintillion',
243
      303 => 'centillion'
244
        );
245
    // }}}
246
 
247
    // {{{ _splitNumber()
248
 
249
    /**
250
     * Split a number to groups of three-digit numbers.
251
     *
252
     * @param  mixed  $num   An integer or its string representation
253
     *                       that need to be split
254
     *
255
     * @return array  Groups of three-digit numbers.
256
     *
257
     * @access private
258
     * @author Kouber Saparev <kouber@php.net>
259
     * @since  PHP 4.2.3
260
     */
261
 
262
    function _splitNumber($num)
263
    {
264
        if (is_string($num)) {
265
            $ret = array();
266
            $strlen = strlen($num);
267
            $first = substr($num, 0, $strlen%3);
268
            preg_match_all('/\d{3}/', substr($num, $strlen%3, $strlen), $m);
269
            $ret =& $m[0];
270
            if ($first) array_unshift($ret, $first);
271
            return $ret;
272
        }
273
        else
274
            return explode(' ', number_format($num, 0, '', ' ')); // a faster version for integers
275
    }
276
    // }}}
277
 
278
    // {{{ _showDigitsGroup()
279
 
280
    /**
281
     * Converts a three-digit number to its word representation
282
     * in French language.
283
     *
284
     * @param  integer  $num     An integer between 1 and 999 inclusive.
285
     *
286
     * @param  boolean  $last    A flag, that determines if it is the last group of digits -
287
     *                           this is used to accord the plural suffix of the "hundreds".
288
     *                           Example: 200 = "deux cents", but 200000 = "deux cent mille".
289
     *
290
     *
291
     * @return string   The words for the given number.
292
     *
293
     * @access private
294
     * @author Kouber Saparev <kouber@php.net>
295
     */
296
    function _showDigitsGroup($num, $last = false)
297
    {
298
        $ret = '';
299
 
300
        // extract the value of each digit from the three-digit number
301
        $e = $num%10;                  // ones
302
        $d = ($num-$e)%100/10;         // tens
303
        $s = ($num-$d*10-$e)%1000/100; // hundreds
304
 
305
        // process the "hundreds" digit.
306
        if ($s) {
307
            if ($s>1) {
308
                $ret .= $this->_digits[$s].$this->_sep.$this->_misc_numbers[100];
309
                if ($last && !$e && !$d) {
310
                    $ret .= $this->_plural;
311
                }
312
            } else {
313
                $ret .= $this->_misc_numbers[100];
314
            }
315
            $ret .= $this->_sep;
316
        }
317
 
318
        // process the "tens" digit, and optionally the "ones" digit.
319
        if ($d) {
320
            // in the case of 1, the "ones" digit also must be processed
321
            if ($d==1) {
322
                if ($e<=6) {
323
                    $ret .= $this->_misc_numbers[10+$e];
324
                } else {
325
                    $ret .= $this->_misc_numbers[10].'-'.$this->_digits[$e];
326
                }
327
                $e = 0;
328
            } elseif ($d>5) {
329
                if ($d<8) {
330
                    $ret .= $this->_misc_numbers[60];
331
                    $resto = $d*10+$e-60;
332
                    if ($e==1) {
333
                        $ret .= $this->_sep.$this->_and.$this->_sep;
334
                    }
335
                    elseif ($resto) {
336
                        $ret .= $this->_dash;
337
                    }
338
 
339
                    if ($resto) {
340
                        $ret .= $this->_showDigitsGroup($resto);
341
                    }
342
                    $e = 0;
343
                } else {
344
                    $ret .= $this->_digits[4].$this->_dash.$this->_misc_numbers[20];
345
                    $resto = $d*10+$e-80;
346
                    if ($resto) {
347
                        $ret .= $this->_dash;
348
                        $ret .= $this->_showDigitsGroup($resto);
349
                        $e = 0;
350
                    } else {
351
                        $ret .= $this->_plural;
352
                    }
353
                }
354
            } else {
355
                $ret .= $this->_misc_numbers[$d*10];
356
            }
357
        }
358
 
359
        // process the "ones" digit
360
        if ($e) {
361
            if ($d) {
362
                if ($e==1) {
363
                    $ret .= $this->_sep.$this->_and.$this->_sep;
364
                } else {
365
                    $ret .= $this->_dash;
366
                }
367
            }
368
            $ret .= $this->_digits[$e];
369
        }
370
 
371
        // strip excessive separators
372
        $ret = rtrim($ret, $this->_sep);
373
 
374
        return $ret;
375
    }
376
    // }}}
377
 
378
    // {{{ toWords()
379
 
380
    /**
381
     * Converts a number to its word representation
382
     * in French language.
383
     *
384
     * @param  integer $num   An integer (or its string representation) between 9.99*-10^302
385
     *                        and 9.99*10^302 (999 centillions) that need to be converted to words
386
     *
387
     * @return string  The corresponding word representation
388
     *
389
     * @access public
390
     * @author Kouber Saparev <kouber@php.net>
391
     */
392
    function toWords($num = 0)
393
    {
394
        $ret = '';
395
 
396
        // check if $num is a valid non-zero number
397
        if (!$num || preg_match('/^-?0+$/', $num) || !preg_match('/^-?\d+$/', $num)) return $this->_zero;
398
 
399
        // add a minus sign
400
        if (substr($num, 0, 1) == '-') {
401
            $ret = $this->_minus . $this->_sep;
402
            $num = substr($num, 1);
403
        }
404
 
405
        // if the absolute value is greater than 9.99*10^302, return infinity
406
        if (strlen($num)>306) {
407
            return $ret . $this->_infinity;
408
        }
409
 
410
        // strip excessive zero signs
411
        $num = ltrim($num, '0');
412
 
413
        // split $num to groups of three-digit numbers
414
        $num_groups = $this->_splitNumber($num);
415
 
416
        $sizeof_numgroups = count($num_groups);
417
 
418
        foreach ($num_groups as $i=>$number) {
419
            // what is the corresponding exponent for the current group
420
            $pow = $sizeof_numgroups-$i;
421
 
422
            // skip processment for empty groups
423
            if ($number!='000') {
424
                if ($number!=1 || $pow!=2) {
425
                    $ret .= $this->_showDigitsGroup($number, $i+1==$sizeof_numgroups).$this->_sep;
426
                }
427
                $ret .= $this->_exponent[($pow-1)*3];
428
                if ($pow>2 && $number>1) {
429
                    $ret .= $this->_plural;
430
                }
431
                $ret .= $this->_sep;
432
            }
433
        }
434
 
435
        return rtrim($ret, $this->_sep);
436
    }
437
    // }}}
438
}
439
?>