BitterTea
|
|
March 31, 2011, 02:13:17 AM |
|
If you want to operate on string, just add suffix "String" to every parameter/attribute name.
It's not a matter of what you "want" to operate on, it's a matter of the API version, and the Bitcoin version, of the user. Any code using the API would have to detect that and modify its behavior.
|
|
|
|
jgarzik
Legendary
Offline
Activity: 1596
Merit: 1100
|
|
March 31, 2011, 02:25:15 AM |
|
We can use different names for parameters, like
SendCoinsString 100.00000000 Instead of SendCoins 100.00000000
That would eleminate such problems forever.
If you want to operate on string, just add suffix "String" to every parameter/attribute name.
Which is, again, a second API to support on top of the first. Twice bugs, twice the pain.
|
Jeff Garzik, Bloq CEO, former bitcoin core dev team; opinions are my own. Visit bloq.com / metronome.io Donations / tip jar: 1BrufViLKnSWtuWGkryPsKsxonV2NQ7Tcj
|
|
|
Gavin Andresen
Legendary
Offline
Activity: 1652
Merit: 2301
Chief Scientist
|
|
March 31, 2011, 12:04:07 PM |
|
Ok.... so Gavin asked me (many times before and now) for the proof that the banking/financial industry avoids floats.
HOW MANY TIMES DO I HAVE TO YELL THIS? ?? Of COURSE you shouldn't use floats internally (unless you are doing something trivial like adding up items in a shopping cart). We are talking about the JSON-RPC api. Which is an api for communicating between bitcoin and other applications, in which all values are turned into strings. So: what are the best practices in the banking world for representing monetary values in strings? As far as I can tell, the answer is "write them out as decimal values and convert them to Decimal() or integer as you read in or write out." Which is exactly what Bitcoin does, and which is what I think we should recommend to people.
|
How often do you get the chance to work on a potentially world-changing project?
|
|
|
BitterTea
|
|
March 31, 2011, 02:54:11 PM |
|
So the difference mainly lies in that the banking world isn't using JSON to shuttle data back and forth.
|
|
|
|
ShadowOfHarbringer
Legendary
Offline
Activity: 1470
Merit: 1006
Bringing Legendary Har® to you since 1952
|
|
March 31, 2011, 03:28:27 PM |
|
Ok.... so Gavin asked me (many times before and now) for the proof that the banking/financial industry avoids floats.
HOW MANY TIMES DO I HAVE TO YELL THIS? ?? Of COURSE you shouldn't use floats internally (unless you are doing something trivial like adding up items in a shopping cart). We are talking about the JSON-RPC api. Which is an api for communicating between bitcoin and other applications, in which all values are turned into strings. Ok, my mistake. So: what are the best practices in the banking world for representing monetary values in strings?
Unfortunately, I do not posess this information.
|
|
|
|
error
|
|
March 31, 2011, 11:55:38 PM |
|
So the difference mainly lies in that the banking world isn't using JSON to shuttle data back and forth.
This is the heart of the issue. JSON is very weakly typed, while much or most financial software is written in strongly typed languages. When a weakly typed language attempts to handle JSON, that large number, with or without a decimal point, may be converted into a floating-point number by the language. So, really, it's the language losing, but we have to somehow deal with it.
|
3KzNGwzRZ6SimWuFAgh4TnXzHpruHMZmV8
|
|
|
BitterTea
|
|
April 01, 2011, 12:04:07 AM |
|
So the difference mainly lies in that the banking world isn't using JSON to shuttle data back and forth.
This is the heart of the issue. JSON is very weakly typed, while much or most financial software is written in strongly typed languages. When a weakly typed language attempts to handle JSON, that large number, with or without a decimal point, may be converted into a floating-point number by the language. So, really, it's the language losing, but we have to somehow deal with it. Then I say in the short term, we deal with JSON's quirks and leave the number as a number (which some languages may treat as a float instead of decimal), but take this into account when designing Bitcoin RPC v2.
|
|
|
|
jgarzik
Legendary
Offline
Activity: 1596
Merit: 1100
|
|
April 01, 2011, 01:22:22 AM |
|
FWIW, this is the python recipe, straight from Python documentation: >>> import decimal >>> json.loads('1.1', parse_float=decimal.Decimal) Decimal('1.1')
|
Jeff Garzik, Bloq CEO, former bitcoin core dev team; opinions are my own. Visit bloq.com / metronome.io Donations / tip jar: 1BrufViLKnSWtuWGkryPsKsxonV2NQ7Tcj
|
|
|
Luke-Jr
Legendary
Offline
Activity: 2576
Merit: 1186
|
|
April 01, 2011, 06:00:04 AM |
|
Then I say in the short term, we deal with JSON's quirks and leave the number as a number (which some languages may treat as a float instead of decimal), but take this into account when designing Bitcoin RPC v2. Exactly: https://en.bitcoin.it/wiki/Wallet_protocol
|
|
|
|
genjix (OP)
Legendary
Offline
Activity: 1232
Merit: 1076
|
|
April 01, 2011, 10:56:42 AM |
|
FWIW, this is the python recipe, straight from Python documentation: >>> import decimal >>> json.loads('1.1', parse_float=decimal.Decimal) Decimal('1.1')
Except Python's JSON-RPC has no support for that. You have to use my (non-standard) modified version: https://en.bitcoin.it/wiki/API_reference_%28JSON-RPC%29#PythonI prefer wherever possible that people stick with official libraries. Bitcoin now is effectively saying that all other languages are broken therefore we won't fix our API. Oh but there's a hack you can use to workaround... It's mostly accurate to the 8th decimal place. Not the point! By exposing an API which nearly all languages interpret as floats, you are expressing a statement of intent that it's fine to use floats for clients (API users). It should be passed as strings (without the decimal point preferably) that users have to explicitly cast to mutable objects. Then they realise that since these values are in INT51 strings (since we can't use large ints in JSON), they'll hopefully understand to deal with the values using ints. You're encouraging users to deal with floats ATM. Bad practice, and shouldn't be encouraged. I am really paranoid about leakage, and for me to even touch a float when dealing with people's money is unacceptable. On Britcoin, there's a whole system of balances and checks at every stage of the various transactions to ensure consistency to all decimal places, and I would not want to throw a spanner in the works because of a tiny rounding error (which would throw up flags and warnings everywhere). Even hearing the words round(...) is like heresy.
|
|
|
|
Gavin Andresen
Legendary
Offline
Activity: 1652
Merit: 2301
Chief Scientist
|
|
April 01, 2011, 11:58:01 AM |
|
I am really paranoid about leakage, and for me to even touch a float when dealing with people's money is unacceptable. On Britcoin, there's a whole system of balances and checks at every stage of the various transactions to ensure consistency to all decimal places, and I would not want to throw a spanner in the works because of a tiny rounding error (which would throw up flags and warnings everywhere). Even hearing the words round(...) is like heresy.
Am I the only person here who looks at our documentation for how to use bitcoin from PHP and thinks "people are going to run away screaming" ? See: https://en.bitcoin.it/wiki/API_reference_(JSON-RPC)I strongly believe you are making the common cases (simple shopping carts or "hold a bitcoin balance for a customer and let them spend it") much, much more complicated than necessary. What do other people think? I'd especially like to hear from people who have prior experience using PHP to implement shopping carts and other simple applications that deal with money. Did you use BCMATH/GMP?
|
How often do you get the chance to work on a potentially world-changing project?
|
|
|
|
Luke-Jr
Legendary
Offline
Activity: 2576
Merit: 1186
|
|
April 01, 2011, 03:35:06 PM |
|
round(100000000 * amount) works fine in PHP. The new Wallet protocol will use ints properly, so this should be good enough.
|
|
|
|
jgarzik
Legendary
Offline
Activity: 1596
Merit: 1100
|
|
April 02, 2011, 06:28:21 AM |
|
See this thread for a python class that handles bitcoin's JSON-RPC, including proper decoding of JSON float-like numbers into python Decimal.
|
Jeff Garzik, Bloq CEO, former bitcoin core dev team; opinions are my own. Visit bloq.com / metronome.io Donations / tip jar: 1BrufViLKnSWtuWGkryPsKsxonV2NQ7Tcj
|
|
|
|
wumpus
|
|
May 21, 2011, 06:06:31 AM |
|
OP is right in that financial software generally uses fixed point instead of floating point (the SQL/Python DECIMAL type). This is because you can guarantee that every picocent is accounted for, when handled correctly there will never be any loss due to precision issues. Twitter had the same problem with their TweetIDs running out of the 53 bit range that JSON is able to represent with numbers. They opted with using strings: http://blog.programmableweb.com/2010/10/19/the-twitter-id-shuffle-text-vs-numbers/Bytemaster: yes, it is out of date. No rounding happens in AmountFromValue.
|
Bitcoin Core developer [PGP] Warning: For most, coin loss is a larger risk than coin theft. A disk can die any time. Regularly back up your wallet through File → Backup Wallet to an external storage or the (encrypted!) cloud. Use a separate offline wallet for storing larger amounts.
|
|
|
|