diff --git a/amount.go b/amount.go
new file mode 100644
index 0000000..d14b97a
--- /dev/null
+++ b/amount.go
@@ -0,0 +1,94 @@
+// Copyright (c) 2013, 2014 Conformal Systems LLC.
+// Use of this source code is governed by an ISC
+// license that can be found in the LICENSE file.
+
+package btcutil
+
+import (
+	"errors"
+	"math"
+	"strconv"
+)
+
+// AmountUnit describes a method of converting an Amount to something
+// other than the base unit of a bitcoin.  The value of the AmountUnit
+// is the exponent component of the decadic multiple to convert from
+// an amount in bitcoin to an amount counted in units.
+type AmountUnit int
+
+// These constants define the various standard units used when describing
+// a bitcoin monetary amount.
+const (
+	AmountMegaBitcoin  AmountUnit = 6
+	AmountKiloBitcoin  AmountUnit = 3
+	AmountBitcoin      AmountUnit = 0
+	AmountMilliBitcoin AmountUnit = -3
+	AmountMicroBitcoin AmountUnit = -6
+	AmountBaseBitcoin  AmountUnit = -8
+)
+
+// String returns the unit as a string.  For recognized units, the SI
+// prefix is used, or "Satoshi" for the base unit.  For all unrecognized
+// units, "1eN BTC" is returned, where N is the AmountUnit.
+func (u AmountUnit) String() string {
+	switch u {
+	case AmountMegaBitcoin:
+		return "MBTC"
+	case AmountKiloBitcoin:
+		return "kBTC"
+	case AmountBitcoin:
+		return "BTC"
+	case AmountMilliBitcoin:
+		return "mBTC"
+	case AmountMicroBitcoin:
+		return "μBTC"
+	case AmountBaseBitcoin:
+		return "Satoshi"
+	default:
+		return "1e" + strconv.FormatInt(int64(u), 10) + " BTC"
+	}
+}
+
+// Amount represents the base bitcoin monetary unit (colloquially referred
+// to as a `Satoshi').  A single Amount is equal to 1e-8 of a bitcoin.
+type Amount int64
+
+// NewAmount creates an Amount from a floating point value representing
+// some value in bitcoin.
+func NewAmount(f float64) (Amount, error) {
+	a := f * float64(SatoshiPerBitcoin)
+
+	// The amount is only valid if it does not exceed the total amount
+	// of bitcoin producable, and is not a floating point number that
+	// would otherwise fail that check such as NaN or +-Inf.
+	switch abs := math.Abs(a); {
+	case abs > float64(MaxSatoshi):
+		fallthrough
+	case math.IsNaN(abs) || math.IsInf(abs, 1):
+		return 0, errors.New("invalid bitcoin amount")
+	}
+
+	// Depending on the sign, add or subtract 0.5 and rely on integer
+	// truncation to correctly round the value up or down.
+	if a < 0 {
+		a = a - 0.5
+	} else {
+		a = a + 0.5
+	}
+	return Amount(a), nil
+}
+
+// ToUnit converts a monetary amount counted in bitcoin base units to a
+// floating point value representing an amount of bitcoin.
+func (a Amount) ToUnit(u AmountUnit) float64 {
+	return float64(a) / math.Pow10(int(u+8))
+}
+
+// Format formats a monetary amount counted in bitcoin base units as a
+// string for a given unit.  The conversion will succeed for any unit,
+// however, known units will be formated with an appended label describing
+// the units with SI notation.
+func (a Amount) Format(u AmountUnit) string {
+	units := " " + u.String()
+	return strconv.FormatFloat(a.ToUnit(u), 'f', -int(u+8), 64) + units
+}
diff --git a/amount_test.go b/amount_test.go
new file mode 100644
index 0000000..f6d6d79
--- /dev/null
+++ b/amount_test.go
@@ -0,0 +1,183 @@
+// Copyright (c) 2013, 2014 Conformal Systems LLC.
+// Use of this source code is governed by an ISC
+// license that can be found in the LICENSE file.
+
+package btcutil_test
+
+import (
+	. "github.com/conformal/btcutil"
+	"math"
+	"testing"
+)
+
+func TestAmountCreation(t *testing.T) {
+	tests := []struct {
+		name     string
+		amount   float64
+		valid    bool
+		expected Amount
+	}{
+		// Positive tests.
+		{
+			name:     "zero",
+			amount:   0,
+			valid:    true,
+			expected: 0,
+		},
+		{
+			name:     "max",
+			amount:   21e6,
+			valid:    true,
+			expected: Amount(MaxSatoshi),
+		},
+		{
+			name:     "min",
+			amount:   -21e6,
+			valid:    true,
+			expected: Amount(-MaxSatoshi),
+		},
+		{
+			name:     "one hundred",
+			amount:   100,
+			valid:    true,
+			expected: Amount(100 * SatoshiPerBitcoin),
+		},
+		{
+			name:     "fraction",
+			amount:   0.01234567,
+			valid:    true,
+			expected: Amount(1234567),
+		},
+		{
+			name:     "rounding up",
+			amount:   54.999999999999943157,
+			valid:    true,
+			expected: Amount(55 * SatoshiPerBitcoin),
+		},
+		{
+			name:     "rounding down",
+			amount:   55.000000000000056843,
+			valid:    true,
+			expected: Amount(55 * SatoshiPerBitcoin),
+		},
+
+		// Negative tests.
+		{
+			name:   "exceeds max",
+			amount: 21e6 + 1,
+			valid:  false,
+		},
+		{
+			name:   "exceeds min",
+			amount: -21e6 - 1,
+			valid:  false,
+		},
+		{
+			name:   "not-a-number",
+			amount: math.NaN(),
+			valid:  false,
+		},
+		{
+			name:   "-infinity",
+			amount: math.Inf(-1),
+			valid:  false,
+		},
+		{
+			name:   "+infinity",
+			amount: math.Inf(1),
+			valid:  false,
+		},
+	}
+
+	for _, test := range tests {
+		a, err := NewAmount(test.amount)
+		switch {
+		case test.valid && err != nil:
+			t.Errorf("%v: Positive test Amount creation failed with: %v", test.name, err)
+			continue
+		case !test.valid && err == nil:
+			t.Errorf("%v: Negative test Amount creation succeeded (value %v) when should fail", test.name, a)
+			continue
+		}
+
+		if a != test.expected {
+			t.Errorf("%v: Created amount %v does not match expected %v", test.name, a, test.expected)
+		}
+	}
+}
+
+func TestAmountUnitConversions(t *testing.T) {
+	tests := []struct {
+		name      string
+		amount    Amount
+		unit      AmountUnit
+		converted float64
+		s         string
+	}{
+		{
+			name:      "MBTC",
+			amount:    Amount(MaxSatoshi),
+			unit:      AmountMegaBitcoin,
+			converted: 21,
+			s:         "21 MBTC",
+		},
+		{
+			name:      "kBTC",
+			amount:    Amount(44433322211100),
+			unit:      AmountKiloBitcoin,
+			converted: 444.33322211100,
+			s:         "444.333222111 kBTC",
+		},
+		{
+			name:      "BTC",
+			amount:    Amount(44433322211100),
+			unit:      AmountBitcoin,
+			converted: 444333.22211100,
+			s:         "444333.222111 BTC",
+		},
+		{
+			name:      "mBTC",
+			amount:    Amount(44433322211100),
+			unit:      AmountMilliBitcoin,
+			converted: 444333222.11100,
+			s:         "444333222.111 mBTC",
+		},
+		{
+
+			name:      "μBTC",
+			amount:    Amount(44433322211100),
+			unit:      AmountMicroBitcoin,
+			converted: 444333222111.00,
+			s:         "444333222111 μBTC",
+		},
+		{
+
+			name:      "satoshi",
+			amount:    Amount(44433322211100),
+			unit:      AmountBaseBitcoin,
+			converted: 44433322211100,
+			s:         "44433322211100 Satoshi",
+		},
+		{
+
+			name:      "non-standard unit",
+			amount:    Amount(44433322211100),
+			unit:      AmountUnit(-1),
+			converted: 4443332.2211100,
+			s:         "4443332.22111 1e-1 BTC",
+		},
+	}
+
+	for _, test := range tests {
+		f := test.amount.ToUnit(test.unit)
+		if f != test.converted {
+			t.Errorf("%v: converted value %v does not match expected %v", test.name, f, test.converted)
+			continue
+		}
+
+		s := test.amount.Format(test.unit)
+		if s != test.s {
+			t.Errorf("%v: format '%v' does not match expected '%v'", test.name, s, test.s)
+		}
+	}
+}
diff --git a/test_coverage.txt b/test_coverage.txt
index 7b99711..41764c6 100644
--- a/test_coverage.txt
+++ b/test_coverage.txt
@@ -4,32 +4,36 @@ github.com/conformal/btcutil/base58.go	 Base58Encode			 100.00% (15/15)
 github.com/conformal/btcutil/block.go	 Block.Tx			 100.00% (12/12)
 github.com/conformal/btcutil/block.go	 Block.Transactions		 100.00% (11/11)
 github.com/conformal/btcutil/address.go	 encodeAddress			 100.00% (9/9)
-github.com/conformal/btcutil/tx.go	 NewTxFromBytes			 100.00% (7/7)
+github.com/conformal/btcutil/amount.go	 AmountUnit.String		 100.00% (8/8)
+github.com/conformal/btcutil/amount.go	 NewAmount			 100.00% (8/8)
 github.com/conformal/btcutil/block.go	 NewBlockFromBytes		 100.00% (7/7)
-github.com/conformal/btcutil/block.go	 Block.Sha			 100.00% (5/5)
+github.com/conformal/btcutil/tx.go	 NewTxFromBytes			 100.00% (7/7)
 github.com/conformal/btcutil/tx.go	 Tx.Sha				 100.00% (5/5)
+github.com/conformal/btcutil/block.go	 Block.Sha			 100.00% (5/5)
+github.com/conformal/btcutil/amount.go	 Amount.Format			 100.00% (2/2)
 github.com/conformal/btcutil/address.go	 NewAddressScriptHash		 100.00% (2/2)
 github.com/conformal/btcutil/hash160.go	 calcHash			 100.00% (2/2)
-github.com/conformal/btcutil/address.go	 AddressScriptHash.ScriptAddress 100.00% (1/1)
-github.com/conformal/btcutil/address.go	 AddressPubKey.EncodeAddress	 100.00% (1/1)
-github.com/conformal/btcutil/address.go	 AddressScriptHash.String	 100.00% (1/1)
-github.com/conformal/btcutil/tx.go	 Tx.MsgTx			 100.00% (1/1)
-github.com/conformal/btcutil/address.go	 AddressPubKeyHash.String	 100.00% (1/1)
-github.com/conformal/btcutil/tx.go	 Tx.SetIndex			 100.00% (1/1)
-github.com/conformal/btcutil/address.go	 AddressPubKey.ScriptAddress	 100.00% (1/1)
-github.com/conformal/btcutil/address.go	 AddressPubKey.String		 100.00% (1/1)
-github.com/conformal/btcutil/address.go	 AddressPubKeyHash.ScriptAddress 100.00% (1/1)
-github.com/conformal/btcutil/block.go	 NewBlock			 100.00% (1/1)
-github.com/conformal/btcutil/block.go	 Block.SetHeight		 100.00% (1/1)
-github.com/conformal/btcutil/block.go	 Block.Height			 100.00% (1/1)
 github.com/conformal/btcutil/hash160.go	 Hash160			 100.00% (1/1)
 github.com/conformal/btcutil/address.go	 AddressPubKeyHash.EncodeAddress 100.00% (1/1)
