diff --git a/src/index.ts b/src/index.ts
index fec956f..88d04d9 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -5,8 +5,7 @@ const escaped: Record<string, string> = { '<': '\\u003C', '>' : '\\u003E', '/':
 const objectProtoOwnPropertyNames = Object.getOwnPropertyNames(Object.prototype).sort().join('\0');
 
 export default function devalue(value: any) {
-	const repeated = new Map();
-	const seen = new Set();
+	const counts = new Map();
 
 	let n = 0;
 
@@ -15,12 +14,12 @@ export default function devalue(value: any) {
 			throw new Error(`Cannot stringify a function`);
 		}
 
-		if (seen.has(thing)) {
-			repeated.set(thing, getName(n++));
+		if (counts.has(thing)) {
+			counts.set(thing, counts.get(thing) + 1);
 			return;
 		}
 
-		seen.add(thing);
+		counts.set(thing, 1);
 
 		if (!isPrimitive(thing)) {
 			const type = getType(thing);
@@ -46,11 +45,11 @@ export default function devalue(value: any) {
 					const proto = Object.getPrototypeOf(thing);
 
 					if (
-					  proto !== Object.prototype &&
-					  proto !== null &&
-					  Object.getOwnPropertyNames(proto).sort().join('\0') !== objectProtoOwnPropertyNames
+						proto !== Object.prototype &&
+						proto !== null &&
+						Object.getOwnPropertyNames(proto).sort().join('\0') !== objectProtoOwnPropertyNames
 					) {
-					  throw new Error(`Cannot stringify arbitrary non-POJOs`);
+						throw new Error(`Cannot stringify arbitrary non-POJOs`);
 					}
 
 					if (Object.getOwnPropertySymbols(thing).length > 0) {
@@ -62,9 +61,20 @@ export default function devalue(value: any) {
 		}
 	}
 
+	walk(value);
+
+	const names = new Map();
+
+	Array.from(counts)
+		.filter(entry => entry[1] > 1)
+		.sort((a, b) => b[1] - a[1])
+		.forEach((entry, i) => {
+			names.set(entry[0], getName(i));
+		});
+
 	function stringify(thing: any): string {
-		if (repeated.has(thing)) {
-			return repeated.get(thing);
+		if (names.has(thing)) {
+			return names.get(thing);
 		}
 
 		if (isPrimitive(thing)) {
@@ -107,15 +117,14 @@ export default function devalue(value: any) {
 		}
 	}
 
-	walk(value);
 	const str = stringify(value);
 
-	if (repeated.size) {
+	if (names.size) {
 		const params: string[] = [];
 		const statements: string[] = [];
 		const values: string[] = [];
 
-		repeated.forEach((name, thing) => {
+		names.forEach((name, thing) => {
 			params.push(name);
 
 			if (isPrimitive(thing)) {
@@ -196,7 +205,9 @@ function stringifyPrimitive(thing: any) {
 	if (typeof thing === 'string') return JSON.stringify(thing).replace(unsafe, escape);
 	if (thing === void 0) return 'void 0';
 	if (thing === 0 && 1 / thing < 0) return '-0';
-	return String(thing);
+	const str = String(thing);
+	if (typeof thing === 'number') return str.replace(/^(-)?0\./, '$1.');
+	return str;
 }
 
 function getType(thing: any) {
diff --git a/test/test.ts b/test/test.ts
index 4865963..74e69bd 100644
--- a/test/test.ts
+++ b/test/test.ts
@@ -14,6 +14,8 @@ describe('devalue', () => {
 		test('number', 42, '42');
 		test('negative number', -42, '-42');
 		test('negative zero', -0, '-0');
+		test('positive decimal', 0.1, '.1');
+		test('negative decimal', -0.1, '-.1');
 		test('string', 'woo!!!', '"woo!!!"');
 		test('boolean', true, 'true');
 		test('Number', new Number(42), 'Object(42)');