| Contents |

9 <inttypes.h> Các phép chuyển đổi số nguyên thêm

Hàm Mô tả
imaxabs() Tính giá trị tuyệt đối của một intmax_t
imaxdiv() Tính thương và số dư của các intmax_t
strtoimax() Chuyển string sang kiểu intmax_t
strtoumax() Chuyển string sang kiểu uintmax_t
wcstoimax() Chuyển wide string sang kiểu intmax_t
wcstoumax() Chuyển wide string sang kiểu uintmax_t

Header này làm các phép chuyển đổi sang số nguyên cỡ lớn nhất, chia với số nguyên cỡ lớn nhất, và cũng cung cấp format specifier cho printf()scanf() cho một loạt kiểu được định nghĩa trong <stdint.h>.

Header <stdint.h> được include bởi header này.

9.1 Macro

Mấy macro này là để giúp printf()scanf() khi bạn dùng một kiểu như int_least16_t… bạn dùng format specifier gì?

Bắt đầu với printf()—mấy macro này bắt đầu bằng PRI rồi theo sau là format specifier mà bạn thường dùng cho kiểu đó. Cuối cùng, thêm số bit.

Ví dụ, format specifier cho số nguyên 64-bit là PRId64—chữ d là vì thường bạn in số nguyên với "%d".

Một số nguyên không dấu 16-bit có thể được in với PRIu16.

Mấy macro này mở rộng thành string literal. Ta có thể tận dụng việc C tự động nối các string literal kề nhau và dùng các specifier này như sau:

#include <stdio.h>     // cho printf()
#include <inttypes.h>

int main(void)
{
    int16_t x = 32;

    printf("The value is %" PRId16 "!\n", x);
}

Không có gì ma thuật xảy ra ở dòng 8 bên trên đâu. Thật vậy, nếu tôi in giá trị của macro:

printf("%s\n", PRId16);

ta nhận được cái này trên hệ của tôi:

hd

là một format specifier của printf() có nghĩa “số nguyên có dấu ngắn”.

Nên quay lại dòng 8, sau khi nối string literal, nó y hệt như tôi đã gõ:

    printf("The value is %hd!\n", x);

Đây là bảng mọi macro bạn có thể dùng cho format specifier của printf()… thay số bit vào N, thường là 8, 16, 32, hoặc 64.

PRIdN PRIdLEASTN PRIdFASTN PRIdMAX PRIdPTR
PRIiN PRIiLEASTN PRIiFASTN PRIiMAX PRIiPTR
PRIoN PRIoLEASTN PRIoFASTN PRIoMAX PRIoPTR
PRIuN PRIuLEASTN PRIuFASTN PRIuMAX PRIuPTR
PRIxN PRIxLEASTN PRIxFASTN PRIxMAX PRIxPTR
PRIXN PRIXLEASTN PRIXFASTN PRIXMAX PRIXPTR

Để ý lần nữa là chữ chữ thường ở giữa đại diện cho các format specifier thông thường bạn truyền cho printf(): d, i, o, u, x, và X.

Và ta có một bộ macro tương tự cho scanf() để đọc các kiểu này:

SCNdN SCNdLEASTN SCNdFASTN SCNdMAX SCNdPTR
SCNiN SCNiLEASTN SCNiFASTN SCNiMAX SCNiPTR
SCNoN SCNoLEASTN SCNoFASTN SCNoMAX SCNoPTR
SCNuN SCNuLEASTN SCNuFASTN SCNuMAX SCNuPTR
SCNxN SCNxLEASTN SCNxFASTN SCNxMAX SCNxPTR

Quy tắc là với mỗi kiểu được định nghĩa trong <stdint.h> sẽ có các macro printf()scanf() tương ứng được định nghĩa ở đây.


9.2 imaxabs()

Tính giá trị tuyệt đối của một intmax_t

Synopsis

#include <inttypes.h>

intmax_t imaxabs(intmax_t j);

Mô tả

Khi bạn cần giá trị tuyệt đối của kiểu số nguyên lớn nhất trên hệ thống, đây là hàm dành cho bạn.

Spec ghi chú rằng nếu giá trị tuyệt đối của số không biểu diễn được, hành vi là undefined. Chuyện này xảy ra nếu bạn thử lấy giá trị tuyệt đối của số âm nhỏ nhất có thể trên hệ thống biểu diễn bù hai (two’s complement).

Giá trị trả về

Trả về giá trị tuyệt đối của đầu vào, \(|j|\).

Ví dụ

#include <stdio.h>
#include <inttypes.h>

int main(void)
{
    intmax_t j = -3490;

    printf("%jd\n", imaxabs(j));    // 3490
}

Xem thêm

fabs()


9.3 imaxdiv()

Tính thương và số dư của các intmax_t

Synopsis

