diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Revision history for pa-field-parser
 
+## 0.3.1.0 -- 2024-09-04
+
+- Improve `boundedScientificIntegral`
+
 ## 0.3.0.0 -- 2023-10-15
 
 - rename `jsonParser` to `toJsonParser`
diff --git a/pa-field-parser.cabal b/pa-field-parser.cabal
--- a/pa-field-parser.cabal
+++ b/pa-field-parser.cabal
@@ -1,7 +1,7 @@
 cabal-version:      3.0
 -- !!! ATTN: file autogenerated from pa-template.cabal.mustache on toplevel !!!
 name:               pa-field-parser
-version:            0.3.0.0
+version:            0.3.1.0
 synopsis:           “Vertical” parsing of values
 description:        
 license:            BSD-3-Clause
@@ -60,6 +60,10 @@
 
     -- to enable the `type` keyword in import lists (ormolu uses this automatically)
     ExplicitNamespaces
+
+    -- allows defining pattern synonyms, but also the `import Foo (pattern FooPattern)` import syntax
+    PatternSynonyms
+
 
   default-language: GHC2021
 
diff --git a/src/FieldParser.hs b/src/FieldParser.hs
--- a/src/FieldParser.hs
+++ b/src/FieldParser.hs
@@ -212,10 +212,19 @@
 -- (e.g. 64 bits via @Int@) and then go from that to the unbounded type (e.g. via 'integralToNatural').
 --
 -- @err@ is added as context around the bounded error.
-boundedScientificIntegral :: forall i. (Integral i, Bounded i) => Error -> FieldParser Scientific i
-boundedScientificIntegral err = FieldParser $ \s -> case Scientific.toBoundedInteger s of
-  Nothing -> Left $ (err & errorContext [fmt|Must be between {iMinBound} and {iMaxBound}|])
-  Just i -> Right i
+boundedScientificIntegral ::
+  forall i.
+  (Integral i, Bounded i) =>
+  Error ->
+  FieldParser Scientific i
+boundedScientificIntegral err = FieldParser $ \s ->
+  -- we check for isFloating first, because @toBoundedInteger@ returns `Nothing` if the number is floating as well as out of bound
+  if Scientific.isFloating s
+    then Left $ (err & errorContext [fmt|Must be a natural number, but was a floating point number: {show s}|])
+    else case Scientific.toBoundedInteger s of
+      Nothing ->
+        Left $ (err & errorContext [fmt|Must be between {iMinBound} and {iMaxBound}, but was: {show s}|])
+      Just i -> Right i
   where
     iMinBound = toInteger (minBound :: i)
     iMaxBound = toInteger (maxBound :: i)
@@ -232,9 +241,9 @@
     & first
       ( \zeroOrInf ->
           ( if
-                | 0 == zeroOrInf -> [fmt|Number {show s} is too small to fit into floating point.|]
-                | isInfinite zeroOrInf -> [fmt|Number {show s} is too big to fit into floating point.|]
-                | otherwise -> [fmt|Number {show s} did not fit into floating point, but we don’t know why (BUG).|]
+              | 0 == zeroOrInf -> [fmt|Number {show s} is too small to fit into floating point.|]
+              | isInfinite zeroOrInf -> [fmt|Number {show s} is too big to fit into floating point.|]
+              | otherwise -> [fmt|Number {show s} did not fit into floating point, but we don’t know why (BUG).|]
           )
       )
 
