I could have sworn I submitted one long ago
<https://xojo.com/issue/41735>
Still it would be good if the basic stuff in Xojo would work well.
I wonder what may be going wrong?
Currency could internally be handled like int64 for most operations.
e.g. for adding one to other. What could go wrong that the div fails?
Please Xojo Inc. take the message in this thread highly serious and prioritize these matters above adding new stuff.
We dealt with it far too long.
[code]Sub Action()
// currency maths test
dim a, b, c as currency=0.00
a=15563.12
b=4.3333
c=a/b
a=a/b
break
End Sub[/code]
Still broken 2 years laterā¦
Thank you Matthew.
I didnāt know that currency is not working with 4 decimals, at least in this case it looks like b is only using 4.33
Edit: in Matthewās example a/b=3594.2539 and should be 3591.5168
15563.12 / 4.33 = 3594.2540 (so 4.33 is used instead of 4.3333 above)
but 3591.5168 * 4.3333 = 15563.1197 (this is correct)
Currency is still quite broken in 64 bit builds (issue 47822):
[code]dim c1 as Currency = 1.1
dim c2 as Currency = 1.2
if c1 = c2 then
Break // Should not break here
End[/code]
Thank you David. Your code works in 32 bit but breaks in 64 bit.
As a workaround I changed the If statement to:
If c1.ToText = c2.ToText Then
and it seems to work.
Any other workaround until the issue is fixed?
Edit: I saw your other code (47822). At the break point d4 is reported as 0.799999ā¦ and d5 as 0.8, so d4 <> d5. But d4.ToText is reported as 0.8000ā¦ the same as d5.ToText. I guess this is a coincidence and not something that we can use every time, right?
The additional sample code I added to 47822 was an example of why using doubles rather than currency can be a bad idea. People using currency want to avoid issues that arise from using doubles with decimals.
Unfortunately the Currency type is badly broken in 64 builds.
Thank you David.
I agree, Iām writing an app that need the Currency type working and it will be better if it had more decimals. In Mexico there were a lot of changes in currency, 1,000 old pesos now are only 1. I need to do some calculations with 5 decimals.
Iāll try Bob Delaney Decimal plugin. I hope that will help with my project. I didnāt want to use any plugin for this, I donāt know about licensing but this is a personal project so I think I donāt have to worry about that yet.
you can also make your own currency class, with an integer part for the decimals, an int64 for the real part
and rewrite the base operators the way you want, with the decimals you want.
Thank you Jean-Yves, way above my programing knowledge. Maybe in the future.
For now Iāll use the Decimal plugin. I already did some tests and it works perfect for what I need.
I wish Xojo can include a Numeric data type, like PostgreSQL, in the future. It can replace Currency and we can use it to up to 16,383 digits after the decimal point. I donāt think I should ever need more than 16.
something like this :
Dim n1,n2 As nativeCurrency
n1.SetNumberOfDecimals( 3)
n1 = "12532.235"
n2 = 52635.952
MsgBox n1 + n2
outputs ā65168.187ā as a string or a double as you like
quick and dirty implementation, someone can surely optimize this.
Class nativeCurrency
Methods
Function Operator_Add(rightSide as nativeCurrency) As nativeCurrency
' adds two nativeCurrency
Dim newCurrency As new nativeCurrency
dim fracLimit as Integer = Pow(10, numberOfDecimals)
newCurrency.fractionnalPart = Me.fractionnalPart + rightSide.fractionnalPart
newCurrency.integerPart = Me.integerPart + rightSide.integerPart
if newCurrency.fractionnalPart>fracLimit Then
newCurrency.fractionnalPart = newCurrency.fractionnalPart - fracLimit
newCurrency.integerPart = newCurrency.integerPart + 1
End If
Return newCurrency
End Function
Function Operator_Convert() As Double
' converts a nativeCurrency to a Double
Dim fracLimit As Integer = Pow(10, numberOfDecimals)
Dim result As Double
result = Me.integerPart + (Me.fractionnalPart / fracLimit)
Return result
End Function
Function Operator_Convert() As String
' converts a nativeCurrency to a String
Dim result As String
Dim fracLimit As Integer = Pow(10, numberOfDecimals)
Dim fracLimitStr As String = Str( fracLimit)
fracLimitStr = Right( fracLimitStr, Len(fracLimitStr)-1)
result = Str(Me.integerPart) + "." + Format(Me.fractionnalPart, fracLimitStr)
Return result
End Function
Sub Operator_Convert(rightSide as String)
' converts a string "xxxx.yyy" to a nativeCurrency
Dim fracLimit As Integer = Pow(10, numberOfDecimals)
Me.integerPart = Val(NthField(rightSide, ".", 1))
Me.fractionnalPart = Val(NthField(rightSide, ".", 2))
End Sub
Sub Operator_Convert(rightSide as Double)
' converts a double xxxx.yyy to a nativeCurrency
Dim fracLimit As Integer = Pow(10, numberOfDecimals)
Me.integerPart = Floor(rightSide)
Dim i As Double = rightSide-Me.integerPart
dim j as Double = i * fracLimit Me.fractionnalPart = Round(j)
End Sub
Shared Methods
Shared Sub SetNumberOfDecimals(number as Integer)
numberOfDecimals = number
End Sub
Properties
Private fractionnalPart As Int64
Private integerPart As Int64
Shared Properties
Private Shared numberOfDecimals As Integer
End Class