diff --git a/bplist_generator.go b/bplist_generator.go
index 5b6513d16b9f081d01d43359b89dc3f95b0a0ecc..09ab71b1f4e647bcc63a91a2169a9bdfcb16fc6d 100644
--- a/bplist_generator.go
+++ b/bplist_generator.go
@@ -109,7 +109,7 @@ func (p *bplistGenerator) writePlistValue(pval cfValue) {
 	case cfString:
 		p.writeStringTag(string(pval))
 	case *cfNumber:
-		p.writeIntTag(pval.value)
+		p.writeIntTag(pval.signed, pval.value)
 	case *cfReal:
 		if pval.wide {
 			p.writeRealTag(pval.value, 64)
@@ -154,7 +154,7 @@ func (p *bplistGenerator) writeBoolTag(v bool) {
 	binary.Write(p.writer, binary.BigEndian, tag)
 }
 
-func (p *bplistGenerator) writeIntTag(n uint64) {
+func (p *bplistGenerator) writeIntTag(signed bool, n uint64) {
 	var tag uint8
 	var val interface{}
 	switch {
@@ -167,12 +167,25 @@ func (p *bplistGenerator) writeIntTag(n uint64) {
 	case n <= uint64(0xffffffff):
 		val = uint32(n)
 		tag = bpTagInteger | 0x2
+	case n > uint64(0x7fffffffffffffff) && !signed:
+		// 64-bit values are always *signed* in format 00.
+		// Any unsigned value that doesn't intersect with the signed
+		// range must be sign-extended and stored as a SInt128
+		val = n
+		tag = bpTagInteger | 0x4
 	default:
 		val = n
 		tag = bpTagInteger | 0x3
 	}
 
 	binary.Write(p.writer, binary.BigEndian, tag)
+	if tag&0xF == 0x4 {
+		// SInt128; in the absence of true 128-bit integers in Go,
+		// we'll just fake the top half. We only got here because
+		// we had an unsigned 64-bit int that didn't fit,
+		// so sign extend it with zeroes.
+		binary.Write(p.writer, binary.BigEndian, uint64(0))
+	}
 	binary.Write(p.writer, binary.BigEndian, val)
 }
 
@@ -216,7 +229,7 @@ func (p *bplistGenerator) writeCountedTag(tag uint8, count uint64) {
 	binary.Write(p.writer, binary.BigEndian, marker)
 
 	if count >= 0xF {
-		p.writeIntTag(count)
+		p.writeIntTag(false, count)
 	}
 }
 
diff --git a/common_data_for_test.go b/common_data_for_test.go
index 7ab295032f1ff7234249a45228be98abfe959ea4..973b09d8e9e1f441ce15286649066771f5ba2fa2 100644
--- a/common_data_for_test.go
+++ b/common_data_for_test.go
@@ -313,12 +313,12 @@ var tests = []TestData{
 	},
 	{
 		Name:  "Unsigned Integers of Increasing Size",
-		Value: []uint64{0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0xfffffff, 0xffffffff, 0xffffffffffffffff},
+		Value: []uint64{0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0xfffffff, 0xffffffff, 0x7fffffffffffffff, 0xdeadbeeffacecafe},
 		Documents: map[int][]byte{
-			OpenStepFormat: []byte(`(255,4095,65535,1048575,16777215,268435455,4294967295,18446744073709551615,)`),
-			GNUStepFormat:  []byte(`(<*I255>,<*I4095>,<*I65535>,<*I1048575>,<*I16777215>,<*I268435455>,<*I4294967295>,<*I18446744073709551615>,)`),
-			XMLFormat:      []byte(xmlPreamble + `<plist version="1.0"><array><integer>255</integer><integer>4095</integer><integer>65535</integer><integer>1048575</integer><integer>16777215</integer><integer>268435455</integer><integer>4294967295</integer><integer>18446744073709551615</integer></array></plist>`),
-			BinaryFormat:   []byte{98, 112, 108, 105, 115, 116, 48, 48, 168, 1, 2, 3, 4, 5, 6, 7, 8, 16, 255, 17, 15, 255, 17, 255, 255, 18, 0, 15, 255, 255, 18, 0, 255, 255, 255, 18, 15, 255, 255, 255, 18, 255, 255, 255, 255, 19, 255, 255, 255, 255, 255, 255, 255, 255, 8, 17, 19, 22, 25, 30, 35, 40, 45, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54},
+			OpenStepFormat: []byte(`(255,4095,65535,1048575,16777215,268435455,4294967295,9223372036854775807,16045690985305262846,)`),
+			GNUStepFormat:  []byte(`(<*I255>,<*I4095>,<*I65535>,<*I1048575>,<*I16777215>,<*I268435455>,<*I4294967295>,<*I9223372036854775807>,<*I16045690985305262846>,)`),
+			XMLFormat:      []byte(xmlPreamble + `<plist version="1.0"><array><integer>255</integer><integer>4095</integer><integer>65535</integer><integer>1048575</integer><integer>16777215</integer><integer>268435455</integer><integer>4294967295</integer><integer>9223372036854775807</integer><integer>16045690985305262846</integer></array></plist>`),
+			BinaryFormat:   []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xa9, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0xff, 0x11, 0x0f, 0xff, 0x11, 0xff, 0xff, 0x12, 0x00, 0x0f, 0xff, 0xff, 0x12, 0x00, 0xff, 0xff, 0xff, 0x12, 0x0f, 0xff, 0xff, 0xff, 0x12, 0xff, 0xff, 0xff, 0xff, 0x13, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xad, 0xbe, 0xef, 0xfa, 0xce, 0xca, 0xfe, 0x08, 0x12, 0x14, 0x17, 0x1a, 0x1f, 0x24, 0x29, 0x2e, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48},
 		},
 	},
 	{
@@ -597,12 +597,12 @@ var tests = []TestData{
 	},
 	{
 		Name:  "Signed Integers",
-		Value: []int64{-1, -127, -255, -32767, -65535},
+		Value: []int64{-1, -127, -255, -32767, -65535, -9223372036854775808},
 		Documents: map[int][]byte{
-			OpenStepFormat: []byte(`(-1,-127,-255,-32767,-65535,)`),
-			GNUStepFormat:  []byte(`(<*I-1>,<*I-127>,<*I-255>,<*I-32767>,<*I-65535>,)`),
-			XMLFormat:      []byte(xmlPreamble + `<plist version="1.0"><array><integer>-1</integer><integer>-127</integer><integer>-255</integer><integer>-32767</integer><integer>-65535</integer></array></plist>`),
-			BinaryFormat:   []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xa5, 0x1, 0x2, 0x3, 0x4, 0x5, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x1, 0x8, 0xe, 0x17, 0x20, 0x29, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b},
+			OpenStepFormat: []byte(`(-1,-127,-255,-32767,-65535,-9223372036854775808,)`),
+			GNUStepFormat:  []byte(`(<*I-1>,<*I-127>,<*I-255>,<*I-32767>,<*I-65535>,<*I-9223372036854775808>,)`),
+			XMLFormat:      []byte(xmlPreamble + `<plist version="1.0"><array><integer>-1</integer><integer>-127</integer><integer>-255</integer><integer>-32767</integer><integer>-65535</integer><integer>-9223372036854775808</integer></array></plist>`),
+			BinaryFormat:   []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xa6, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x13, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0f, 0x18, 0x21, 0x2a, 0x33, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45},
 		},
 	},
 	{