├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── bower.json ├── index.js ├── package.json └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Jonathan Svärdén (http://svarden.se) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # short-number [![Build Status](https://travis-ci.org/cfj/short-number.svg?branch=master)](https://travis-ci.org/cfj/short-number) [![npm version](https://badge.fury.io/js/short-number.svg)](http://badge.fury.io/js/short-number) 2 | 3 | > Turn a long number into a short one to improve readability. 4 | 5 | 6 | ## Installation 7 | 8 | ```sh 9 | $ npm install --save short-number 10 | ``` 11 | Or with bower: 12 | ```sh 13 | $ bower install short-number 14 | ``` 15 | 16 | 17 | ## Usage 18 | 19 | ```js 20 | var shortNumber = require('short-number'); 21 | 22 | shortNumber(5432); 23 | //=> 5.4K 24 | 25 | shortNumber(1236903); 26 | //=> 1.2M 27 | ``` 28 | 29 | Supports numbers up to `1e18`. 30 | 31 | 32 | ## License 33 | 34 | MIT © [Jonathan Svärdén](http://svarden.se) -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "short-number", 3 | "version": "1.0.0", 4 | "description": "Turn a long number into a short one for easier reading, like 23634 => 23.6K", 5 | "moduleType": ["globals", "amd", "node"], 6 | "license": "MIT", 7 | "authors": [{ 8 | "name": "Jonathan Svärdén", 9 | "email": "jonathan.svarden@gmail.com", 10 | "homepage": "http://svarden.se" 11 | }], 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/cfj/short-number" 15 | }, 16 | "keywords": [ 17 | "number", 18 | "shorten", 19 | "simplify", 20 | "readability", 21 | "thousands", 22 | "millions" 23 | ], 24 | "ignore": [ 25 | "**/.*", 26 | "node_modules", 27 | "package.json", 28 | "test.js" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | (function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 | typeof define === 'function' && define.amd ? define(factory) : 4 | global.shortNumber = factory(); 5 | }(this, function (num) { 6 | 'use strict'; 7 | 8 | return function (num) { 9 | if(typeof num !== 'number') { 10 | throw new TypeError('Expected a number'); 11 | } 12 | 13 | if(num > 1e19) { 14 | throw new RangeError('Input expected to be < 1e19'); 15 | } 16 | 17 | if(num < -1e19) { 18 | throw new RangeError('Input expected to be > -1e19'); 19 | } 20 | 21 | if(Math.abs(num) < 1000) { 22 | return num; 23 | } 24 | 25 | var shortNumber; 26 | var exponent; 27 | var size; 28 | var sign = num < 0 ? '-' : ''; 29 | var suffixes = { 30 | 'K': 6, 31 | 'M': 9, 32 | 'B': 12, 33 | 'T': 16 34 | }; 35 | 36 | num = Math.abs(num); 37 | size = Math.floor(num).toString().length; 38 | 39 | exponent = size % 3 === 0 ? size - 3 : size - (size % 3); 40 | shortNumber = Math.round(10 * (num / Math.pow(10, exponent))) / 10; 41 | 42 | for(var suffix in suffixes) { 43 | if(exponent < suffixes[suffix]) { 44 | shortNumber += suffix; 45 | break; 46 | } 47 | } 48 | 49 | return sign + shortNumber; 50 | }; 51 | })); 52 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "short-number", 3 | "version": "1.0.7", 4 | "description": "Turn a long number into a short one to improve readability, like 23634 => 23.6K", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/cfj/short-number" 8 | }, 9 | "main": "index.js", 10 | "scripts": { 11 | "test": "node test.js" 12 | }, 13 | "keywords": [ 14 | "number", 15 | "shorten", 16 | "simplify", 17 | "readability", 18 | "thousands", 19 | "millions" 20 | ], 21 | "author": { 22 | "name": "Jonathan Svärdén", 23 | "email": "jonathan.svarden@gmail.com", 24 | "url": "http://svarden.se" 25 | }, 26 | "license": "MIT", 27 | "devDependencies": { 28 | "tape": "^4.0.3" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var test = require('tape'); 3 | var shortNumber = require('./'); 4 | 5 | test('positive tests', function(t) { 6 | t.plan(17); 7 | 8 | t.equal(shortNumber(231), 231); 9 | t.equal(shortNumber(231.6), 231.6); 10 | t.equal(shortNumber(1000), '1K'); 11 | t.equal(shortNumber(5432), '5.4K'); 12 | t.equal(shortNumber(5432.8567), '5.4K'); 13 | t.equal(shortNumber(35656), '35.7K'); 14 | t.equal(shortNumber(1000000), '1M'); 15 | t.equal(shortNumber(1000000.89), '1M'); 16 | t.equal(shortNumber(1236903), '1.2M'); 17 | t.equal(shortNumber(49653234), '49.7M'); 18 | t.equal(shortNumber(984938293), '984.9M'); 19 | t.equal(shortNumber(1000000000), '1B'); 20 | t.equal(shortNumber(2743000000), '2.7B'); 21 | t.equal(shortNumber(64743000000), '64.7B'); 22 | t.equal(shortNumber(344843000000), '344.8B'); 23 | t.equal(shortNumber(1000000000000), '1T'); 24 | t.equal(shortNumber(1344843000000), '1.3T'); 25 | }); 26 | 27 | test('negative tests', function(t) { 28 | t.plan(17); 29 | 30 | t.equal(shortNumber(-231), -231); 31 | t.equal(shortNumber(-231.6), -231.6); 32 | t.equal(shortNumber(-1000), '-1K'); 33 | t.equal(shortNumber(-5432), '-5.4K'); 34 | t.equal(shortNumber(-5432.8567), '-5.4K'); 35 | t.equal(shortNumber(-35656), '-35.7K'); 36 | t.equal(shortNumber(-1000000), '-1M'); 37 | t.equal(shortNumber(-1000000.89), '-1M'); 38 | t.equal(shortNumber(-1236903), '-1.2M'); 39 | t.equal(shortNumber(-49653234), '-49.7M'); 40 | t.equal(shortNumber(-984938293), '-984.9M'); 41 | t.equal(shortNumber(-1000000000), '-1B'); 42 | t.equal(shortNumber(-2743000000), '-2.7B'); 43 | t.equal(shortNumber(-64743000000), '-64.7B'); 44 | t.equal(shortNumber(-344843000000), '-344.8B'); 45 | t.equal(shortNumber(-1000000000000), '-1T'); 46 | t.equal(shortNumber(-1344843000000), '-1.3T'); 47 | }); 48 | 49 | test('throw error on too large numbers', function(t) { 50 | t.plan(1); 51 | 52 | t.throws(function() { 53 | shortNumber(1e20); 54 | }, RangeError, 'Input expected to be < 1e19'); 55 | }); 56 | 57 | test('throw error on too small numbers', function(t) { 58 | t.plan(1); 59 | 60 | t.throws(function() { 61 | shortNumber(-1e20); 62 | }, RangeError, 'Input expected to be > -1e19'); 63 | }); 64 | 65 | test('throw error on incorrect type', function(t) { 66 | t.plan(4); 67 | 68 | t.throws(function() { 69 | shortNumber('abc'); 70 | }, TypeError, 'Expected a number'); 71 | 72 | t.throws(function() { 73 | shortNumber(true); 74 | }, TypeError, 'Expected a number'); 75 | 76 | t.throws(function() { 77 | shortNumber([]); 78 | }, TypeError, 'Expected a number'); 79 | 80 | t.throws(function() { 81 | shortNumber({}); 82 | }, TypeError, 'Expected a number'); 83 | }); --------------------------------------------------------------------------------