28const char*
ncnmetric(uintmax_t val,
size_t s, uintmax_t decimal,
29 char* buf,
int omitdec, uintmax_t mult,
31 fesetround(FE_TONEAREST);
33 const wchar_t* subprefixes = SUBPREFIXES;
34 const wchar_t prefixes[] = L
"KMGTPEZY";
35 if(decimal == 0 || mult == 0){
38 if(decimal > UINTMAX_MAX / 10){
41 unsigned consumed = 0;
43 if(decimal <= val || val == 0){
45 while((val / decimal) >= dv && consumed <
sizeof(prefixes) /
sizeof(*prefixes)){
48 if(UINTMAX_MAX / dv < mult){
53 while(val < decimal && consumed <
sizeof(prefixes) /
sizeof(*prefixes)){
56 if(UINTMAX_MAX / dv < mult){
63 if((val / decimal) / dv > 0){
74 if(omitdec && (val % dv) == 0){
75 sprintfed = snprintf(buf, s,
"%" PRIu64
"%lc", (uint64_t)(val / dv),
76 (wint_t)prefixes[consumed - 1]);
78 sprintfed = snprintf(buf, s,
"%.2f%lc", (
double)val / dv,
79 (wint_t)prefixes[consumed - 1]);
85 if((
size_t)sprintfed < s){
86 buf[sprintfed] = uprefix;
87 buf[++sprintfed] =
'\0';
94 if(omitdec && val % decimal == 0){
96 sprintfed = snprintf(buf, s,
"%" PRIu64
"%lc", (uint64_t)(val / decimal),
97 (wint_t)subprefixes[consumed - 1]);
99 sprintfed = snprintf(buf, s,
"%" PRIu64, (uint64_t)(val / decimal));
103 sprintfed = snprintf(buf, s,
"%.2f%lc", (
double)val / decimal,
104 (wint_t)subprefixes[consumed - 1]);
106 sprintfed = snprintf(buf, s,
"%.2f", (
double)val / decimal);
112 if(consumed && uprefix){
113 if((
size_t)sprintfed < s){
114 buf[sprintfed] = uprefix;
115 buf[++sprintfed] =
'\0';
const char * ncnmetric(uintmax_t val, size_t s, uintmax_t decimal, char *buf, int omitdec, uintmax_t mult, int uprefix)