summaryrefslogtreecommitdiff
path: root/man/ru/mpu_printf.3
blob: 58195f8994de47c0023dda79281390cd567340e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
.TH MPU_PRINTF 3 "Сентябрь 2026" "libmpuio" "Руководство программиста LIBMPUIO"
.SH ИМЯ
mpu_printf, mpu_fprintf, mpu_sprintf, mpu_snprintf, mpu_asprintf,
mpu_dprintf, mpu_vprintf, mpu_vfprintf, mpu_vsprintf, mpu_vsnprintf,
mpu_vasprintf, mpu_vdprintf, mpu_printf_unlocked, mpu_fprintf_unlocked,
mpu_vprintf_unlocked, mpu_vfprintf_unlocked
\- форматированный вывод UCS-2, включая числа libmpu произвольной точности
.SH ОБЗОР
.nf
#include <libmpuio.h>

int       mpu_printf( const __mpu_char16_t *format, ... );
int       mpu_fprintf( mpu_FILE *stream,
                       const __mpu_char16_t *format, ... );
int       mpu_sprintf( __mpu_char16_t *string,
                       const __mpu_char16_t *format, ... );
int       mpu_snprintf( __mpu_char16_t *string, size_t size,
                        const __mpu_char16_t *format, ... );
int       mpu_asprintf( __mpu_char16_t **string,
                        const __mpu_char16_t *format, ... );
int       mpu_dprintf( int fd, const __mpu_char16_t *format, ... );
int       mpu_vprintf( const __mpu_char16_t *format, va_list args );
int       mpu_vfprintf( mpu_FILE *stream,
                        const __mpu_char16_t *format, va_list args );
int       mpu_vsprintf( __mpu_char16_t *string,
                        const __mpu_char16_t *format, va_list args );
int       mpu_vsnprintf( __mpu_char16_t *string, size_t size,
                         const __mpu_char16_t *format, va_list args );
int       mpu_vasprintf( __mpu_char16_t **string,
                         const __mpu_char16_t *format, va_list args );
int       mpu_vdprintf( int fd, const __mpu_char16_t *format,
                        va_list args );
int       mpu_printf_unlocked( const __mpu_char16_t *format, ... );
int       mpu_fprintf_unlocked( mpu_FILE *stream,
                                const __mpu_char16_t *format, ... );
int       mpu_vprintf_unlocked( const __mpu_char16_t *format, va_list args );
int       mpu_vfprintf_unlocked( mpu_FILE *stream,
                                 const __mpu_char16_t *format, va_list args );