#include <inttypes.h>

imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom);

Mô tả

Khi bạn muốn làm phép chia nguyên và lấy số dư trong cùng một phép, hàm này sẽ làm cho bạn.

Nó tính numer/denomnumer%denom rồi trả về kết quả trong một struct kiểu imaxdiv_t.

Struct này có hai field kiểu imaxdiv_t, quotrem, mà bạn dùng để lấy các giá trị mong muốn.

Giá trị trả về

Trả về một imaxdiv_t chứa thương và số dư của phép toán.

Ví dụ

#include <stdio.h>
#include <inttypes.h>

int main(void)
{
    intmax_t numer = INTMAX_C(3490);
    intmax_t denom = INTMAX_C(17);

    imaxdiv_t r = imaxdiv(numer, denom);

    printf("Quotient: %jd, remainder: %jd\n", r.quot, r.rem);
}

Output:

Quotient: 205, remainder: 5

Xem thêm

remquo()


9.4 strtoimax() strtoumax()

Chuyển string sang kiểu intmax_tuintmax_t

Synopsis

#include <inttypes.h>

intmax_t strtoimax(const char * restrict nptr, char ** restrict endptr,
                   int base);

uintmax_t strtoumax(const char * restrict nptr, char ** restrict endptr,
                   int base);

Mô tả

Mấy cái này hoạt động y hệt họ hàm strtol(), chỉ khác là trả về intmax_t hoặc uintmax_t.

Xem trang tham chiếu strtol() để biết chi tiết.

Giá trị trả về

Trả về string đã chuyển dưới dạng intmax_t hoặc uintmax_t.

Nếu kết quả nằm ngoài miền giá trị, giá trị trả về sẽ là INTMAX_MAX, INTMAX_MIN, hoặc UINTMAX_MAX, tuỳ trường hợp. Và biến errno sẽ được set thành ERANGE.

Ví dụ

Ví dụ sau chuyển một số cơ số 10 sang intmax_t. Rồi nó thử chuyển một số cơ số 2 không hợp lệ, bắt lỗi.

#include <stdio.h>
#include <inttypes.h>

int main(void)
{
    intmax_t r;
    char *endptr;

    // Số cơ số 10 hợp lệ
    r = strtoimax("123456789012345", &endptr, 10);

    if (*endptr != '\0')
        printf("Invalid digit: %c\n", *endptr);
    else
        printf("Value is %jd\n", r);
    
    // Số nhị phân sau chứa chữ số không hợp lệ
    r = strtoimax("0100102010101101", &endptr, 2);

    if (*endptr != '\0')
        printf("Invalid digit: %c\n", *endptr);
    else
        printf("Value is %jd\n", r);
}

Output:

Value is 123456789012345
Invalid digit: 2

Xem thêm

strtol(), errno


9.5 wcstoimax() wcstoumax()

Chuyển wide string sang kiểu intmax_tuintmax_t

Synopsis

#include <stddef.h> // cho wchar_t
#include <inttypes.h>

intmax_t wcstoimax(const wchar_t * restrict nptr,
                   wchar_t ** restrict endptr, int base);

uintmax_t wcstoumax(const wchar_t * restrict nptr,
                    wchar_t ** restrict endptr, int base);

Mô tả

Mấy cái này hoạt động y hệt họ hàm wcstol(), chỉ khác là trả về intmax_t hoặc uintmax_t.

Xem trang tham chiếu wcstol() để biết chi tiết.

Giá trị trả về

Trả về wide string đã chuyển dưới dạng intmax_t hoặc uintmax_t.

Nếu kết quả nằm ngoài miền giá trị, giá trị trả về sẽ là INTMAX_MAX, INTMAX_MIN, hoặc UINTMAX_MAX, tuỳ trường hợp. Và biến errno sẽ được set thành ERANGE.

Ví dụ

Ví dụ sau chuyển một số cơ số 10 sang intmax_t. Rồi nó thử chuyển một số cơ số 2 không hợp lệ, bắt lỗi.

#include <wchar.h>
#include <inttypes.h>

int main(void)
{
    intmax_t r;
    wchar_t *endptr;

    // Số cơ số 10 hợp lệ
    r = wcstoimax(L"123456789012345", &endptr, 10);

    if (*endptr != '\0')
        wprintf(L"Invalid digit: %lc\n", *endptr);
    else
        wprintf(L"Value is %jd\n", r);
    
    // Số nhị phân sau chứa chữ số không hợp lệ
    r = wcstoimax(L"0100102010101101", &endptr, 2);

    if (*endptr != '\0')
        wprintf(L"Invalid digit: %lc\n", *endptr);
    else
        wprintf(L"Value is %jd\n", r);
}
Value is 123456789012345
Invalid digit: 2

Xem thêm

wcstol(), errno


| Contents |