prathameshmm02 / Calculator-inator

Calculator & Converter for Android
GNU General Public License v3.0
146 stars 15 forks source link

Conversion is not accurate. #28

Closed jcperil closed 7 months ago

jcperil commented 2 years ago

USDINR pair is currently trading at ~ 78. This calculator shows 74.24.

BTCUSD pair is currently trading at ~ 21000. This calculator shows 42034.11.

1 gigabyte = 1024 megabyte. This calculator shows 1000.

1 hour = 60 minutes. This calculator shows 24.00000000000864.

1 day = 24 hours. This calculator shows 6.999999999993952.

prathameshmm02 commented 2 years ago

USDINR pair is currently trading at ~ 78. This calculator shows 74.24.

BTCUSD pair is currently trading at ~ 21000. This calculator shows 42034.11.

This is actually an issue because of the API I am using. I'll try to fix this if possible in the next update.

1 hour = 60 minutes. This calculator shows 24.00000000000864.

1 day = 24 hours. This calculator shows 6.999999999993952.

These bugs are fixed in the latest update (1.2.0) .

1 gigabyte = 1024 megabyte. This calculator shows 1000.

These rates are based on Google's converter see here

jcperil commented 2 years ago

I found this convertor which gives accurate results. Perhaps you can use the same API.

Para-lyzed commented 2 years ago

1 gigabyte = 1024 megabyte. This calculator shows 1000.

@jcperil I believe this is actually because the standard has changed. The SI prefix kilo- means thousand, so 1 kilobyte by SI standards should be 1000 bytes. This discrepancy was confusing, so there was an attempt made to fix it. The old 1024 byte kilobyte (which is what computers still use at the low level because they use binary, but the OS may automatically convert to the new standard to describe size) is now called a kibibyte. This is extended to all higher measurements as well, with a megabyte now being 1000 kilobytes, and a mebibyte being 1024 kibibytes. So this converter is correct in that regard, but most people don't know the difference between a kilobyte and a kibibyte.

The rest of this comment is intended for @prathameshmm02.

What I'd personally like to add is the discrepancy in US measurements. For instance, 1 US gallon should be 16 US cups, but I'll list a bunch of discrepancies below (due to errors in floating point logic that need to be fixed by using more modern decimal division methods, such as Java's BigDecimal implementation). The converter returns the following incorrect conversions between US volume measurements:

1 gallon = 4.000007570825068 quarts 1 gallon = 8.000015141650136 pints 1 gallon = 15.77255222607493 cups 1 gallon = 127.99993943339943 fluid ounces 1 gallon = 255.99987886679887 tablespoons 1 gallon = 767.9996366003967 teaspoons quart -> all above conversions (gallon, pint, cups, fl oz, tbsp, tsp) pint -> all above conversions ... etc.

The following US length conversions are also incorrect:

1 mile = 1759.9903173999999 yards 1 mile = 5279.9870456 feet 1 mile = 63359.876734 inches ... etc.

All US conversions are incorrect due to poorly handled floating point logic. I imagine the same is true for (non-US) imperial measurements. This also means the conversion between metric and imperial (US and non-US) has a large error.

I don't personally know much about Kotlin, but I believe there is some implementation of BigDecimal as per the documentation. I also saw some discussion about multiplatform limitations when I briefly looked into it here. At the worst, it seems like you may need to use an external library to port the functionality to Android, and that is discussed in the forum post I linked. The BigDecimal can be used for all division, it doesn't have to be used exclusively for imperial measurements with non-metric subdivisions. That would also potentially take the place of any system you used to ensure consistency in metric conversions (as while dividing by factors of 10 would still usually result in floating point inaccuracies, it seems the conversions for metric all work).

I should mention that I realize you likely use APIs to handle all of your unit conversions. However, since these conversions won't ever change, there would be no reason not to hard code them if that would allow you to achieve more accurate results. This also decreases reliance on sending requests through the Internet, which is all around a bonus for the end user. Of course, this doesn't extend to currency exchange rates, but it works great for measurements.

Since this is specifically an issue with floating point logic, I can open another issue if necessary, as there are some differences between the problem that started this issue and the problems I am describing. Let me know and I would happily move this to its own issue.