diff --git a/library/TextBuilder/Domains/Digits.hs b/library/TextBuilder/Domains/Digits.hs
--- a/library/TextBuilder/Domains/Digits.hs
+++ b/library/TextBuilder/Domains/Digits.hs
@@ -147,11 +147,20 @@
 -- * Signed Numbers
 
 {-# INLINE signed #-}
-signed :: (Ord a, Num a) => (a -> TextBuilder) -> a -> TextBuilder
-signed onUnsigned i =
-  if i >= 0
-    then onUnsigned i
-    else unicodeCodepoint 45 <> onUnsigned (negate i)
+signed :: (Integral a) => (forall a. (Integral a) => a -> TextBuilder) -> a -> TextBuilder
+signed onUnsigned a =
+  if a >= 0
+    then onUnsigned a
+    else
+      unicodeCodepoint 45
+        <> let negated = negate a
+            in if negated /= a
+                 then onUnsigned negated
+                 else
+                   -- This is a special case for the minimum value of signed types.
+                   -- The negation of the minimum value is not representable in the same type.
+                   -- For example, for Int8, -128 is not representable as a positive number.
+                   onUnsigned (negate (fromIntegral a :: Integer))
 
 -- | Signed decimal representation of an integer.
 --
@@ -163,7 +172,13 @@
 --
 -- >>> decimal 0
 -- "0"
-{-# INLINEABLE decimal #-}
+--
+-- >>> decimal (-2 :: Int8)
+-- "-2"
+--
+-- >>> decimal (-128 :: Int8)
+-- "-128"
+{-# INLINE decimal #-}
 decimal :: (Integral a) => a -> TextBuilder
 decimal = signed unsignedDecimal
 
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -33,12 +33,34 @@
     testGroup "Functions" $
       [ testGroup "decimal" $
           [ testGroup "Int" $
-              [ mapsToMonoid @Int decimal
+              [ mapsToMonoid @Int decimal,
+                testProperty "Encodes the same as show" $ \(x :: Int) ->
+                  (fromString . show) x === toText (decimal x)
               ],
+            testGroup "Int8" $
+              [ mapsToMonoid @Int8 decimal,
+                testProperty "Encodes the same as show" $ \(x :: Int8) ->
+                  (fromString . show) x === toText (decimal x)
+              ],
+            testGroup "Word" $
+              [ mapsToMonoid @Word decimal,
+                testProperty "Encodes the same as show" $ \(x :: Word) ->
+                  (fromString . show) x === toText (decimal x)
+              ],
+            testGroup "Word8" $
+              [ mapsToMonoid @Word8 decimal,
+                testProperty "Encodes the same as show" $ \(x :: Word8) ->
+                  (fromString . show) x === toText (decimal x)
+              ],
             testGroup "Integer" $
               [ mapsToMonoid @Integer decimal,
                 testProperty "Encodes the same as show" $ \(x :: Integer) ->
-                  (fromString . show) x === (toText (decimal x))
+                  (fromString . show) x === toText (decimal x)
+              ],
+            testGroup "Natural" $
+              [ mapsToMonoid @Natural decimal,
+                testProperty "Encodes the same as show" $ \(x :: Natural) ->
+                  (fromString . show) x === toText (decimal x)
               ]
           ],
         testGroup "fixedLengthDecimal" $
@@ -61,10 +83,19 @@
           ],
         testGroup "thousandSeparatedDecimal" $
           [ testGroup "Int" $
-              [ mapsToMonoid @Int (thousandSeparatedDecimal ',')
+              [ mapsToMonoid @Int (thousandSeparatedDecimal ','),
+                testProperty "Encodes the same as show" $ \(x :: Int) ->
+                  (fromString . show) x === Text.filter (/= ',') (toText (thousandSeparatedDecimal ',' x))
               ],
+            testGroup "Int8" $
+              [ mapsToMonoid @Int8 (thousandSeparatedDecimal ','),
+                testProperty "Encodes the same as show" $ \(x :: Int8) ->
+                  (fromString . show) x === Text.filter (/= ',') (toText (thousandSeparatedDecimal ',' x))
+              ],
             testGroup "Integer" $
-              [ mapsToMonoid @Integer (thousandSeparatedDecimal ',')
+              [ mapsToMonoid @Integer (thousandSeparatedDecimal ','),
+                testProperty "Encodes the same as show" $ \(x :: Integer) ->
+                  (fromString . show) x === Text.filter (/= ',') (toText (thousandSeparatedDecimal ',' x))
               ]
           ],
         testGroup "binary" $
diff --git a/text-builder.cabal b/text-builder.cabal
--- a/text-builder.cabal
+++ b/text-builder.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: text-builder
-version: 1.0.0.2
+version: 1.0.0.3
 category: Text, Builders
 synopsis: Efficient and flexible strict text builder
 description:
