fenv: Add appropriate #ifdef's to rounding direction helpers.
authorNick Bowler <nbowler@draconx.ca>
Wed, 13 Oct 2010 22:38:54 +0000 (13 18:38 -0400)
committerNick Bowler <nbowler@draconx.ca>
Wed, 13 Oct 2010 22:38:54 +0000 (13 18:38 -0400)
An implementation need not support all of the rounding modes, so only
compile in support for those that are available.

Data/Floating/Environment.hs
cfloat.c

index c90ee11..ccc38d8 100644 (file)
@@ -70,10 +70,14 @@ import Debug.Trace
 import Foreign.C
 import Foreign
 
-foreign import ccall unsafe "set_roundmode"
-    set_roundmode :: CInt -> IO CInt
-foreign import ccall unsafe "get_roundmode"
-    get_roundmode :: IO CInt
+foreign import ccall unsafe "fenv_set_roundmode"
+    fenv_set_roundmode :: CInt -> IO CInt
+foreign import ccall unsafe "fenv_get_roundmode"
+    fenv_get_roundmode :: IO CInt
+foreign import ccall unsafe "fenv_test_excepts"
+    fenv_test_excepts :: IO CUInt
+foreign import ccall unsafe "fenv_raise_excepts"
+    fenv_raise_excepts :: CUInt -> IO CInt
 
 foreign import ccall unsafe "fegetenv"
     c_fegetenv :: Ptr FEnvState -> IO CInt
@@ -81,10 +85,6 @@ foreign import ccall unsafe "fesetenv"
     c_fesetenv :: Ptr FEnvState -> IO CInt
 foreign import ccall unsafe "feholdexcept"
     c_feholdexcept :: Ptr FEnvState -> IO CInt
-foreign import ccall unsafe "fenv_test_excepts"
-    fenv_test_excepts :: IO CUInt
-foreign import ccall unsafe "fenv_raise_excepts"
-    fenv_raise_excepts :: CUInt -> IO CInt
 
 data RoundingMode = ToNearest | Upward | Downward | TowardZero
     deriving (Show, Read, Enum, Bounded)
@@ -227,12 +227,12 @@ unsafeRaiseExceptions ex = do
 
 unsafeSetRoundingMode :: RoundingMode -> IO ()
 unsafeSetRoundingMode mode = do
-    rc <- set_roundmode (fromIntegral (fromEnum mode))
+    rc <- fenv_set_roundmode (fromIntegral (fromEnum mode))
     unless (rc == 0) $ fail "Error setting rounding mode"
 
 getRoundingMode :: IO RoundingMode
 getRoundingMode = do
-    rc <- get_roundmode
+    rc <- fenv_get_roundmode
     unless (rc >= 0) $ fail "Error getting rounding mode"
     return . toEnum . fromIntegral $ rc
 
index 58af4b9..6fd13d5 100644 (file)
--- a/cfloat.c
+++ b/cfloat.c
@@ -104,23 +104,31 @@ int float_compare(float a, float b)
        return -1;
 }
 
-int set_roundmode(int mode)
+int fenv_set_roundmode(int mode)
 {
        int cmode;
 
        switch (mode) {
+#ifdef FE_TONEAREST
        case 0:
                cmode = FE_TONEAREST;
                break;
+#endif
+#ifdef FE_UPWARD
        case 1:
                cmode = FE_UPWARD;
                break;
+#endif
+#ifdef FE_DOWNWARD
        case 2:
                cmode = FE_DOWNWARD;
                break;
+#endif
+#ifdef FE_TOWARDZERO
        case 3:
                cmode = FE_TOWARDZERO;
                break;
+#endif
        default:
                return -1;
        }
@@ -128,19 +136,27 @@ int set_roundmode(int mode)
        return fesetround(cmode);
 }
 
-int get_roundmode(void)
+int fenv_get_roundmode(void)
 {
        int cmode = fegetround();
 
        switch (cmode) {
+#ifdef FE_TONEAREST
        case FE_TONEAREST:
                return 0;
+#endif
+#ifdef FE_UPWARD
        case FE_UPWARD:
                return 1;
+#endif
+#ifdef FE_DOWNWARD
        case FE_DOWNWARD:
                return 2;
+#endif
+#ifdef FE_TOWARDZERO
        case FE_TOWARDZERO:
                return 3;
+#endif
        default:
                return -1;
        }