num2words 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +40 -0
- data/CHANGELOG.md +18 -0
- data/README.md +26 -0
- data/Rakefile +38 -2
- data/benchmark/converter_benchmark.rb +96 -0
- data/docs/api.md +422 -0
- data/docs/api.ru.md +422 -0
- data/docs/limits.md +140 -0
- data/docs/limits.ru.md +140 -0
- data/docs/locale_development.md +241 -0
- data/docs/locale_development.ru.md +241 -0
- data/lib/num2words/version.rb +1 -1
- data/num2words.gemspec +1 -0
- metadata +24 -2
data/docs/api.ru.md
ADDED
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
# Справочник API
|
|
2
|
+
|
|
3
|
+
Этот документ описывает публичный API `num2words`.
|
|
4
|
+
|
|
5
|
+
## Подключение
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
require "num2words"
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Это подключает модульный API и core extensions для поддерживаемых Ruby-классов.
|
|
12
|
+
|
|
13
|
+
## Модульный API
|
|
14
|
+
|
|
15
|
+
### `Num2words.to_words`
|
|
16
|
+
|
|
17
|
+
```ruby
|
|
18
|
+
Num2words.to_words(value, locale = I18n.default_locale, only = nil, short = false, **options)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Преобразует числа, даты, время и дату-время в слова.
|
|
22
|
+
|
|
23
|
+
Примеры:
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
Num2words.to_words(123, :ru)
|
|
27
|
+
# => "сто двадцать три"
|
|
28
|
+
|
|
29
|
+
Num2words.to_words("3,5", :ru)
|
|
30
|
+
# => "три целых пять десятых"
|
|
31
|
+
|
|
32
|
+
Num2words.to_words("2024-08-21", :en)
|
|
33
|
+
# => "the twenty-first of August, two thousand twenty four"
|
|
34
|
+
|
|
35
|
+
Num2words.to_words("14:35:42", :fr)
|
|
36
|
+
# => "quatorze heures trente cinq minutes quarante deux secondes"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Также поддерживается передача локали через keyword-аргумент:
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
Num2words.to_words(123, locale: :en)
|
|
43
|
+
# => "one hundred twenty three"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### `Num2words.to_currency`
|
|
47
|
+
|
|
48
|
+
```ruby
|
|
49
|
+
Num2words.to_currency(amount, locale = I18n.default_locale, **options)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Преобразует денежную сумму в слова с учетом выбранной локали и валюты.
|
|
53
|
+
|
|
54
|
+
Примеры:
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
Num2words.to_currency("21,05", :ru)
|
|
58
|
+
# => "двадцать один рубль пять копеек"
|
|
59
|
+
|
|
60
|
+
Num2words.to_currency(12.50, :en, code: :EUR)
|
|
61
|
+
# => "twelve euros fifty cents"
|
|
62
|
+
|
|
63
|
+
Num2words.to_currency(BigDecimal("21.05"), :ru)
|
|
64
|
+
# => "двадцать один рубль пять копеек"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Core Extensions
|
|
68
|
+
|
|
69
|
+
`num2words` добавляет удобные методы в стандартные классы Ruby.
|
|
70
|
+
|
|
71
|
+
### `Integer#to_words`
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
123.to_words(:ru)
|
|
75
|
+
# => "сто двадцать три"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### `Integer#to_currency`
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
123.to_currency(:en, code: :USD)
|
|
82
|
+
# => "one hundred twenty three dollars zero cents"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### `Float#to_words`
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
45.67.to_words(:ru)
|
|
89
|
+
# => "сорок пять целых шестьдесят семь сотых"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### `Float#to_currency`
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
12.5.to_currency(:ru, code: :USD)
|
|
96
|
+
# => "двенадцать долларов пятьдесят центов"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### `String#to_words`
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
"007".to_words(:en)
|
|
103
|
+
# => "seven"
|
|
104
|
+
|
|
105
|
+
"3,5".to_words(:ru)
|
|
106
|
+
# => "три целых пять десятых"
|
|
107
|
+
|
|
108
|
+
"2024-08-21 14:35:42".to_words(:ru)
|
|
109
|
+
# => "двадцать первое августа две тысячи двадцать четвёртого года, четырнадцать часов тридцать пять минут сорок две секунды"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`String#to_currency` сейчас не определен. Для строковых сумм используй `Num2words.to_currency("12.50", :en)`.
|
|
113
|
+
|
|
114
|
+
### `Date#to_words`
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
Date.new(2024, 8, 21).to_words(:ru)
|
|
118
|
+
# => "двадцать первое августа две тысячи двадцать четвёртого года"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### `Time#to_words`
|
|
122
|
+
|
|
123
|
+
```ruby
|
|
124
|
+
Time.new(2024, 8, 21, 14, 35, 42).to_words(:en)
|
|
125
|
+
# => "fourteen hours thirty five minutes forty two seconds"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### `DateTime#to_words`
|
|
129
|
+
|
|
130
|
+
```ruby
|
|
131
|
+
DateTime.parse("2024-08-21 14:35:42").to_words(:en)
|
|
132
|
+
# => "the twenty-first of August, two thousand twenty four at fourteen hours thirty five minutes forty two seconds"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Поддерживаемые типы входных данных
|
|
136
|
+
|
|
137
|
+
`to_words` поддерживает:
|
|
138
|
+
|
|
139
|
+
- `Integer`
|
|
140
|
+
- `Float`
|
|
141
|
+
- `Date`
|
|
142
|
+
- `Time`
|
|
143
|
+
- `DateTime`
|
|
144
|
+
- строки с целыми числами, например `"007"` или `"-42"`
|
|
145
|
+
- строки с дробными числами через точку или запятую, например `"3.5"` или `"3,5"`
|
|
146
|
+
- строки с датами, например `"2024-08-21"` или `"21.08.2024"`
|
|
147
|
+
- строки со временем, например `"14:35"` или `"14:35:42"`
|
|
148
|
+
- строки с датой и временем, например `"2024-08-21 14:35:42"`
|
|
149
|
+
|
|
150
|
+
`to_currency` поддерживает:
|
|
151
|
+
|
|
152
|
+
- `Integer`
|
|
153
|
+
- `Float`
|
|
154
|
+
- `String`
|
|
155
|
+
- `BigDecimal`
|
|
156
|
+
|
|
157
|
+
Строковые денежные суммы могут использовать точку или запятую как десятичный разделитель.
|
|
158
|
+
|
|
159
|
+
## Опции
|
|
160
|
+
|
|
161
|
+
### `locale`
|
|
162
|
+
|
|
163
|
+
Выбирает локаль.
|
|
164
|
+
|
|
165
|
+
```ruby
|
|
166
|
+
Num2words.to_words(123, :ru)
|
|
167
|
+
Num2words.to_words(123, locale: :ru)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Если локаль не передана, используется `I18n.default_locale`.
|
|
171
|
+
|
|
172
|
+
### `style`
|
|
173
|
+
|
|
174
|
+
Управляет выводом дробной части в `to_words`.
|
|
175
|
+
|
|
176
|
+
Поддерживаемые значения:
|
|
177
|
+
|
|
178
|
+
- `:fraction` - стиль дробей по умолчанию.
|
|
179
|
+
- `:decimal` - чтение дробной части по цифрам, если локаль поддерживает такой стиль.
|
|
180
|
+
|
|
181
|
+
```ruby
|
|
182
|
+
Num2words.to_words(12.12, :en)
|
|
183
|
+
# => "twelve and twelve hundredths"
|
|
184
|
+
|
|
185
|
+
Num2words.to_words(12.12, :en, style: :decimal)
|
|
186
|
+
# => "twelve point one two"
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### `joiner`
|
|
190
|
+
|
|
191
|
+
Управляет соединителем для дробей в стиле `:fraction`.
|
|
192
|
+
|
|
193
|
+
Поддерживаемые значения:
|
|
194
|
+
|
|
195
|
+
- `:default`
|
|
196
|
+
- `:and`
|
|
197
|
+
|
|
198
|
+
```ruby
|
|
199
|
+
Num2words.to_words(0.5, :ru)
|
|
200
|
+
# => "ноль целых пять десятых"
|
|
201
|
+
|
|
202
|
+
Num2words.to_words(0.5, :ru, joiner: :and)
|
|
203
|
+
# => "ноль и пять десятых"
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Некорректные значения вызывают `ArgumentError`.
|
|
207
|
+
|
|
208
|
+
### `date_case`
|
|
209
|
+
|
|
210
|
+
Управляет падежом дня в датах для локалей, которые это поддерживают.
|
|
211
|
+
|
|
212
|
+
Поддерживаемые значения:
|
|
213
|
+
|
|
214
|
+
- `:default`
|
|
215
|
+
- `:genitive`
|
|
216
|
+
|
|
217
|
+
```ruby
|
|
218
|
+
Num2words.to_words("2024-08-21", :ru)
|
|
219
|
+
# => "двадцать первое августа две тысячи двадцать четвёртого года"
|
|
220
|
+
|
|
221
|
+
Num2words.to_words("2024-08-21", :ru, date_case: :genitive)
|
|
222
|
+
# => "двадцать первого августа две тысячи двадцать четвёртого года"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Некорректные значения вызывают `ArgumentError`.
|
|
226
|
+
|
|
227
|
+
### `short`
|
|
228
|
+
|
|
229
|
+
Включает короткий вывод для времени или даты-времени.
|
|
230
|
+
|
|
231
|
+
```ruby
|
|
232
|
+
Num2words.to_words("14:35:42", :ru, short: true)
|
|
233
|
+
# => "четырнадцать часов тридцать пять минут"
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Для даты-времени `short: true` возвращает сокращенную строку даты-времени, если не используется `only`.
|
|
237
|
+
|
|
238
|
+
### `only`
|
|
239
|
+
|
|
240
|
+
Выбирает часть значения дата-время.
|
|
241
|
+
|
|
242
|
+
```ruby
|
|
243
|
+
Num2words.to_words("2024-08-21 14:35:42", :ru, only: :date)
|
|
244
|
+
# => "двадцать первое августа две тысячи двадцать четвёртого года"
|
|
245
|
+
|
|
246
|
+
Num2words.to_words("2024-08-21 14:35:42", :ru, only: :time)
|
|
247
|
+
# => "четырнадцать часов тридцать пять минут сорок две секунды"
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Также поддерживается старый позиционный вариант:
|
|
251
|
+
|
|
252
|
+
```ruby
|
|
253
|
+
"2024-08-21 14:35:42".to_words(:ru, :date)
|
|
254
|
+
"2024-08-21 14:35:42".to_words(:ru, :time)
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### `format`
|
|
258
|
+
|
|
259
|
+
Используется при преобразовании дат и времени.
|
|
260
|
+
|
|
261
|
+
Для дат:
|
|
262
|
+
|
|
263
|
+
- `:default`
|
|
264
|
+
- `:nominative`, если формат есть в данных локали.
|
|
265
|
+
- `:short` возвращает числовой формат даты `DD.MM.YYYY`.
|
|
266
|
+
|
|
267
|
+
Для времени:
|
|
268
|
+
|
|
269
|
+
- `:default`
|
|
270
|
+
- `:hours_only`
|
|
271
|
+
- `:hours_minutes`
|
|
272
|
+
- `:hours_minutes_seconds`
|
|
273
|
+
|
|
274
|
+
```ruby
|
|
275
|
+
Num2words.to_words("14:35:42", :ru, format: :hours_minutes)
|
|
276
|
+
# => "четырнадцать часов тридцать пять минут"
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Неподдерживаемые форматы времени вызывают `ArgumentError`.
|
|
280
|
+
|
|
281
|
+
### `word_case`
|
|
282
|
+
|
|
283
|
+
Меняет регистр результата.
|
|
284
|
+
|
|
285
|
+
Поддерживаемые значения:
|
|
286
|
+
|
|
287
|
+
- `:default`
|
|
288
|
+
- `:upper`
|
|
289
|
+
- `:downcase`
|
|
290
|
+
- `:capitalize`
|
|
291
|
+
- `:title`
|
|
292
|
+
|
|
293
|
+
```ruby
|
|
294
|
+
Num2words.to_words(21, :en, word_case: :upper)
|
|
295
|
+
# => "TWENTY ONE"
|
|
296
|
+
|
|
297
|
+
Num2words.to_words(21, :en, word_case: :title)
|
|
298
|
+
# => "Twenty One"
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### `feminine`
|
|
302
|
+
|
|
303
|
+
Для локалей с грамматическим родом включает женские формы там, где они поддерживаются.
|
|
304
|
+
|
|
305
|
+
```ruby
|
|
306
|
+
Num2words.to_words(1, :ru, feminine: true)
|
|
307
|
+
# => "одна"
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### `code`
|
|
311
|
+
|
|
312
|
+
Выбирает код валюты в `to_currency`.
|
|
313
|
+
|
|
314
|
+
```ruby
|
|
315
|
+
Num2words.to_currency(12.50, :ru, code: :USD)
|
|
316
|
+
# => "двенадцать долларов пятьдесят центов"
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Если валюта недоступна для локали, `num2words` использует валюту локали по умолчанию и может вывести warning в зависимости от настроек.
|
|
320
|
+
|
|
321
|
+
### `minor`
|
|
322
|
+
|
|
323
|
+
Управляет выводом младшей денежной единицы.
|
|
324
|
+
|
|
325
|
+
Поддерживаемые значения:
|
|
326
|
+
|
|
327
|
+
- `:always` - всегда выводить младшую единицу.
|
|
328
|
+
- `:nonzero` - выводить младшую единицу только когда она больше нуля.
|
|
329
|
+
- `:never` - не выводить младшую единицу.
|
|
330
|
+
|
|
331
|
+
```ruby
|
|
332
|
+
Num2words.to_currency(12, :ru)
|
|
333
|
+
# => "двенадцать рублей ноль копеек"
|
|
334
|
+
|
|
335
|
+
Num2words.to_currency(12, :ru, minor: :nonzero)
|
|
336
|
+
# => "двенадцать рублей"
|
|
337
|
+
|
|
338
|
+
Num2words.to_currency(12.50, :ru, minor: :never)
|
|
339
|
+
# => "двенадцать рублей"
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Некорректные значения вызывают `ArgumentError`.
|
|
343
|
+
|
|
344
|
+
## Конфигурация
|
|
345
|
+
|
|
346
|
+
### `Num2words.default_currency`
|
|
347
|
+
|
|
348
|
+
Получает или задает валюту по умолчанию.
|
|
349
|
+
|
|
350
|
+
```ruby
|
|
351
|
+
Num2words.default_currency(:ru)
|
|
352
|
+
# => :RUB
|
|
353
|
+
|
|
354
|
+
Num2words.default_currency(:ru, :USD)
|
|
355
|
+
# => :USD
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### `Num2words.available_currencies`
|
|
359
|
+
|
|
360
|
+
Возвращает коды валют, доступные для локали.
|
|
361
|
+
|
|
362
|
+
```ruby
|
|
363
|
+
Num2words.available_currencies(:ru)
|
|
364
|
+
# => [:RUB, :USD, :EUR, ...]
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### `Num2words.currency_warnings`
|
|
368
|
+
|
|
369
|
+
Управляет warning при запросе валюты, недоступной для локали.
|
|
370
|
+
|
|
371
|
+
```ruby
|
|
372
|
+
Num2words.currency_warnings = false
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Локали и валюты
|
|
376
|
+
|
|
377
|
+
Поддерживаемые локали:
|
|
378
|
+
|
|
379
|
+
```text
|
|
380
|
+
ar be bg bn cs da de el en es et fa fi fr gu he hi hr hu id it ja kn ko
|
|
381
|
+
kz lt lv ml mr ms nb nl pa pl pt ro ru sk sl sr sv sw ta te th tr uk ur
|
|
382
|
+
vi zh
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
Каждая завершенная локаль поддерживает один и тот же набор из 32 валют:
|
|
386
|
+
|
|
387
|
+
```text
|
|
388
|
+
BDT BGN BRL BYN CNY CZK DKK EUR GBP HUF IDR ILS INR IRR JPY KES KRW
|
|
389
|
+
KZT MYR NOK PKR PLN RON RSD RUB SAR SEK THB TRY UAH USD VND
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Ошибки
|
|
393
|
+
|
|
394
|
+
Неподдерживаемый тип входных данных:
|
|
395
|
+
|
|
396
|
+
```ruby
|
|
397
|
+
Num2words.to_words(Object.new, :en)
|
|
398
|
+
# raises ArgumentError: Unsupported input type: ...
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Неподдерживаемые опции:
|
|
402
|
+
|
|
403
|
+
```ruby
|
|
404
|
+
Num2words.to_words(0.5, :ru, joiner: :plus)
|
|
405
|
+
# raises ArgumentError: Unsupported joiner option: :plus
|
|
406
|
+
|
|
407
|
+
Num2words.to_currency(12, :ru, minor: :sometimes)
|
|
408
|
+
# raises ArgumentError: Unsupported minor option: :sometimes
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
Некорректная денежная сумма:
|
|
412
|
+
|
|
413
|
+
```ruby
|
|
414
|
+
Num2words.to_currency("abc", :en)
|
|
415
|
+
# raises ArgumentError: Unsupported currency amount: "abc"
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
## Документация для разработки
|
|
419
|
+
|
|
420
|
+
- [Числовые ограничения](limits.ru.md)
|
|
421
|
+
- [Locale development guide](locale_development.md)
|
|
422
|
+
- [Русская инструкция по разработке локалей](locale_development.ru.md)
|
data/docs/limits.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Numeric Limits
|
|
2
|
+
|
|
3
|
+
This document describes the currently documented numeric scale limits for `Num2words.to_words`.
|
|
4
|
+
|
|
5
|
+
These limits are documentation-only. Runtime validation is not enforced yet, so values above the documented range may produce incomplete, unnatural or locale-dependent output. A future release may add strict validation for numbers that exceed locale limits.
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
| Locale group | Locales | Guaranteed integer range |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| Western 3-digit scales | Most locales | `-(10^15 - 1)` to `10^15 - 1` |
|
|
12
|
+
| Indian scales | `bn gu hi kn ml mr pa ta te ur` | `-(10^12 - 1)` to `10^12 - 1` |
|
|
13
|
+
| East Asian 4-digit scales | `ja ko zh` | `-(10^20 - 1)` to `10^20 - 1` |
|
|
14
|
+
|
|
15
|
+
The guaranteed range means that the locale has named scale data for every group required inside that interval.
|
|
16
|
+
|
|
17
|
+
## Western 3-Digit Scale Locales
|
|
18
|
+
|
|
19
|
+
Most locales use 3-digit grouping:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
thousand, million, billion, trillion
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The highest named group is the `10^12` group, so the documented maximum is:
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
999_999_999_999_999
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
That is `999 trillion` plus lower groups.
|
|
32
|
+
|
|
33
|
+
Examples:
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
Num2words.to_words(999_999_999_999_999, :en)
|
|
37
|
+
Num2words.to_words(999_999_999_999_999, :ru)
|
|
38
|
+
Num2words.to_words(-999_999_999_999_999, :fr)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Values at `10^15` and above require a named `10^15` group, which is not currently part of the common scale catalog.
|
|
42
|
+
|
|
43
|
+
## Indian Scale Locales
|
|
44
|
+
|
|
45
|
+
These locales use Indian-style grouping in their Ruby locale modules:
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
bn gu hi kn ml mr pa ta te ur
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The implemented named groups are:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
thousand, lakh, crore, arab
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The highest primary named group is `arab`, equal to `10^9`, so the documented maximum is:
|
|
58
|
+
|
|
59
|
+
```ruby
|
|
60
|
+
999_999_999_999
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
That is `999 arab` plus lower groups.
|
|
64
|
+
|
|
65
|
+
Examples:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
Num2words.to_words(999_999_999_999, :hi)
|
|
69
|
+
Num2words.to_words(999_999_999_999, :ur)
|
|
70
|
+
Num2words.to_words(-999_999_999_999, :bn)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Values at `10^12` and above may still produce output through recursive composition, but that output is not currently guaranteed as idiomatic or stable.
|
|
74
|
+
|
|
75
|
+
## East Asian 4-Digit Scale Locales
|
|
76
|
+
|
|
77
|
+
These locales use 4-digit grouping:
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
ja ko zh
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The Ruby locale modules define five 4-digit groups:
|
|
84
|
+
|
|
85
|
+
| Locale | Groups |
|
|
86
|
+
| --- | --- |
|
|
87
|
+
| `ja` | `万`, `億`, `兆`, `京` |
|
|
88
|
+
| `ko` | `만`, `억`, `조`, `경` |
|
|
89
|
+
| `zh` | `万`, `亿`, `兆`, `京` |
|
|
90
|
+
|
|
91
|
+
The highest named group is the `10^16` group, so the documented maximum is:
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
99_999_999_999_999_999_999
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
That is `10^20 - 1`.
|
|
98
|
+
|
|
99
|
+
Examples:
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
Num2words.to_words(99_999_999_999_999_999_999, :ja)
|
|
103
|
+
Num2words.to_words(99_999_999_999_999_999_999, :ko)
|
|
104
|
+
Num2words.to_words(99_999_999_999_999_999_999, :zh)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Values at `10^20` and above require another 4-digit scale name and are not currently guaranteed.
|
|
108
|
+
|
|
109
|
+
## Fractions and Currency
|
|
110
|
+
|
|
111
|
+
The integer part of a decimal or currency amount follows the same locale limit.
|
|
112
|
+
|
|
113
|
+
Examples:
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
Num2words.to_words("999999999999999.99", :en)
|
|
117
|
+
Num2words.to_currency("999999999999.99", :hi, code: :INR)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Fraction denominators are currently defined up to `1_000_000_000`. Very long decimal strings may fall back to a locale default fraction word once the denominator is outside the defined fraction catalog.
|
|
121
|
+
|
|
122
|
+
## Current Behavior Above Limits
|
|
123
|
+
|
|
124
|
+
Above the documented range, behavior is currently unspecified:
|
|
125
|
+
|
|
126
|
+
- some locales may raise an exception;
|
|
127
|
+
- some locales may omit a scale name;
|
|
128
|
+
- some locales may compose a technically readable but unnatural phrase;
|
|
129
|
+
- output may change in a future release.
|
|
130
|
+
|
|
131
|
+
Applications that process user-supplied large numbers should validate input before calling `num2words`.
|
|
132
|
+
|
|
133
|
+
## Future Direction
|
|
134
|
+
|
|
135
|
+
A future release may add:
|
|
136
|
+
|
|
137
|
+
- `Num2words.locale_limits(locale)`;
|
|
138
|
+
- strict validation for values above the locale limit;
|
|
139
|
+
- `strict: true` and `strict: false` behavior;
|
|
140
|
+
- specs that pin the maximum supported value for every locale.
|
data/docs/limits.ru.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Числовые ограничения
|
|
2
|
+
|
|
3
|
+
Этот документ описывает текущие документированные пределы числовых разрядов для `Num2words.to_words`.
|
|
4
|
+
|
|
5
|
+
Эти ограничения пока только документируют гарантированный диапазон. Runtime validation еще не добавлен, поэтому значения выше указанного диапазона могут давать неполный, неестественный или зависящий от локали результат. В будущей версии может появиться строгая проверка чисел, превышающих лимит локали.
|
|
6
|
+
|
|
7
|
+
## Кратко
|
|
8
|
+
|
|
9
|
+
| Группа локалей | Локали | Гарантированный диапазон целых чисел |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| Западные 3-значные разряды | Большинство локалей | `-(10^15 - 1)` .. `10^15 - 1` |
|
|
12
|
+
| Индийские разряды | `bn gu hi kn ml mr pa ta te ur` | `-(10^12 - 1)` .. `10^12 - 1` |
|
|
13
|
+
| Восточноазиатские 4-значные разряды | `ja ko zh` | `-(10^20 - 1)` .. `10^20 - 1` |
|
|
14
|
+
|
|
15
|
+
Гарантированный диапазон означает, что у локали есть именованные разряды для всех групп внутри этого интервала.
|
|
16
|
+
|
|
17
|
+
## Локали с западными 3-значными разрядами
|
|
18
|
+
|
|
19
|
+
Большинство локалей используют группировку по 3 цифры:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
тысяча, миллион, миллиард, триллион
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Старшая именованная группа находится на уровне `10^12`, поэтому документированный максимум:
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
999_999_999_999_999
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
То есть `999 триллионов` плюс младшие группы.
|
|
32
|
+
|
|
33
|
+
Примеры:
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
Num2words.to_words(999_999_999_999_999, :en)
|
|
37
|
+
Num2words.to_words(999_999_999_999_999, :ru)
|
|
38
|
+
Num2words.to_words(-999_999_999_999_999, :fr)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Значения `10^15` и выше требуют именованной группы `10^15`, которой сейчас нет в общем каталоге разрядов.
|
|
42
|
+
|
|
43
|
+
## Локали с индийскими разрядами
|
|
44
|
+
|
|
45
|
+
Эти локали используют индийскую систему разрядов в Ruby-модулях локалей:
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
bn gu hi kn ml mr pa ta te ur
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Реализованные именованные группы:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
тысяча, lakh, crore, arab
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Старшая основная группа - `arab`, то есть `10^9`, поэтому документированный максимум:
|
|
58
|
+
|
|
59
|
+
```ruby
|
|
60
|
+
999_999_999_999
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
То есть `999 arab` плюс младшие группы.
|
|
64
|
+
|
|
65
|
+
Примеры:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
Num2words.to_words(999_999_999_999, :hi)
|
|
69
|
+
Num2words.to_words(999_999_999_999, :ur)
|
|
70
|
+
Num2words.to_words(-999_999_999_999, :bn)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Значения `10^12` и выше могут все еще выводиться через рекурсивную композицию, но такой результат сейчас не гарантируется как идиоматичный или стабильный.
|
|
74
|
+
|
|
75
|
+
## Восточноазиатские 4-значные разряды
|
|
76
|
+
|
|
77
|
+
Эти локали используют группировку по 4 цифры:
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
ja ko zh
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Ruby-модули локалей определяют пять 4-значных групп:
|
|
84
|
+
|
|
85
|
+
| Локаль | Разряды |
|
|
86
|
+
| --- | --- |
|
|
87
|
+
| `ja` | `万`, `億`, `兆`, `京` |
|
|
88
|
+
| `ko` | `만`, `억`, `조`, `경` |
|
|
89
|
+
| `zh` | `万`, `亿`, `兆`, `京` |
|
|
90
|
+
|
|
91
|
+
Старшая именованная группа находится на уровне `10^16`, поэтому документированный максимум:
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
99_999_999_999_999_999_999
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
То есть `10^20 - 1`.
|
|
98
|
+
|
|
99
|
+
Примеры:
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
Num2words.to_words(99_999_999_999_999_999_999, :ja)
|
|
103
|
+
Num2words.to_words(99_999_999_999_999_999_999, :ko)
|
|
104
|
+
Num2words.to_words(99_999_999_999_999_999_999, :zh)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Значения `10^20` и выше требуют следующего имени 4-значного разряда и сейчас не гарантируются.
|
|
108
|
+
|
|
109
|
+
## Дроби и валюты
|
|
110
|
+
|
|
111
|
+
Целая часть дробного числа или денежной суммы подчиняется тому же лимиту локали.
|
|
112
|
+
|
|
113
|
+
Примеры:
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
Num2words.to_words("999999999999999.99", :en)
|
|
117
|
+
Num2words.to_currency("999999999999.99", :hi, code: :INR)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Дробные знаменатели сейчас определены до `1_000_000_000`. Очень длинные десятичные строки могут перейти на дефолтное слово дроби локали, если знаменатель выходит за пределы каталога дробей.
|
|
121
|
+
|
|
122
|
+
## Текущее поведение выше лимитов
|
|
123
|
+
|
|
124
|
+
Выше документированного диапазона поведение сейчас не специфицировано:
|
|
125
|
+
|
|
126
|
+
- часть локалей может выбросить исключение;
|
|
127
|
+
- часть локалей может пропустить имя разряда;
|
|
128
|
+
- часть локалей может составить технически читаемую, но неестественную фразу;
|
|
129
|
+
- результат может измениться в будущей версии.
|
|
130
|
+
|
|
131
|
+
Приложения, которые обрабатывают очень большие числа от пользователя, должны валидировать ввод до вызова `num2words`.
|
|
132
|
+
|
|
133
|
+
## Возможное развитие
|
|
134
|
+
|
|
135
|
+
В будущей версии можно добавить:
|
|
136
|
+
|
|
137
|
+
- `Num2words.locale_limits(locale)`;
|
|
138
|
+
- строгую проверку значений выше лимита локали;
|
|
139
|
+
- поведение `strict: true` и `strict: false`;
|
|
140
|
+
- specs, которые фиксируют максимум для каждой локали.
|