.fi
.SH ОПИСАНИЕ
Семейство
.B mpu_printf()
формирует форматированный текст из строки формата UCS-2.
.B mpu_printf()
и
.B mpu_vprintf()
пишут в
.BR mpu_stdout .
.B mpu_fprintf()
и
.B mpu_vfprintf()
пишут в указанный
.BR mpu_FILE .
.B mpu_sprintf()
и
.B mpu_vsprintf()
пишут в неограниченную строку памяти UCS-2, предоставленную вызывающей стороной.
.B mpu_snprintf()
и
.B mpu_vsnprintf()
записывают не более
.I size
кодовых единиц UCS-2, включая завершающий ноль.
.PP
Для потоков реальных файлов текст UCS-2, созданный formatter, кодируется
потоковым слоем в UTF-8.  Назначения в памяти/строках остаются UCS-2.
.PP
.B mpu_asprintf()
и
.B mpu_vasprintf()
выделяют через
.BR malloc (3)
достаточно большой NUL-терминированный результат UCS-2.
При успехе они сохраняют указатель через
.IR string ;
вызывающая сторона освобождает его через
.BR free (3).
Если операция завершается ошибкой,
.I *string
устанавливается в NULL.
.PP
.B mpu_dprintf()
и
.B mpu_vdprintf()
пишут форматированный текст в существующий POSIX-файловый дескриптор.
Дескриптор не закрывается, владение остаётся у вызывающей стороны.  Текст
кодируется в UTF-8 по тем же правилам внешнего представления, что и для
обычного файлового потока LIBMPUIO на основе дескриптора.
.PP
Обычный синтаксис преобразований следует соглашениям printf.  LIBMPUIO
расширяет его преобразованиями целых, вещественных и комплексных объектов
libmpu произвольной точности.
.SH ФОРМАТ СТРОКИ ФОРМАТА
Обычные символы в
.I format
копируются без изменений.  Спецификация преобразования начинается с
.B %
и имеет вид
.PP
.nf
%[flags][width][.precision][.expdigits][length-or-Zbits]conversion
.fi
.PP
Поле
.B .expdigits
\- расширение LIBMPUIO, используемое преобразованиями вещественных и комплексных
чисел MPU.  Оно не является частью обычного синтаксиса printf языка C.
.PP
Литерал знака процента выводится через
.BR %% .
.SH ФЛАГИ
Распознаются следующие флаги.
.TP
.B -
Выравнивать преобразованное значение по левому краю поля.  Флаг
.B 0
игнорируется при наличии
.BR - .
.TP
.B +
Всегда выводить знак для знаковых числовых преобразований.
.TP
.B " "
Добавлять пробел перед положительным знаковым числовым значением.  Флаг
.B +
имеет приоритет.
.TP
.B #
Выбрать альтернативную форму.  Для восьмеричного вывода она обеспечивает
начальный ноль.  Для шестнадцатеричного вывода ненулевое значение получает
.B 0x
или
.BR 0X .
Для двоичных
.B b/B
ненулевое значение получает
.B 0b
или
.BR 0B .
Для обычных вещественных преобразований флаг имеет стандартный printf-смысл
альтернативной формы.  Для общего формата MPU он также запрещает удаление
незначащих завершающих нулей дробной части и десятичной точки.
.TP
.B 0
Дополнять числовые поля нулями вместо пробелов, когда это применимо.  Для
целочисленных преобразований флаг игнорируется при наличии явной точности.
.SH ШИРИНА ПОЛЯ
Десятичное число задаёт минимальную ширину поля.  При необходимости
преобразованное значение дополняется, но никогда не усекается только ради
соблюдения ширины.
.PP
Ширина
.B *
берётся из следующего аргумента типа
.BR int .
Отрицательная ширина трактуется как положительная ширина вместе с флагом
.BR - .
.SH ТОЧНОСТЬ
Точность начинается с точки.  После неё может следовать десятичное целое или
.BR * .
Отрицательная точность, переданная через
.BR * ,
трактуется так, как если бы точность вообще не была указана.
.PP
Для
.B d, i, u, o, x, X, b
и
.B B
точность задаёт минимальное число цифр.  Целое значение ноль при точности ноль
не выводит цифр с учётом правил альтернативной формы.
.PP
Для
.B s
точность задаёт максимальное число символов UCS-2, выводимых из строки.
Точность не влияет на
.BR c .
.PP
Для обычных вещественных преобразований точность имеет стандартный printf-
смысл.  Для вещественных преобразований MPU см. раздел
.B ПРЕОБРАЗОВАНИЯ ВЕЩЕСТВЕННЫХ ЧИСЕЛ MPU
ниже.
.SH МОДИФИКАТОРЫ ДЛИНЫ
Для обычных целочисленных преобразований поддерживаются следующие модификаторы
длины.
.TP
.B hh
Аргумент преобразуется как
.B signed char
или
.BR unsigned char .
.TP
.B h
Аргумент преобразуется как
.B short
или
.BR unsigned short .
.TP
.B l
Аргумент имеет тип
.B long
или
.BR unsigned long .
Для обычного вещественного вывода, как и в C printf,
.B l
не изменяет продвинутый аргумент
.BR double .
.TP
.B ll
Аргумент имеет тип
.B long long
или
.BR unsigned long long .
.TP
.B j
Аргумент имеет тип
.B intmax_t
или
.BR uintmax_t .
Для
.B %n
при использовании
.B j
аргумент имеет тип
.BR intmax_t\ * .
.TP
.B t
Аргумент имеет тип
.B ptrdiff_t
или соответствующую беззнаковую интерпретацию.
.TP
.B L
Для обычных вещественных преобразований аргумент имеет тип
.BR "long double" .
.PP
Стандартный модификатор длины C
.B z
намеренно не реализован.  В LIBMPUIO и
.B z,
и
.B Z
вводят описанный ниже модификатор размера LibMPU.
.PP
Буква
.B j
также обозначает историческое комплексное преобразование MPU.  Она трактуется
как стандартный модификатор длины
.B intmax_t,
если после неё следует обычное целочисленное преобразование или
.BR n ;
в остальных случаях это комплексное преобразование MPU.
.SH ОБЫЧНЫЕ ПРЕОБРАЗОВАНИЯ
.TP
.B d, i
Вывести знаковое десятичное целое.
.TP
.B u
Вывести беззнаковое десятичное целое.
.TP
.B o
Вывести беззнаковое целое в восьмеричном виде.
.TP
.B x, X
Вывести беззнаковое целое в шестнадцатеричном виде.  Цифры и префикс
альтернативной формы используют нижний регистр для
.B x
и верхний для
.BR X .
.TP
.B b, B
Расширение LIBMPUIO: вывести беззнаковое целое в двоичном виде.  С
.B #
ненулевое значение получает
.B 0b
или
.BR 0B .
.TP
.B c
Вывести один символ UCS-2.  Поскольку символьный I/O LIBMPUIO использует UCS-2,
аргумент имеет тип
.B int,
значение которого преобразуется в
.BR __mpu_char16_t .
Это не многобайтовое/wchar_t-преобразование libc.
.TP
.B s
Вывести NUL-терминированную строку UCS-2 типа
.BR "const __mpu_char16_t *" .
Точность ограничивает число выводимых символов UCS-2.  NULL-указатель выводится
как
.BR (null) .
.TP
.B a
Расширение LIBMPUIO: вывести NUL-терминированную многобайтовую строку текущей
локали типа
.BR "const __mpu_char8_t *" .
Байтовая строка декодируется согласно активной локали
.B LC_CTYPE
и преобразуется в строгий UCS-2 до попадания в поток LIBMPUIO.  Ширина поля и
точность измеряются в преобразованных символах UCS-2.  NULL-указатель выводится
как
.BR (null) .
Некорректная многобайтовая последовательность, суррогат или символ вне модели
UCS-2 приводят к ошибке преобразования
.BR EILSEQ .
Модификаторы длины и MPU-модификатор
.B z/Z<bits>
к этому преобразованию не применяются.
.TP
.B p
Вывести значение указателя в шестнадцатеричной альтернативной форме.  Тип
аргумента \-
.BR "void *" .
.TP
.B n
Записать число символов UCS-2, сформированных к этому моменту, через аргумент-
указатель.  Это преобразование само не выводит символов.  Тип указателя
выбирается модификатором длины: без модификатора используется
.BR int\ * ;
.B hh, h, l, ll, j
и
.B t
выбирают соответствующие целочисленные типы указателей.
.TP
.B f, F
Вывести обычный
.B double
(или
.B long double
с
.BR L )
в фиксированном формате.
.TP
.B e, E
Вывести обычное вещественное значение в научной нотации.
.TP
.B g, G
Вывести обычное вещественное значение в общем формате.
.PP
Обычный вывод
.B f/F/e/E/g/G
делегируется правилам форматирования libc хост-системы и потому следует
активному символу десятичного разделителя
.BR LC_NUMERIC .
LIBMPUIO декодирует полученное многобайтовое поле libc в строгий UCS-2 до
передачи в поток LIBMPUIO; некорректные последовательности, суррогатный вывод
или символы вне модели UCS-2 отвергаются с
.BR EILSEQ .
Соответствующие обычные преобразования scanf используют то же соглашение о
десятичном разделителе локали.
Грамматика форматированных чисел MPU
.B z/Z<bits>
отделена от этого обычного поведения локали C.
.SH МОДИФИКАТОР РАЗМЕРА MPU
Модификатор размера LibMPU для чисел произвольной точности имеет вид
.B z<bits>
или
.BR Z<bits> .
Строчная и прописная формы эквивалентны.  Стандартный модификатор длины C
.B z
для
.B size_t
намеренно не является частью языка форматов LIBMPUIO.
.PP
Десятичное поле
.I bits
не является произвольным числом времени выполнения.  Оно должно обозначать один
из размеров MPU, скомпилированных в грамматику текущей сборки LIBMPUIO:
.PP
.nf
8, 16, 32, 64, 128, 256, 512, 1024,
2048, 4096, 8192, 16384, 32768, 65536
.fi
.PP
В конкретной сборке существуют только значения, не превышающие
.B MPU_REAL_IO_LIMIT
из
.BR <libmpu.h> .
Например, если
.B MPU_REAL_IO_LIMIT
равен 16384, то модификаторы
.B z32768,
.B Z32768,
.B z65536
и
.B Z65536
в языке форматов этой сборки LIBMPUIO отсутствуют и приводят к ошибке формата.
.PP
Если после
.B z
или
.BR Z
не следуют десятичные цифры, предполагается 128 бит.  Поэтому
.B %zu
является MPU-преобразованием 128-битного беззнакового целого и по размеру точно
эквивалентно
.BR %z128u ;
это
.B не
преобразование
.BR size_t .
Аналогично,
.B %zR,
.B %ZR,
.B %zJ
и
.B %ZJ
используют размер MPU по умолчанию, равный 128 бит.
.PP
Модификатор размера разбирается до буквы преобразования.  После принятия размера
буква преобразования выбирает класс числа: целочисленные преобразования работают
с целым объектом libmpu, вещественные \- с вещественным объектом libmpu, а
.B j/J
\- с комплексным объектом libmpu.  Целочисленные преобразования принимают размеры
MPU начиная с 8 бит; для вещественных и комплексных преобразований требуется не
менее 32 бит.
.PP
.B MPU_MATH_FN_LIMIT
не определяет грамматику форматированного I/O.  Он ограничивает только
трансцендентные/математические функции.  Набор доступных модификаторов
.B z/Z<bits>
определяется
.BR MPU_REAL_IO_LIMIT .
.SH МОДЕЛЬ ТИПОВ АРГУМЕНТОВ
Обычные преобразования C и преобразования MPU намеренно используют разные
соглашения об аргументах.
.PP
Для обычного преобразования буква преобразования и стандартный модификатор
длины описывают тип C, который должен извлечь
.BR va_arg ().
Аргумент передаётся по значению с обычными преобразованиям аргументов по умолчанию.
Например:
.PP
.nf
char  k = 7;
mpu_printf( MPU_UCS2("k = %d\n"), k );
.fi
.PP
Здесь
.B k
продвигается до
.B int
до попадания в список вариадических аргументов, а
.B %d
выбирает значение
.BR int .
Formatter не обнаруживает тип аргумента во время выполнения; строка формата
сообщает ему, какой тип C извлекать.
.PP
Преобразование MPU, выбранное
.B z<bits>
или
.BR Z<bits> ,
имеет другой контракт.  Его аргумент \- указатель на хранилище объекта MPU, а
модификатор размера точно сообщает formatter, сколько бит содержит этот
объект.  Для array typedef, используемых libmpu, имя объекта в аргументе вызова
функции обычно подвергается стандартному преобразованию массива в указатель,
поэтому естественная запись выглядит так:
.PP
.nf
mpu_int128_t   c;
mpu_real128_t  r;

