diff --git a/include/stdint.h b/include/stdint.h
index 5d6f04769..6d51565e0 100644
--- a/include/stdint.h
+++ b/include/stdint.h
@@ -52,15 +52,15 @@ typedef unsigned char       uint8_t;
 typedef unsigned            uint16_t;
 typedef unsigned long       uint32_t;
 
-#define INT8_MIN            ((int8_t) 0x80)
-#define INT8_MAX            ((int8_t) 0x7F)
-#define INT16_MIN           ((int16_t) 0x8000)
-#define INT16_MAX           ((int16_t) 0x7FFF)
-#define INT32_MIN           ((int32_t) 0x80000000)
-#define INT32_MAX           ((int32_t) 0x7FFFFFFF)
-#define UINT8_MAX           ((uint8_t) 0xFF)
-#define UINT16_MAX          ((uint16_t) 0xFFFF)
-#define UINT32_MAX          ((uint32_t) 0xFFFFFFFF)
+#define INT8_MIN            -128
+#define INT8_MAX            127
+#define INT16_MIN           (-32767 - 1)
+#define INT16_MAX           32767
+#define INT32_MIN           (-2147483647L - 1L)
+#define INT32_MAX           2147483647L
+#define UINT8_MAX           255
+#define UINT16_MAX          65535U
+#define UINT32_MAX          4294967295UL
 
 /* Minimum-width integer types */
 typedef signed char         int_least8_t;
@@ -70,15 +70,15 @@ typedef unsigned char       uint_least8_t;
 typedef unsigned            uint_least16_t;
 typedef unsigned long       uint_least32_t;
 
-#define INT_LEAST8_MIN      ((int_least8_t) 0x80)
-#define INT_LEAST8_MAX      ((int_least8_t) 0x7F)
-#define INT_LEAST16_MIN     ((int_least16_t) 0x8000)
-#define INT_LEAST16_MAX     ((int_least16_t) 0x7FFF)
-#define INT_LEAST32_MIN     ((int_least32_t) 0x80000000)
-#define INT_LEAST32_MAX     ((int_least32_t) 0x7FFFFFFF)
-#define UINT_LEAST8_MAX     ((uint_least8_t) 0xFF)
-#define UINT_LEAST16_MAX    ((uint_least16_t) 0xFFFF)
-#define UINT_LEAST32_MAX    ((uint_least32_t) 0xFFFFFFFF)
+#define INT_LEAST8_MIN      INT8_MIN
+#define INT_LEAST8_MAX      INT8_MAX
+#define INT_LEAST16_MIN     INT16_MIN
+#define INT_LEAST16_MAX     INT16_MAX
+#define INT_LEAST32_MIN     INT32_MIN
+#define INT_LEAST32_MAX     INT32_MAX
+#define UINT_LEAST8_MAX     UINT8_MAX
+#define UINT_LEAST16_MAX    UINT16_MAX
+#define UINT_LEAST32_MAX    UINT32_MAX
 
 /* Fastest minimum-width integer types */
 typedef signed char         int_fast8_t;
@@ -88,40 +88,40 @@ typedef unsigned char       uint_fast8_t;
 typedef unsigned            uint_fast16_t;
 typedef unsigned long       uint_fast32_t;
 
-#define INT_FAST8_MIN       ((int_fast8_t) 0x80)
-#define INT_FAST8_MAX       ((int_fast8_t) 0x7F)
-#define INT_FAST16_MIN      ((int_fast16_t) 0x8000)
-#define INT_FAST16_MAX      ((int_fast16_t) 0x7FFF)
-#define INT_FAST32_MIN      ((int_fast32_t) 0x80000000)
-#define INT_FAST32_MAX      ((int_fast32_t) 0x7FFFFFFF)
-#define UINT_FAST8_MAX      ((uint_fast8_t) 0xFF)
-#define UINT_FAST16_MAX     ((uint_fast16_t) 0xFFFF)
-#define UINT_FAST32_MAX     ((uint_fast32_t) 0xFFFFFFFF)
+#define INT_FAST8_MIN       INT8_MIN
+#define INT_FAST8_MAX       INT8_MAX
+#define INT_FAST16_MIN      INT16_MIN
+#define INT_FAST16_MAX      INT16_MAX
+#define INT_FAST32_MIN      INT32_MIN
+#define INT_FAST32_MAX      INT32_MAX
+#define UINT_FAST8_MAX      UINT8_MAX
+#define UINT_FAST16_MAX     UINT16_MAX
+#define UINT_FAST32_MAX     UINT32_MAX
 
 /* Integer types capable of holding object pointers */
 typedef int                 intptr_t;
 typedef unsigned            uintptr_t;
 
