If I want to place a bidding offer for an asset at 41.5, it's getting converted to 41.499999.

Is there a way in the JS-SDK to make the price exactly as intended? I know there is a price:{n,d} object but I fail to find a function to make use of it like getPricePair(fromIntendedPrice) or something.


If you pass a string as a price in Operation.manageOffer JS SDK will use continued fraction approximation algorithm. I've just checked it and it approximates 41.5 to {n: 83, d: 2} which is fine. Not sure how you got 41.499999.

Because low level code in stellar-core operates on fractions you may want ot pass a fraction directly in JS SDK. This can be done by passing an object with two fields:

  • n - numerator
  • d - denominator

in price parameter.

  • Thanks Bartek, but to do the opposite op you need to do 1/price which will give you decs and not an exact conversion once it hits the server. And I know there is a way to pass {n,d} but what should be the values of n and d? That's what the question is about. I'm trying padding them with 15 zeroes and I get the right number on the console but it fails on the SDK with out of bounds. So how to calculate 83 and 2? No function in the SDK to derive them? – Kuyawa Feb 21 '18 at 21:18
  • The opposite of [83, 2] would be [2, 83], no? And for offer to be consumed it doesn't have to have exactly the opposite price. When buying an asset you can set a higher price and it will still use the seller's price (if no new offer with a higher price is created in a meantime). – Bartek Nowotarski Feb 21 '18 at 22:19
  • Yes but why 83? why not 99? I know it is calculated but how? I have amount and price as vars, so how to set {n:what, d:why} ? – Kuyawa Feb 22 '18 at 1:29

So here is the problem and one possible solution to dividing 1/price and getting a rounding error:

askPrice = 41.5 bidPrice = 1/41.5 // 0.024096385542168676

There is a function in BigNumber.toFraction that does the conversion from a price to a fraction but unfortunately it's hidden, now there is this function Operation.toXDRPrice that does the same and it takes a price or a fraction:

fraction = StellarSdk.Operation._toXDRPrice(askPrice)._attributes bidPrice = StellarSdk.Operation._toXDRPrice({n: fraction.d, d: fraction.n})._attributes

Now bidPrice is exactly the same as askPrice without rounding error {83, 2} and {2, 83} just as Bartek Nowotarski explained.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.