mpu_printf( MPU_UCS2("c = %z128u\n"), c );
mpu_printf( MPU_UCS2("r = %z128g\n"), r );
.fi
.PP
Сам указатель не несёт метаданных размера объекта.  Поэтому вариадический
formatter не может определить, указывает ли он, например, на 32-, 128- или
65536-битный объект MPU.  Явное поле
.B z/Z<bits>
следовательно является частью типового контракта MPU-преобразования, а не
избыточным украшением.
.PP
Технически возможно направить MPU-преобразование на хранилище обычного объекта
C, если его точное представление и размер намеренно известны, например:
.PP
.nf
char  k = 7;
mpu_printf( MPU_UCS2("k = %z8d\n"), &k );
.fi
.PP
Это низкоуровневая интерпретация байта по адресу
.B &k
как 8-битного целого объекта MPU; это
.B не
обычное соглашение вывода C
.B char
и не должно использоваться как переносимая замена
.BR %d .
Для многобайтовых объектов C такое использование дополнительно может зависеть
от представления, порядка байтов и совместимости с хранилищем libmpu.  Обычные
объекты C обычно должны использовать обычные преобразования C; объекты MPU \-
.BR z/Z<bits> .
.PP
Замена array typedef libmpu на structure typedef не сделала бы вариадическую
функцию самоописывающейся.  C
.B va_list
не несёт универсальных метаданных типа или размера времени выполнения, а
.B va_arg()
по-прежнему требует, чтобы ожидаемый тип был известен из контракта формата.

.SH ЦЕЛОЧИСЛЕННЫЕ ПРЕОБРАЗОВАНИЯ MPU
С
.BR z/Z<bits> ,
.B d
и
.B i
форматируют знаковое целое произвольной точности.  Преобразования
.B u, o, x, X, b
и
.B B
форматируют беззнаковое целое произвольной точности.  Аргумент является
указателем на целый объект libmpu, размер хранилища которого соответствует
выбранному числу бит.
.PP
Примеры:
.PP
.nf
%Z128d
%#Z256x
%#Z1024B
%08.3Z128d
.fi
.PP
Formatter удаляет внутренний префикс основания libmpu до применения собственных
правил альтернативной формы printf.  Поэтому
.B #
имеет одинаковый внешне наблюдаемый смысл для обычного и MPU-целочисленного
вывода.
.SH ПРЕОБРАЗОВАНИЯ ВЕЩЕСТВЕННЫХ ЧИСЕЛ MPU
Нативные вещественные преобразования MPU \-
.B r
и
.BR R .
Если явный модификатор
.B z/Z<bits>
не задан, используется 128 бит.
.PP
Буква преобразования выбирает регистр, однако маркер экспоненты, выводимый для
вещественного числа, равен
.B e
для
.B %r
и
.B E
для
.BR %R .
Буквы
.B r/R
являются спецификаторами преобразования, а не печатаемым разделителем
экспоненты вещественного числа.
.PP
Примеры:
.PP
.nf
%Z128R
%.28Z128R
%.28.4Z128R
.fi
.PP
Первая точность управляет числом цифр мантиссы.  Необязательное второе поле
.B .expdigits
задаёт минимальную ширину экспоненты.  Оно также может передаваться через
.BR * .
Например:
.PP
.nf
%.4.3Z128e     -> 1.2346e+004
.fi
.PP
Также поддерживаются MPU-формы
.B z/Z<bits>e,
.B z/Z<bits>E,
.B z/Z<bits>f,
.B z/Z<bits>F,
.B z/Z<bits>g
и
.BR z/Z<bits>G .
.PP
Все эти вещественные преобразования извлекают указатель на вещественный объект
libmpu выбранного размера.  В частности, и
.B %Z128R,
и
.B %Z128E
ожидают объект
.BR mpu_real128_t .
Комплексный вывод отделён:
.B %Z128J
ожидает объект
.BR mpu_complex128_t .
Таким образом, соответствие типов имеет вид:
.PP
.nf
%Z128R  -> mpu_real128_t
%Z128E  -> mpu_real128_t
%Z128J  -> mpu_complex128_t
.fi
.PP
Для исторической совместимости с CODE.LIB
.B MPU f/F являются научными псевдонимами e/E;
они не являются преобразованиями фиксированной точки.  Это намеренно отличается
от обычных C
.BR %f/%F .
.PP
Для MPU
.B g/G
отсутствующая точность по умолчанию равна 6, а точность ноль трактуется как одна
значащая цифра.  Научная нотация выбирается, если десятичная экспонента меньше
-4 или больше либо равна точности.  В остальных случаях используется
фиксированный стиль.  Завершающие незначащие нули дробной части и десятичная
точка удаляются, если не указан
.BR # .
.PP
Строчная
.B %a
\- преобразование LIBMPUIO для многобайтовой строки текущей локали.
.SH ПРЕОБРАЗОВАНИЯ КОМПЛЕКСНЫХ ЧИСЕЛ MPU
Нативные комплексные преобразования MPU \-
.B j
и
.BR J .
Если явный размер MPU не задан, по умолчанию используется 128 бит.  Аргумент
является указателем на комплексный объект libmpu выбранного размера.
.PP
Действительная и мнимая компоненты объединяются в историческом комплексном
представлении MPU.  Например:
.PP
.nf
%.20.4Z128J
    -> 1.25000000000000000000R+0000-2.50000000000000000000J+0000
