Skip to content

Support for Exponential Notation (e Powers) #19

@push1kb

Description

@push1kb

Description

Currently, dnum does not support exponential notation (e.g., 1e18), which is commonly used in Web3 for token balances and financial calculations. This makes it difficult to work with large numbers in a concise way.

Use Case

  • Many blockchain applications use 1e18 notation for token values (e.g., ETH, USDC, DAI).
  • Using BigInt(10) ** BigInt(18) works, but 1e18 is more intuitive and widely used in libraries like BigNumber.js.
  • Would improve developer experience when working with token decimals and mathematical operations.

Temporary Workaround

Until native support is added, I'm using the following function to convert exponential notation to a full decimal string:

function expoNtnToDecimalString(numStr) {
  // If the string doesn't contain an exponent, return it unchanged.
  if (!/[eE]/.test(numStr)) return numStr;

  // Split the number into coefficient and exponent parts.
  let [coef, expStr] = numStr.split(/e/i);
  let exp = parseInt(expStr, 10); // minimal numeric conversion for the exponent
  let sign = '';
  if (coef[0] === '-' || coef[0] === '+') {
    sign = coef[0];
    coef = coef.slice(1);
  }

  // Remove the decimal point from the coefficient and record its original position.
  let dotIndex = coef.indexOf('.');
  let digits, intPartLen;
  if (dotIndex === -1) {
    digits = coef;
    intPartLen = digits.length;
  } else {
    digits = coef.replace('.', '');
    intPartLen = dotIndex;
  }

  // Calculate the new decimal point position.
  let newDecimalPos = intPartLen + exp;

  if (newDecimalPos <= 0) {
    // If the new position is before the first digit, pad with zeros.
    let zeros = '0'.repeat(-newDecimalPos);
    return sign + '0.' + zeros + digits;
  } else if (newDecimalPos >= digits.length) {
    // If the new position is after all digits, pad zeros at the end.
    let zeros = '0'.repeat(newDecimalPos - digits.length);
    return sign + digits + zeros;
  } else {
    // Insert the decimal point within the digits.
    return sign + digits.slice(0, newDecimalPos) + '.' + digits.slice(newDecimalPos);
  }
}

// Example usage:
console.log(expoNtnToDecimalString("2.05483475399e-7")); // "0.000000205483475399"
console.log(expoNtnToDecimalString("1.23")); // "1.23"

Question

Would this be a valid workaround for now, or do you suggest any other approach? Also, is there any plan to natively support e notation in dnum?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions