0

I'm working on a project that involves manipulating cryptocurrency prices in JavaScript. I'm trying to write a function that can adjust the decimal points of a number, and then add or subtract a specified amount from that number. For example, if the input number is "27055.95" and I want to add "1" to it, the result should be "27055.96". If the input number is "26973.9" and I want to add "1" to it, the result should be "26974.0".

I've written a function that can perform the addition or subtraction, but I'm having trouble adjusting the decimal points of the input number. Here's what I have so far:

function adjustPrice(priceString, increaseAmount) {
  const price = parseFloat(priceString);
  const newPrice = price + increaseAmount;

  // TODO: Adjust decimal points of newPrice

  return newPrice.toString();
}

console.log(adjustPrice("27055.95", 1)); // Expected output: "27055.96"
console.log(adjustPrice("27055.99", 1)); // Expected output: "27056.0"
console.log(adjustPrice("27055.00", -1)); // Expected output: "27054.99"
console.log(adjustPrice("26973.9", 1)); // Expected output: "26974.0"
console.log(adjustPrice("269", 1)); // Expected output: "270"

How can I modify this function to adjust the decimal points of newPrice so that it matches the desired output format? I want the function to add or subtract increaseAmount from price, and then adjust the decimal points of the result to match the input format. For example, if the input format is "27055.95", I want the output format to be "27055.96" if I add "1" to it, and "27055.94" if I subtract "1" from it. Is there a built-in JavaScript method or library that can help me achieve this? If not, what is the most efficient way to perform this operation?

I've also tried using the "big.js" library to perform this operation, but I'm having trouble getting the expected output. Here's what I've tried:

const Big = require('big.js');

function adjustPrice(priceString, increaseAmount) {
  const bigPrice = new Big(priceString);
  const bigIncreaseAmount = new Big(increaseAmount);

  const newPrice = bigPrice.plus(bigIncreaseAmount);

  // TODO: Adjust decimal points of newPrice

  return newPrice.toString();
}
Kvlknctk
  • 634
  • 12
  • 27
  • You say you want to add 1, but you really want to add 0.01, 0.01, -0.01, 0.1 and 1 respectively for the examples you gave. You need to start by figuring out the number of decimal places. That will get you the correct number to add, as well as the information you need to correctly format the result. – ikegami Mar 28 '23 at 03:43
  • Indeed, you are right. I actually want both. I don't know how many digits the number has after the decimal point. Sometimes there won't even be a decimal point. We can think of cryptocurrency exchange prices as an example. In such cases, how can I increase or decrease these variables? Actually, all I want is to be able to add 1 to the last digit, whether or not there is a decimal point. – Kvlknctk Mar 28 '23 at 03:47
  • 1
    It's just a question of multiplying by a power of 10, 10 to the -2 will give 0.01, for example. – ikegami Mar 28 '23 at 03:49
  • 1
    Re "*I want is to be able to add 1 to the last digit, whether or not there is a decimal point.*", What about `adjustPrice( "270", 1 )`. Should it give the same thing as `adjustPrice( "269", 2 )`? – ikegami Mar 28 '23 at 03:52
  • I would like it to give yes – Kvlknctk Mar 28 '23 at 03:58
  • Lucky for you, then. So like I said, just a question of counting the (potentially zero) decimal places. A quick [string search](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf) will give you that. – ikegami Mar 28 '23 at 04:01

1 Answers1

1
  1. Validate the input
  2. Determine the number of decimal places
  3. Calculate the adjustment factor based on #2
  4. Parse the input price
  5. Multiply the adjustment factor by the adjustment amount and add the price
  6. Return the final value, formatted using fixed-point notation

const regexp = /^\d+(\.(?<decimals>\d+))?$/;

function adjustPrice(priceString, adjustment) {
  const match = priceString.match(regexp);
  if (!match) throw new Error("Unexpected input format");
  const decimals = match.groups.decimals?.length ?? 0;
  const factor = 10 ** (decimals * -1);
  const price = Number(priceString);
  const adjustedPrice = adjustment * factor + price;
  return adjustedPrice.toFixed(decimals);
}

for (
  const [input, adjustment, expected] of [
    ["27055.95", 1, "27055.96"],
    ["27055.99", 1, "27056.00"],
    ["27055.00", -1, "27054.99"],
    ["26973.9", 1, "26974.0"],
    ["269", 1, "270"],
  ]
) {
  const actual = adjustPrice(input, adjustment);
  console.log(
    actual === expected ? "✅" : "❌",
    `(${input}, ${adjustment})`,
    "->",
    actual,
  );
}

Lastly: Beware the perhaps unintuitive consequences of floating point math: 1, 2

jsejcksn
  • 27,667
  • 4
  • 38
  • 62