-github.com/conformal/btcutil/tx.go	 NewTx				 100.00% (1/1)
-github.com/conformal/btcutil/block.go	 NewBlockFromBlockAndBytes	 100.00% (1/1)
+github.com/conformal/btcutil/address.go	 AddressPubKeyHash.ScriptAddress 100.00% (1/1)
+github.com/conformal/btcutil/address.go	 AddressPubKeyHash.String	 100.00% (1/1)
 github.com/conformal/btcutil/address.go	 AddressScriptHash.EncodeAddress 100.00% (1/1)
-github.com/conformal/btcutil/tx.go	 Tx.Index			 100.00% (1/1)
+github.com/conformal/btcutil/address.go	 AddressScriptHash.ScriptAddress 100.00% (1/1)
+github.com/conformal/btcutil/address.go	 AddressScriptHash.String	 100.00% (1/1)
+github.com/conformal/btcutil/address.go	 AddressPubKey.EncodeAddress	 100.00% (1/1)
+github.com/conformal/btcutil/address.go	 AddressPubKey.ScriptAddress	 100.00% (1/1)
+github.com/conformal/btcutil/address.go	 AddressPubKey.String		 100.00% (1/1)
+github.com/conformal/btcutil/amount.go	 Amount.ToUnit			 100.00% (1/1)
 github.com/conformal/btcutil/block.go	 OutOfRangeError.Error		 100.00% (1/1)
 github.com/conformal/btcutil/block.go	 Block.MsgBlock			 100.00% (1/1)
