summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibC/inttypes.cpp
blob: c4160ad4da3982679e5945f05f2c1c524d7dca7f (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
/*
 * Copyright (c) 2021, Mițca Dumitru <dumitru0mitca@gmail.com>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <AK/NumericLimits.h>
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>

extern "C" {

imaxdiv_t imaxdiv(intmax_t numerator, intmax_t denominator)
{
    imaxdiv_t result;
    result.quot = numerator / denominator;
    result.rem = numerator % denominator;

    if (numerator >= 0 && result.rem < 0) {
        result.quot++;
        result.rem -= denominator;
    }

    return result;
}

intmax_t strtoimax(char const* str, char** endptr, int base)
{
    long long_value = strtoll(str, endptr, base);

    intmax_t max_int_value = NumericLimits<intmax_t>::max();
    intmax_t min_int_value = NumericLimits<intmax_t>::min();
    if (long_value > max_int_value) {
        errno = -ERANGE;
        return max_int_value;
    } else if (long_value < min_int_value) {
        errno = -ERANGE;
        return min_int_value;
    }

    return long_value;
}

uintmax_t strtoumax(char const* str, char** endptr, int base)
{
    unsigned long ulong_value = strtoull(str, endptr, base);

    uintmax_t max_uint_value = NumericLimits<uintmax_t>::max();
    if (ulong_value > max_uint_value) {
        errno = -ERANGE;
        return max_uint_value;
    }

    return ulong_value;
}
}