-#define INTPTR_MIN          ((intptr_t)0x8000)
-#define INTPTR_MAX          ((intptr_t)0x7FFF)
-#define UINTPTR_MAX         ((uintptr_t) 0xFFFF)
+#define INTPTR_MIN          INT16_MIN
+#define INTPTR_MAX          INT16_MAX
+#define UINTPTR_MAX         UINT16_MAX
 
 /* Greatest width integer types */
 typedef long                intmax_t;
 typedef unsigned long       uintmax_t;
 
-#define INTMAX_MIN          ((intmax_t) 0x80000000)
-#define INTMAX_MAX          ((intmax_t) 0x7FFFFFFF)
-#define UINTMAX_MAX         ((uintmax_t) 0xFFFFFFFF)
+#define INTMAX_MIN          INT32_MIN
+#define INTMAX_MAX          INT32_MAX
+#define UINTMAX_MAX         UINT32_MAX
 
 /* Limits of other integer types */
-#define PTRDIFF_MIN         ((int) 0x8000)
-#define PTRDIFF_MAX         ((int) 0x7FFF)
+#define PTRDIFF_MIN         INT16_MIN
+#define PTRDIFF_MAX         INT16_MAX
 
-#define SIG_ATOMIC_MIN      ((unsigned char) 0x00)
-#define SIG_ATOMIC_MAX      ((unsigned char) 0xFF)
+#define SIG_ATOMIC_MIN      0
+#define SIG_ATOMIC_MAX      UINT8_MAX
 
-#define SIZE_MAX            0xFFFF
+#define SIZE_MAX            UINT16_MAX
 
 /* Macros for minimum width integer constants */
 #define INT8_C(c)           c
