tru7
tru7

Reputation: 7222

toPrecision() with choice of rounding direction

Javascript's toPrecision rounds half up so

(123.46).toPrecision(4)    // 123.5
(123.44).toPrecision(4)    // 123.4

But what is a straightforward method to choose the direction of the rounding (up/ceil or down/floor)? so

(123.46).toPrecisionFloor(4)   // would give 123.4
(123.44).toPrecisionCeil(4)    // 123.5

Upvotes: 2

Views: 993

Answers (2)

a.cayzer
a.cayzer

Reputation: 289

I know this is an old post but I've been doing something similar. Where the scale of the number is known you can do a simple subtraction and use the precision function as is.

In my own I am trying to round to the nearest century so before I use the toPrecision function I take 50 years off the value which allows the function to produce the same ultimate result you were looking for. In the example from the original post if the precision is always going to be 4 places and the number in the format ddd.dd then you could simply remove 0.05 from the number before the precision function is called. Similarly if you wanted to round up you could add 0.05

Upvotes: 0

sauntimo
sauntimo

Reputation: 1591

It's not a one liner but I think this does what you're asking? You could probably tidy it up a little.

EDIT Updated (in a fairly rudimentary kind of way) to work with significant figures rather than decimals

EDIT 2 Golfed the code down a bit and added further tests

/**
 * rounds a number up or down to specified accuracy
 * @param number {numeric} number to perform operations on
 * @param precision {numeric} number of significant figures to return
 * @param direction {string} wether to round up or down
 */
function toPrecision(number, precision, direction) {
  precision -= Math.floor(number).toString().length;
  var order = Math.pow(10, precision);
  number *= order;
  var option = (direction === 'down' ? 'floor' : 'ceil');
  return (Math[option].call(null, number) / order);
}

// values to test
var test_1 = 123.567891;
var test_2 = 15000;
var test_3 = 12340000;

// define tests
var tests = {
  "a": [test_1, 3, "down"],
  "b": [test_1, 4, "up"],
  "c": [test_2, 3, "down"],
  "d": [test_2, 4, "up"],
  "e": [test_2, 1, "down"],
  "f": [test_2, 1, "up"],
  "g": [test_3, 4, "down"],
  "h": [test_3, 4, "up"]
}

// loop over tests and execute
for (var key in tests) {
  console.log("key:", key, "result: ", toPrecision.apply(null, tests[key]));
}

/*
	Test results: 
  key: a result:  123
  key: b result:  123.6
  key: c result:  15000
  key: d result:  15000
  key: e result:  10000
  key: f result:  20000
  key: g result:  12340000
  key: h result:  12340000
*/

JS Fiddle link

Upvotes: 1

Related Questions