.fi
.PP
Для
.B %j
маркеры экспонент компонентов \-
.B r
и
.BR j .
Для
.B %J
они равны
.B R
и
.BR J .
Этот исторический комплексный синтаксис намеренный.  Он отличается от
вещественных
.BR %r/%R ,
у которых печатаемый маркер экспоненты \-
.BR e/E .
.PP
Если флаг
.B 0
используется вместе с полем, ширина которого больше длины сформированного
комплексного значения, свободная часть поля делится поровну между
действительной и мнимой компонентами.  Нули вставляются после знака каждой
компоненты.  Если свободная ширина нечётна, один оставшийся символ выводится
как обычный ведущий пробел.  Например, для значения с компонентами 1.25 и 2.5:
.PP
.nf
%+040.6.3Z128J
    -> +0000001.250000R+000+0000002.500000J+000
%+039.6.3Z128J
    ->  +000001.250000R+000+000002.500000J+000
.fi
.SH СТРОКОВЫЙ ВЫВОД И УСЕЧЕНИЕ
.B mpu_sprintf()
и
.B mpu_vsprintf()
не знают ёмкость назначения.  Вызывающая сторона обязана предоставить достаточно
хранилища UCS-2 для полного результата и завершающего нуля.
.PP
.B mpu_snprintf()
и
.B mpu_vsnprintf()
записывают не более
.I size
кодовых единиц UCS-2, включая завершающий ноль.  Если
.I size
равен нулю, данные назначения не записываются.  Возвращаемое значение \- число
символов UCS-2, которое было бы сформировано при достаточном пространстве, без
завершающего нуля.
.SH БЛОКИРОВКА
Обычные потоковые варианты блокируют
.B mpu_FILE
на время форматирования.  Варианты
.B *_unlocked
не захватывают mutex потока.  Они предназначены для кода, который уже
сериализовал доступ, обычно через
.BR mpu_flockfile (3):
.PP
.nf
mpu_flockfile( fp );
mpu_fprintf_unlocked( fp, fmt, ... );
mpu_fflush_unlocked( fp );
mpu_funlockfile( fp );
.fi
.PP
Функции строкового вывода используют приватные потоки памяти и не имеют
публичных unlocked-вариантов.
.SH ОПРЕДЕЛЕНИЕ РАЗМЕРА И УСЕЧЕНИЕ SNPRINTF
Для
.B mpu_snprintf()
и
.BR mpu_vsnprintf ()
аргумент
.I size
\- ёмкость массива назначения UCS-2, включая конечный символ NUL.  Если
.I size
равен нулю, символы назначения не сохраняются, а
.I string
может быть NULL.  Функции всё равно полностью разбирают формат и возвращают
число символов UCS-2, которое было бы сформировано, без конечного NUL.  Это
позволяет использовать обычную двухпроходную схему выделения памяти.
.PP
При усечении вывода возвращаемое значение и любое преобразование
.B %n
используют логическое число символов, а не число символов, реально поместившихся
в массив назначения.
.PP
Если логическое число символов форматированного вывода не представимо типом
.BR int ,
операция завершается с отрицательным возвращаемым значением и
.B errno,
установленным в
.BR EOVERFLOW .
.SH ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успехе эти функции возвращают число сформированных символов UCS-2 без
завершающего нуля, используемого строковыми назначениями.  Для
.BR mpu_asprintf ()
и
.BR mpu_vasprintf ()
это число выделенных кодовых единиц UCS-2 до завершающего NUL.
Для
.BR mpu_dprintf ()
и
.BR mpu_vdprintf ()
счётчик по-прежнему измеряется в символах UCS-2, а не в числе байтов UTF-8,
записанных в дескриптор.  Отрицательное значение означает ошибку.
.PP
.B %n
не выводит символов; оно лишь сохраняет счётчик, накопленный к этому моменту.
.SH ОШИБКИ
Ошибки нижележащего потока и выделения памяти сообщаются отрицательным
возвращаемым значением и, где применимо,
.BR errno .
.B mpu_asprintf()
и
.B mpu_vasprintf()
сообщают об ошибке выделения памяти через
.BR ENOMEM ;
NULL-указатель назначения отвергается с
.BR EINVAL .
.B mpu_dprintf()
и
.B mpu_vdprintf()
могут сообщать ошибки дескриптора и записи, например
.BR EBADF .
Недопустимый настроенный размер MPU приводит к ошибке с
.BR EINVAL .
Строгая файловая граница UCS-2 может возвращать
.B EILSEQ,
если символ не может быть представлен по правилам UCS-2/UTF-8 LIBMPUIO.
.SH ПРИМЕРЫ
Строка UCS-2 и обычные значения:
.PP
.nf
__mpu_char16_t  fmt[]  = MPU_UCS2("name=%s value=%08x");
__mpu_char16_t  name[] = MPU_UCS2("mpu");
mpu_printf( fmt, name, 0x1234U );
.fi
.PP
Многобайтовая строка текущей локали:
.PP
.nf
__mpu_char8_t  name8[] = "Andrey";
mpu_printf( MPU_UCS2("name=%a\n"), name8 );
.fi
.PP
Целое произвольной точности:
.PP
.nf
__mpu_char16_t  fmt[] = MPU_UCS2("%#Z256x");
mpu_printf( fmt, &integer256 );
.fi
.PP
128-битное вещественное число с 28 цифрами мантиссы и четырьмя цифрами
экспоненты:
.PP
.nf
__mpu_char16_t  fmt[] = MPU_UCS2("%.28.4Z128E");
mpu_fprintf( fp, fmt, &real128 );
.fi
.SH СТРОКОВЫЕ ЛИТЕРАЛЫ UCS-2
Публичный макрос
.B MPU_UCS2()
формирует нативный 16-битный строковый литерал с помощью префикса языка
.BR u"..." .
Например:
.PP
.nf
mpu_printf( MPU_UCS2( "value=%d" ), value );
.fi
.PP
В отличие от
.BR L"..." ,
использующего платформенный тип
.BR wchar_t ,
.B MPU_UCS2()
предназначен для интерфейсов LIBMPUIO, текстовые аргументы которых используют
тип LIBMPU
.BR __mpu_char16_t .
.PP
Публичный заголовок включает эту возможность, когда режим трансляции
предоставляет 16-битные строковые литералы
.BR u"..." :
C11 или новее, C++11 или новее либо режим GNU C, поддерживающий это расширение.
Конфигурация сборки также может определить
.B MPU_HAVE_UCS2_STRING_LITERALS
до включения
.B <libmpuio.h>,
явно указывая доступность возможности.  Если она недоступна, публичный заголовок
выдаёт ошибку времени компиляции.
.PP
Префикс литерала является возможностью исходного языка, а не переключателем
кодировки времени выполнения.  LIBMPUIO по-прежнему применяет строгие правила
UCS-2 и отвергает суррогатные кодовые единицы с
.BR EILSEQ .
.SH ПРИМЕЧАНИЯ
LIBMPUIO использует внутри 16-битный UCS-2, а не платформенный тип
.BR wchar_t .
Поэтому
.B %c
и
.B %s
работают непосредственно с символами и строками UCS-2 и не имеют многобайтовой
семантики libc
.BR %lc/%ls .
Преобразование LIBMPUIO
.B %a
является явным интерфейсом многобайтовой строки текущей локали; тип его аргумента
\-
.BR "const __mpu_char8_t *" .
.PP
Строгий UCS-2 не может представлять скалярные значения Unicode выше U+FFFF.
Текстовый слой не представляет такой ввод парами суррогатов.
.SH СМ. ТАКЖЕ
.BR mpu_scanf (3),
.BR mpu_flockfile (3),
.BR mpu_unlocked (3),
.BR mpu_fopen (3),
.BR libmpuio (3)
.SH ЛОКАЛЬ
Для обычных преобразований с плавающей точкой символ десятичной точки следует
активной локали C так же, как в системном семействе
.BR printf (3).
Следовательно, локаль, в которой
.B LC_NUMERIC
использует запятую, может, например, вывести
.B 1,50
для
.BR %.2f .
Регрессионный набор LIBMPUIO выбирает локаль C после инициализации libmpu, чтобы
ожидаемые строки были воспроизводимыми.