diff --git a/test/val/stdint.c b/test/val/stdint.c
new file mode 100644
index 000000000..29b48346a
--- /dev/null
+++ b/test/val/stdint.c
@@ -0,0 +1,167 @@
+/* Test definitions from stdint.h */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <signal.h>
+
+/* All macros from stdint.h must be evaluatable by the preprocessor */
+#if INT8_MIN
+#endif
+#if INT8_MAX
+#endif
+#if INT16_MIN
+#endif
+#if INT16_MAX
+#endif
+#if INT32_MIN
+#endif
+#if INT32_MAX
+#endif
+#if UINT8_MAX
+#endif
+#if UINT16_MAX
+#endif
+#if UINT32_MAX
+#endif
+#if INT_LEAST8_MIN
+#endif
+#if INT_LEAST8_MAX
+#endif
+#if INT_LEAST16_MIN
+#endif
+#if INT_LEAST16_MAX
+#endif
+#if INT_LEAST32_MIN
+#endif
+#if INT_LEAST32_MAX
+#endif
+#if UINT_LEAST8_MAX
+#endif
+#if UINT_LEAST16_MAX
+#endif
+#if UINT_LEAST32_MAX
+#endif
+#if INT_FAST8_MIN
+#endif
+#if INT_FAST8_MAX
+#endif
+#if INT_FAST16_MIN
+#endif
+#if INT_FAST16_MAX
+#endif
+#if INT_FAST32_MIN
+#endif
+#if INT_FAST32_MAX
+#endif
+#if UINT_FAST8_MAX
+#endif
+#if UINT_FAST16_MAX
+#endif
+#if UINT_FAST32_MAX
+#endif
+#if INTPTR_MIN
+#endif
+#if INTPTR_MAX
+#endif
+#if UINTPTR_MAX
+#endif
+#if INTMAX_MIN
+#endif
+#if INTMAX_MAX
+#endif
+#if UINTMAX_MAX
+#endif
+#if PTRDIFF_MIN
+#endif
+#if PTRDIFF_MAX
+#endif
+#if SIG_ATOMIC_MIN
+#endif
+#if SIG_ATOMIC_MAX
+#endif
+#if SIZE_MAX
+#endif
+
+#define SMIN(type)      ((type)(1L << (sizeof(type) * CHAR_BIT - 1)))
+#define SMAX(type)      ((type)(~SMIN(type)))
+#define UMAX(type)      ((type)(~(type)0))
+
+#define SMIN_CHECK(type, val)                                           \
+    if (SMIN(type) != val) {                                            \
+        ++failures;                                                     \
+        printf("Mismatch for %s, minimum (%ld) is not %s (%ld)\n",      \
+               #type, (long)SMIN(type), #val, (long)val);               \
+    }
+#define SMAX_CHECK(type, val)                                           \
+    if (SMAX(type) != val) {                                            \
+        ++failures;                                                     \
+        printf("Mismatch for %s, maximum (%ld) is not %s (%ld)\n",      \
+               #type, (long)SMAX(type), #val, (long)val);               \
+    }
+#define UMAX_CHECK(type, val)                                           \
+    if (UMAX(type) != val) {                                            \
+        ++failures;                                                     \
+        printf("Mismatch for %s, maximum (%lu) is not %s (%lu)\n",      \
+               #type, (unsigned long)UMAX(type), #val,                  \
+               (unsigned long)val);                                     \
+    }
+
+static unsigned failures = 0;
+
+int main()
+{
+    SMIN_CHECK(int8_t, INT8_MIN);
+    SMAX_CHECK(int8_t, INT8_MAX);
+    SMIN_CHECK(int16_t, INT16_MIN);
+    SMAX_CHECK(int16_t, INT16_MAX);
+    SMIN_CHECK(int32_t, INT32_MIN);
+    SMAX_CHECK(int32_t, INT32_MAX);
+    UMAX_CHECK(uint8_t, UINT8_MAX);
+    UMAX_CHECK(uint16_t, UINT16_MAX);
+    UMAX_CHECK(uint32_t, UINT32_MAX);
+
+    SMIN_CHECK(int_least8_t, INT_LEAST8_MIN);
+    SMAX_CHECK(int_least8_t, INT_LEAST8_MAX);
+    SMIN_CHECK(int_least16_t, INT_LEAST16_MIN);
+    SMAX_CHECK(int_least16_t, INT_LEAST16_MAX);
+    SMIN_CHECK(int_least32_t, INT_LEAST32_MIN);
+    SMAX_CHECK(int_least32_t, INT_LEAST32_MAX);
+    UMAX_CHECK(uint_least8_t, UINT_LEAST8_MAX);
+    UMAX_CHECK(uint_least16_t, UINT_LEAST16_MAX);
+    UMAX_CHECK(uint_least32_t, UINT_LEAST32_MAX);
+
+    SMIN_CHECK(int_fast8_t, INT_FAST8_MIN);
+    SMAX_CHECK(int_fast8_t, INT_FAST8_MAX);
+    SMIN_CHECK(int_fast16_t, INT_FAST16_MIN);
+    SMAX_CHECK(int_fast16_t, INT_FAST16_MAX);
+    SMIN_CHECK(int_fast32_t, INT_FAST32_MIN);
+    SMAX_CHECK(int_fast32_t, INT_FAST32_MAX);
+    UMAX_CHECK(uint_fast8_t, UINT_FAST8_MAX);
+    UMAX_CHECK(uint_fast16_t, UINT_FAST16_MAX);
+    UMAX_CHECK(uint_fast32_t, UINT_FAST32_MAX);
+
+    SMIN_CHECK(intptr_t, INTPTR_MIN);
+    SMAX_CHECK(intptr_t, INTPTR_MAX);
+    UMAX_CHECK(uintptr_t, UINTPTR_MAX);
+
+    SMIN_CHECK(intmax_t, INTMAX_MIN);
+    SMAX_CHECK(intmax_t, INTMAX_MAX);
+    UMAX_CHECK(uintmax_t, UINTMAX_MAX);
+
+    SMIN_CHECK(ptrdiff_t, PTRDIFF_MIN);
+    SMAX_CHECK(ptrdiff_t, PTRDIFF_MAX);
+
+#if SIG_ATOMIC_MIN < 0
+    SMIN_CHECK(sig_atomic_t, SIG_ATOMIC_MIN);
+    SMAX_CHECK(sig_atomic_t, SIG_ATOMIC_MAX);
+#else
+    UMAX_CHECK(sig_atomic_t, SIG_ATOMIC_MAX);
+#endif
+
+    UMAX_CHECK(size_t, SIZE_MAX);
+
+    return failures;
+}