+github.com/conformal/btcutil/block.go	 Block.Height			 100.00% (1/1)
+github.com/conformal/btcutil/block.go	 Block.SetHeight		 100.00% (1/1)
+github.com/conformal/btcutil/block.go	 NewBlock			 100.00% (1/1)
+github.com/conformal/btcutil/block.go	 NewBlockFromBlockAndBytes	 100.00% (1/1)
+github.com/conformal/btcutil/tx.go	 Tx.MsgTx			 100.00% (1/1)
+github.com/conformal/btcutil/tx.go	 Tx.Index			 100.00% (1/1)
+github.com/conformal/btcutil/tx.go	 Tx.SetIndex			 100.00% (1/1)
+github.com/conformal/btcutil/tx.go	 NewTx				 100.00% (1/1)
 github.com/conformal/btcutil/address.go	 DecodeAddress			 95.65% (22/23)
 github.com/conformal/btcutil/appdata.go	 appDataDir			 92.00% (23/25)
 github.com/conformal/btcutil/address.go	 NewAddressPubKeyHash		 91.67% (11/12)
@@ -38,17 +42,17 @@ github.com/conformal/btcutil/address.go	 EncodePrivateKey		 90.91% (20/22)
 github.com/conformal/btcutil/block.go	 Block.TxLoc			 88.89% (8/9)
 github.com/conformal/btcutil/block.go	 Block.Bytes			 88.89% (8/9)
 github.com/conformal/btcutil/address.go	 AddressPubKey.serialize	 85.71% (6/7)
+github.com/conformal/btcutil/address.go	 DecodePrivateKey		 83.33% (20/24)
 github.com/conformal/btcutil/address.go	 NewAddressPubKey		 83.33% (15/18)
 github.com/conformal/btcutil/address.go	 checkBitcoinNet		 83.33% (5/6)
-github.com/conformal/btcutil/address.go	 DecodePrivateKey		 82.61% (19/23)
 github.com/conformal/btcutil/block.go	 Block.TxSha			 75.00% (3/4)
 github.com/conformal/btcutil/address.go	 AddressPubKeyHash.IsForNet	 60.00% (3/5)
-github.com/conformal/btcutil/address.go	 AddressPubKey.IsForNet		 60.00% (3/5)
 github.com/conformal/btcutil/address.go	 AddressScriptHash.IsForNet	 60.00% (3/5)
+github.com/conformal/btcutil/address.go	 AddressPubKey.IsForNet		 60.00% (3/5)
 github.com/conformal/btcutil/certgen.go	 NewTLSCertPair			 0.00% (0/50)
 github.com/conformal/btcutil/address.go	 AddressPubKey.AddressPubKeyHash 0.00% (0/3)
-github.com/conformal/btcutil/address.go	 AddressPubKey.SetFormat	 0.00% (0/1)
 github.com/conformal/btcutil/appdata.go	 AppDataDir			 0.00% (0/1)
 github.com/conformal/btcutil/address.go	 AddressPubKey.Format		 0.00% (0/1)
-github.com/conformal/btcutil		 ------------------------------- 77.25% (275/356)
+github.com/conformal/btcutil/address.go	 AddressPubKey.SetFormat	 0.00% (0/1)
+github.com/conformal/btcutil		 ------------------------------- 78.46% (295/376)