support for negative numbers in Decimal from @cosmjs/math
Description
The Decimal class from @cosmjs/math currently rejects negative values and throws an error when the input contains a "-" sign.
This makes it impossible to represent or work with signed decimal numbers in CosmJS.
🔍 Example
import { Decimal } from "@cosmjs/math";
Decimal.fromUserInput("-0.123", 3);
// ❌ Error: Negative values not supported
💡 Expected behavior
Decimal should support negative values, or at least provide an alternative (e.g. SignedDecimal) for cases where signed arithmetic is required.
🧠 Context
In the Go Cosmos SDK, the equivalent type sdk.Dec does support negative numbers.
This is useful for many valid scenarios, such as:
- Calculating deltas or differences between balances or prices
- Expressing signed ratios or deviations
- Performing off-chain accounting or simulation logic
In CosmJS, however, the current implementation appears to be limited to non-negative quantities (like tokens, gas prices, etc.), which restricts flexibility in analytical or off-chain use cases.
🚀 Proposal
- Extend the existing
Decimalclass to allow negative values, or - Introduce a new
SignedDecimaltype that:- Keeps the same precision handling
- Encodes/decodes safely
- Maintains backward compatibility with positive-only decimals
Interesting. I also just found https://github.com/hyperweb-io/telescope/issues/642.
Decimal was never written for the Cosmos SDK type github.com/cosmos/cosmos-sdk/types.Dec. It was meant to make writong dapps with balances easier and avoid add the rounding issues that number has, especially for displaying balances. We also have explicitly "A type for arbitrary precision, non-negative decimals." in the type description.
Not sure what the best solution is here. The entire design right now is made for Coin.
I see. Well, I found a simple workaround for my usecase.
However support for negative values could be useful for some requirements in akash which may arise in the future but I dont have enough details to insist on implementing negative decimals support.
Cc: @troian
After #1916 the Decimal type is pretty much fully migrated from string to bigint. This should make it easy to add extra tests and remove the restriction to non-negative values.
Could you review https://github.com/cosmos/cosmjs/pull/1930?