Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converting between currencies with different bases returns wrong scale #477

Open
sarahdayan opened this issue Nov 4, 2021 Discussed in #446 · 2 comments
Open

Converting between currencies with different bases returns wrong scale #477

sarahdayan opened this issue Nov 4, 2021 Discussed in #446 · 2 comments
Assignees
Labels
bug Something isn't working

Comments

@sarahdayan
Copy link
Collaborator

When converting between currencies with different bases (e.g., MRU and UAH), the scale is wrong. This comes from the scale calculation in convert.

Reproduction: https://codesandbox.io/s/github/dinerojs/dinero.js/tree/main/examples/starter?file=/main.js

Discussed in #446

Originally posted by antpv October 17, 2021
I have currency rate like this: 0.0001234

How can i calculate "scale" and "amount" for dinero currency rate correctly?

@sarahdayan sarahdayan added the bug Something isn't working label Nov 4, 2021
@sarahdayan sarahdayan self-assigned this Nov 4, 2021
@sarahdayan sarahdayan changed the title Converting between currencies with different bases returns wrong scale Converting between currencies with different bases returns wrong results Nov 4, 2021
@sarahdayan sarahdayan changed the title Converting between currencies with different bases returns wrong results Converting between currencies with different bases returns wrong scale Nov 4, 2021
@matheusfcorocher
Copy link

matheusfcorocher commented Apr 28, 2022

I was verifying this issue and I found that convert() function only works with amount and scale. When, both dinero objects have the same base doesn't have this problem but with different bases, this bug happen. I'm trying to make a solution about that.

Today, it works like that:

Old behavior of function:
	- multiplies amount of dinero that will be converted with amount of
	rate
	- adds scale of dinero that will be converted with scale of rate
	- returns dinero with new amount and currency, and converts 
	to highest scale

I was thinking about:

New behavior of function:
	- convert dinero base to have the same base of new currency
	- multiplies amount of dinero that will be converted with amount of
	rate
	- adds scale of dinero that will be converted with scale of rate
	- returns dinero with new amount and currency, and converts 
	to highest scale

What do you think @sarahdayan?

@matheusfcorocher
Copy link

I was verifying this issue and I found that convert() function only works with amount and scale. When, both dinero objects have the same base doesn't have this problem but with different bases, this bug happen. I'm trying to make a solution about that.

Today, it works like that:

Old behavior of function:
	- multiplies amount of dinero that will be converted with amount of
	rate
	- adds scale of dinero that will be converted with scale of rate
	- returns dinero with new amount and currency, and converts 
	to highest scale

I was thinking about:

New behavior of function:
	- convert dinero base to have the same base of new currency
	- multiplies amount of dinero that will be converted with amount of
	rate
	- adds scale of dinero that will be converted with scale of rate
	- returns dinero with new amount and currency, and converts 
	to highest scale

What do you think @sarahdayan?

I was trying to create the algorithm for converting dinero to a same currency and my idea was to use toUnit() function for getting the real value of dinero object, try to convert into another base and create new dinero object with new base.

I asked a question in MathStackExchange to verify if was possible solve the base conversion. I receive this answer in MathStackExchange by Paul Sinclair.
By his answer, in order to implement an algorithm that I was thinking, I should consider 2 types of case:

  • If the real value of dinero object has a terminating expansion in the new base
    • If value is integer, keep dividing by new base until the result is no longer integer. exponent will be the number of times you divided and got an integer result. amount is the last integer result you got.
    • If value is not integer, keep multiplying by new base until you get an integer result. exponent will be the opposite of the number of times you multiplied by new base to get that integer result. amount will be the integer result.
  • The real value of dinero object does not have a terminating expression in the new base

In the last case, is impossible to express with integers the number, almost all number he said.
So the algorithm would be inconsistency if the real value doesn't have a terminating expression in the new base. It implies that is not a good idea to implement it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants