diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+v0.4	better sin, cos, tan
+v0.3.1	use complex-generic
 v0.2.1	fixed point
 v0.2	generic IEEE-ish
 v0.1.1	fixed for ghc-7.0.4
diff --git a/Numeric/VariablePrecision/Algorithms.hs b/Numeric/VariablePrecision/Algorithms.hs
--- a/Numeric/VariablePrecision/Algorithms.hs
+++ b/Numeric/VariablePrecision/Algorithms.hs
@@ -44,6 +44,7 @@
   , genericLog2
   , genericLog''
   , genericPi
+  , genericSin
   , genericPositiveZero
   , genericNegativeZero
   , genericPositiveInfinity
@@ -53,7 +54,7 @@
   ) where
 
 import Data.Bits (bit, shiftR)
-
+import Data.List (foldl')
 
 -- | Special values implemented using basic RealFloat functionality.
 genericPositiveZero, genericNegativeZero, genericPositiveInfinity, genericNegativeInfinity, genericNotANumber :: RealFloat a => a
@@ -291,6 +292,47 @@
         k' = k + 1
         p' = scaleFloat (-2) (sqr (a + b) / t)
 
+
+-- | Compute 'sin' using the method described in section 3 of
+--   /Efficient multiple-precision evaluation of elementary functions/
+--   David M Smith, 1989,
+--   <http://digitalcommons.lmu.edu/math_fac/1/>
+--
+--   Requires a value for pi.
+--
+--   Uses basic RealFloat functionality, '(/)', and sqrt.
+genericSin :: RealFloat a => Int {-^ accuracy -} -> a {-^ pi -} -> a {-^ x -} -> a
+genericSin accuracy pi x0 = reduced taylor x0
+  where
+    sqr y = y * y
+    t :: Double
+    t = fromIntegral (floatDigits x0 - accuracy)
+    k :: Int
+    k = round (t / 3)
+    three = 3 ^ k
+    up 0 !y = y
+    up n !y = up (n - 1) (y * (3 - scaleFloat 2 (sqr y)))
+    reduced f y
+      | y == 0      = y
+      | y <  0      = (negate . reduced f . negate) y
+      | y <= pi / 4 = (up k . f . (/ three)) y
+      | y <= pi / 2 = (sqrt . (1 -) . sqr . reduced f . (pi / 2 -)) y
+      | y <= pi     = (reduced f . (pi -)) y
+      | y <= pi * 2 = (negate . reduced f . (pi * 2 -)) y
+      | otherwise = (reduced f . subtract (pi * 2)) y
+    taylor y = (sum' . reverse . takeWhile ((> threshold) . abs) . go 1) y
+      where
+        threshold = scaleFloat (negate (floatDigits y * 2)) y
+        x2 = sqr y
+        go !n !xnf = xnf : go n' xnf'
+          where
+            n' = n + 1
+            xnf' = negate (x2 * xnf / fromInt (2 * n + 1))
+    fromInt :: Num a => Int -> a
+    fromInt = fromIntegral
+
+sum' :: Num a => [a] -> a
+sum' = foldl' (+) 0
 
 -- | Lift a function from Double to generic 'RealFloat' types.
 viaDouble :: (RealFloat a, RealFloat b) => (Double -> Double) -> a -> b
diff --git a/Numeric/VariablePrecision/Float.hs b/Numeric/VariablePrecision/Float.hs
--- a/Numeric/VariablePrecision/Float.hs
+++ b/Numeric/VariablePrecision/Float.hs
@@ -62,13 +62,13 @@
 --
 --     * 'exp',
 --
---     * 'log'.
+--     * 'log',
 --
+--     * 'sin', 'cos', 'tan'.
+--
 --   These 'Floating' methods transit via 'Double' and so have limited
 --   precision:
 --
---     * 'sin', 'cos', 'tan',
---
 --     * 'asin', 'acos', 'atan',
 --
 --     * 'sinh', 'cosh', 'tanh',
@@ -344,7 +344,7 @@
         | otherwise = (fromInteger n', f')
         where
           n = m `shiftR` (negate e)
-          d = checkVFloat "properFraction" $ F (n `shiftL` (negate e)) e
+          d = encodeVFloat (asTypeIn self) (n `shiftL` (negate e)) e
           f = me - d
           (n', f')
             | (m >= 0) == (f >= 0) = (n, f)
@@ -440,11 +440,11 @@
 
   -- 'logBase' uses default implementation in Floating
 
-  sin = viaDouble sin -- FIXME
+  sin = genericSin 2 pi
 
-  cos = viaDouble cos -- FIXME
+  cos x = sin (x + pi/2)
 
-  tan = viaDouble tan -- FIXME
+  tan x = sin x / cos x
 
   sinh = viaDouble sinh -- FIXME
 
diff --git a/variable-precision.cabal b/variable-precision.cabal
--- a/variable-precision.cabal
+++ b/variable-precision.cabal
@@ -1,10 +1,11 @@
 Name:                variable-precision
-Version:             0.3.1
+Version:             0.4
 Synopsis:            variable-precision floating point
 Description:
   Software floating point with type-tagged variable mantissa precision,
   implemented using a strict pair of 'Integer' and 'Int' scaled alike
-  to 'decodeFloat'.  Version 0.2.1 added a fixed point number type.
+  to 'decodeFloat'.  Version 0.4 adds more number-type-agnostic numerical
+  algorithms ('sin', 'cos', 'tan').
   .
   Instances of the usual numeric type classes are provided, along with
   additional operators (with carefully chosen fixities) to coerce,
@@ -72,4 +73,4 @@
 source-repository this
   type:     git
   location: git://gitorious.org/variable-precision/variable-precision.git
-  tag:      v0.3.1
+  tag:      v0.4