.SH ПЕРЕПОЛНЕНИЕ ПАРСЕРА ФОРМАТА
Парсер формата обнаруживает переполнение при десятичном накоплении ширины поля,
точности, расширения ширины экспоненты LIBMPU и полей размера z/Z<bits>.
Он также отвергает INT_MIN, переданный как отрицательная ширина поля через *,
поскольку это значение нельзя представить как положительную ширину int.  Эти
случаи завершаются с отрицательным возвращаемым значением и устанавливают errno
в EOVERFLOW.
.SH БЛОКИРУЕМЫЙ И UNLOCKED-ФОРМАТИРОВАННЫЙ ВЫВОД
.BR mpu_fprintf_unlocked (),
.BR mpu_vfprintf_unlocked (),
.BR mpu_printf_unlocked ()
и
.BR mpu_vprintf_unlocked ()
используют ровно тот же formatter, что и обычные потоковые формы, но не
выполняют неявную блокировку потока.  Разбор формата, обработка MPU z/Z<bits>,
поведение локали, %n, логические счётчики вывода, правила усечения и ошибки не
изменяются.
.PP
Семейства sprintf/snprintf пишут в память UCS-2, принадлежащую вызывающей
стороне, а не в поток mpu_FILE, и потому не имеют stream-unlocked вариантов.