This looks a lot like a rounding problem in floating point arithmetic to me.
Check your variable declarations.
If this is the problem, I would recommend an explicit variable declaration to avoid such rounding problems.
I could imagine that the problem might also arise when passing a variable into a table or list and you somehow define the placeholder for this variable in the table with a default value (double, float). If you retrieve the value later, it has changed because it has been transformed. To be on the safe side, save the variable as a string, retrieve this string as a string and convert it to your desired format.
Of course, you can also try rounding. But that might not produce the desired results either, I imagine.
It depends on your code and the variable declarations, I'm sure.
I had a similar problem with floating point arithmetic when calculating the orbit of the moon in my compass programme. The rounding errors at the beginning of a 43-step calculation routine were extremely high, which led to a deviation of 10 degrees. And the error was only somewhere far back in the decimal places...
Edit:
You mentioned a SQL-Database. What is the format of the target cell in which you save the value?
This looks a lot like a rounding problem in floating point arithmetic to me.
Check your variable declarations.
If this is the problem, I would recommend an explicit variable declaration to avoid such rounding problems.
I could imagine that the problem might also arise when passing a variable into a table or list and you somehow define the placeholder for this variable in the table with a default value (double, float). If you retrieve the value later, it has changed because it has been transformed. To be on the safe side, save the variable as a string, retrieve this string as a string and convert it to your desired format.
Of course, you can also try rounding. But that might not produce the desired results either, I imagine.
It depends on your code and the variable declarations, I'm sure.
I had a similar problem with floating point arithmetic when calculating the orbit of the moon in my compass programme. The rounding errors at the beginning of a 43-step calculation routine were extremely high, which led to a deviation of 10 degrees. And the error was only somewhere far back in the decimal places...
When it comes to SQL, you have (as far as I know) two options for defining a field for numbers within a table. These options are INT and REAL.
As far as I know, there are only these two options with SQL, but I would be happy to be corrected.
If the field is defined as REAL, your value is automatically converted into a real value when it is stored in this cell. I suspect that this is where the rounding error occurs.
Can you have a look into the table with an SQL-Viewer directly after filling the cell?
However, the error can just as easily occur when the value is retrieved from the SQL table. Display it directly afterwards with a log command.
Edit:
A simple but somewhat unusual way would be to save the amounts as cent amounts. In other words, multiply them by 100, save them as integers and divide them by 100 again after retrieving them. However, this may again cause problems with small cent amounts. Use then the proper format in defining the cell (SQL_INT). Personally, I would save the value as a string (SQL_TEXT) and convert it to the desired decimal number format after retrieving it from the database. (Decimal 10,2).
When it comes to SQL, you have (as far as I know) two options for defining a field within a table. These options are INT and REAL.
As far as I know, there are only these two options with SQL, but I would be happy to be corrected.
If the field is defined as REAL, your value is automatically converted into a real value when it is stored in this cell. I suspect that this is where the rounding error occurs.
Can you have a look into the table with an SQL-Viewer directly after filling the cell?
However, the error can just as easily occur when the value is retrieved from the SQL table. Display it directly afterwards with a log command.
Field is Decimal(10,2)
Log that show a value directly from a database shows the same problem 503.41999999999996
I solved it by using Round2(PaymentAmount,2)
What I have noticed that if the only 1 record meets the search criteria it works correctly. But if it more than 1 record - I have this problem.
Like for example
One record with PaymentAmount 1432.55 works correctly with weekend date 2024-11-23T00:00:00
Two records 322.19 and 181.23 and we have a problem with weekend date 2024-11-16T00:00:00
The only difference is a different weekend date.
B4X:
SELECT
sum(PaidAmount) As PaidAmount,
Max(PaidDate) As PaidDate
FROM tblBilling
where WeekEndDate='2024-11-16T00:00:00'
Have a look, I edited my previous post.
Do you display the table directly in your programme or do you display the values of the SQL database in a B4X table?
I it is a B4X table I would recommend to work with ticks-values when it comes to date and time. Then you are on the safe site.
Have a look, I edited my previous post.
Do you display the table directly in your programme or do you display the values of the SQL database in a B4X table?
I it is a B4X table I would recommend to work with ticks-values when it comes to date and time. Then you are on the safe site.
So this is as I expected. You put your decimal formatted value into a REAL-field of the SQL-database. In this moment your value will be transformed into a real value.
So this is as I expected. You put your decimal formatted value into a REAL-field of the SQL-database. In this moment your value will be transformed into a real value.
Ok, makes no difference you can convert the ticks. But this is not your problem. Decision is yours how to store your data.
When it comes to the point of prevent rounding errors when transforming a monetary value, I would suggest these two options:
1. store cent values in an INT-field of the database or
2. store the value as a string and convert it after picking to decimal (10,2)
I don't know exactly how SQL handles that decimal declaration. Is probably a formatted real value, so this would not help in your case. (automatically rounding)
So, keep it simple, option 1 is my recommendation.
Well, it looks like it works correctly, but if the cents value is anything other than 0, 25, 50 or 75 cents, then it will not actually be precisely correct.
These are normal display problems with Double numbers.
A digital number cannot hold the exact value of 503.42, but only the closest one 503.41999999999996.
To display the result use NumberFormat or NumberFormat2.
Try this code:
B4X:
Private a, b As Double
a = 322.19
b = 181.23
Log(a + b)
These are normal rounding problems with Double numbers.
A digital number cannot hold the exact value of 503.42, but only the closest one 503.41999999999996.
To display the result use NumberFormat or NumberFormat2.
Try this code:
B4X:
Private a, b As Double
a = 322.19
b = 181.23
Log(a + b)
not this way, but I run a SQL statement to get a sum of 2 rows and if I run this statement in db viewer it works fine and shows me 503.42 but if I run the same SQL from my code it shows 503.41999999999996
As @klaus says this is an inevitable side effect of using Doubles that being binary values do not accurately represent all decimal values. If you need decimal precision you can use my BigNumbers library.
If you need to do very accurate claculations using decimal numbers then the normal Java numeric types are not appropriate because, being finite length binary numbers, they cannot accurately represent every possible decimal number. The Java libraries contain a BigDecimal class that is optimised...
As @klaus says this is an inevitable side effect of using Doubles that being binary values do not accurately represent all decimal values. If you need decimal precision you can use my BigNumbers library.
If you need to do very accurate claculations using decimal numbers then the normal Java numeric types are not appropriate because, being finite length binary numbers, they cannot accurately represent every possible decimal number. The Java libraries contain a BigDecimal class that is optimised...