num2words 0.3.0 → 0.4.0
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 +39 -0
- data/Gemfile +1 -0
- data/README.md +83 -0
- data/Rakefile +38 -2
- data/benchmark/converter_benchmark.rb +96 -0
- data/docs/api.md +478 -0
- data/docs/api.ru.md +478 -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/docs/rails.md +130 -0
- data/docs/rails.ru.md +130 -0
- data/lib/num2words/config.rb +44 -0
- data/lib/num2words/converter.rb +2 -1
- data/lib/num2words/rails/helpers.rb +27 -0
- data/lib/num2words/rails/validators/currency_validator.rb +30 -0
- data/lib/num2words/rails/validators/locale_validator.rb +22 -0
- data/lib/num2words/railtie.rb +27 -0
- data/lib/num2words/version.rb +1 -1
- data/lib/num2words.rb +2 -0
- data/num2words.gemspec +1 -0
- metadata +30 -2
data/docs/api.ru.md
ADDED
|
@@ -0,0 +1,478 @@
|
|
|
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_available?`
|
|
368
|
+
|
|
369
|
+
Проверяет, доступна ли валюта для локали.
|
|
370
|
+
|
|
371
|
+
```ruby
|
|
372
|
+
Num2words.currency_available?(:ru, :RUB)
|
|
373
|
+
# => true
|
|
374
|
+
|
|
375
|
+
Num2words.currency_available?(:ru, "usd")
|
|
376
|
+
# => true
|
|
377
|
+
|
|
378
|
+
Num2words.currency_available?(:ru, :XYZ)
|
|
379
|
+
# => false
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### `Num2words.currency_info`
|
|
383
|
+
|
|
384
|
+
Возвращает данные валюты для локали или `nil`, если валюта недоступна.
|
|
385
|
+
|
|
386
|
+
```ruby
|
|
387
|
+
Num2words.currency_info(:ru, :RUB)
|
|
388
|
+
# => {
|
|
389
|
+
# code: :RUB,
|
|
390
|
+
# major_unit: ["рубль", "рубля", "рублей"],
|
|
391
|
+
# minor_unit: ["копейка", "копейки", "копеек"],
|
|
392
|
+
# symbol: "₽"
|
|
393
|
+
# }
|
|
394
|
+
|
|
395
|
+
Num2words.currency_info(:ru, :XYZ)
|
|
396
|
+
# => nil
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### `Num2words.default_currency_info`
|
|
400
|
+
|
|
401
|
+
Возвращает данные валюты по умолчанию для локали.
|
|
402
|
+
|
|
403
|
+
```ruby
|
|
404
|
+
Num2words.default_currency_info(:ru)
|
|
405
|
+
# => {
|
|
406
|
+
# code: :RUB,
|
|
407
|
+
# major_unit: ["рубль", "рубля", "рублей"],
|
|
408
|
+
# minor_unit: ["копейка", "копейки", "копеек"],
|
|
409
|
+
# symbol: "₽"
|
|
410
|
+
# }
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### `Num2words.available_locales`
|
|
414
|
+
|
|
415
|
+
Возвращает список поддерживаемых локалей.
|
|
416
|
+
|
|
417
|
+
```ruby
|
|
418
|
+
Num2words.available_locales
|
|
419
|
+
# => [:ar, :be, :bg, :bn, :cs, ...]
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### `Num2words.currency_warnings`
|
|
423
|
+
|
|
424
|
+
Управляет warning при запросе валюты, недоступной для локали.
|
|
425
|
+
|
|
426
|
+
```ruby
|
|
427
|
+
Num2words.currency_warnings = false
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
## Локали и валюты
|
|
431
|
+
|
|
432
|
+
Поддерживаемые локали:
|
|
433
|
+
|
|
434
|
+
```text
|
|
435
|
+
ar be bg bn cs da de el en es et fa fi fr gu he hi hr hu id it ja kn ko
|
|
436
|
+
kz lt lv ml mr ms nb nl pa pl pt ro ru sk sl sr sv sw ta te th tr uk ur
|
|
437
|
+
vi zh
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
Каждая завершенная локаль поддерживает один и тот же набор из 32 валют:
|
|
441
|
+
|
|
442
|
+
```text
|
|
443
|
+
BDT BGN BRL BYN CNY CZK DKK EUR GBP HUF IDR ILS INR IRR JPY KES KRW
|
|
444
|
+
KZT MYR NOK PKR PLN RON RSD RUB SAR SEK THB TRY UAH USD VND
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
## Ошибки
|
|
448
|
+
|
|
449
|
+
Неподдерживаемый тип входных данных:
|
|
450
|
+
|
|
451
|
+
```ruby
|
|
452
|
+
Num2words.to_words(Object.new, :en)
|
|
453
|
+
# raises ArgumentError: Unsupported input type: ...
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Неподдерживаемые опции:
|
|
457
|
+
|
|
458
|
+
```ruby
|
|
459
|
+
Num2words.to_words(0.5, :ru, joiner: :plus)
|
|
460
|
+
# raises ArgumentError: Unsupported joiner option: :plus
|
|
461
|
+
|
|
462
|
+
Num2words.to_currency(12, :ru, minor: :sometimes)
|
|
463
|
+
# raises ArgumentError: Unsupported minor option: :sometimes
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Некорректная денежная сумма:
|
|
467
|
+
|
|
468
|
+
```ruby
|
|
469
|
+
Num2words.to_currency("abc", :en)
|
|
470
|
+
# raises ArgumentError: Unsupported currency amount: "abc"
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
## Документация для разработки
|
|
474
|
+
|
|
475
|
+
- [Числовые ограничения](limits.ru.md)
|
|
476
|
+
- [Rails-интеграция](rails.ru.md)
|
|
477
|
+
- [Locale development guide](locale_development.md)
|
|
478
|
+
- [Русская инструкция по разработке локалей](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.
|