Pages:
Author

Topic: why JSON RPC values not use INT64 instead of float string? (Read 18432 times)

hero member
Activity: 812
Merit: 1022
No Maps for These Territories
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.
hero member
Activity: 770
Merit: 566
fractally
https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_Calls_list says that the sendtoaddress and sendfrom "rounds to the nearest 0.01"   

I am guessing that this documentation is out of date?   Is the a new, "non original",  RPC documentation?
legendary
Activity: 1596
Merit: 1100
See this thread for a python class that handles bitcoin's JSON-RPC, including proper decoding of JSON float-like numbers into python Decimal.
legendary
Activity: 2576
Merit: 1186
round(100000000 * amount) works fine in PHP. The new Wallet protocol will use ints properly, so this should be good enough.
legendary
Activity: 1232
Merit: 1076
Instead of removing all of this:

https://en.bitcoin.it/w/index.php?title=PHP_developer_intro&action=historysubmit&diff=6404&oldid=5737

Maybe we should add it to the bottom of the page, with an opening paragraph about how it isn't strictly necessary, but can help avoid problems. Because I did take time to write that for people, and doubtless others will find it useful, but not everyone may wish to use it Wink
legendary
Activity: 1652
Merit: 2301
Chief Scientist
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?
legendary
Activity: 1232
Merit: 1076
FWIW, this is the python recipe, straight from Python documentation:

Code:
>>> 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#Python

I 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.
legendary
Activity: 2576
Merit: 1186
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
legendary
Activity: 1596
Merit: 1100
FWIW, this is the python recipe, straight from Python documentation:

Code:
>>> import decimal
>>> json.loads('1.1', parse_float=decimal.Decimal)
Decimal('1.1')
sr. member
Activity: 294
Merit: 252
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.
hero member
Activity: 588
Merit: 500
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.
legendary
Activity: 1470
Merit: 1006
Bringing Legendary Har® to you since 1952
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?Huh??

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.
sr. member
Activity: 294
Merit: 252
So the difference mainly lies in that the banking world isn't using JSON to shuttle data back and forth.
legendary
Activity: 1652
Merit: 2301
Chief Scientist
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?Huh??

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.
legendary
Activity: 1596
Merit: 1100
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.

sr. member
Activity: 294
Merit: 252
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.
legendary
Activity: 1470
Merit: 1006
Bringing Legendary Har® to you since 1952
Ok.... so Gavin asked me (many times before and now) for the proof that the banking/financial industry avoids floats.

And i have found it !!

http://en.wikipedia.org/wiki/Floating_point#Minimizing_the_effect_of_accuracy_problems

Quote
Binary floating-point arithmetic is at its best when it is simply being used to measure real-world quantities over a wide range of scales (such as the orbital period of a moon around Saturn or the mass of a proton), and at its worst when it is expected to model the interactions of quantities expressed as decimal strings that are expected to be exact. An example of the latter case is financial calculations. For this reason, financial software tends not to use a binary floating-point number representation.[7] The "decimal" data type of the C# and Python programming languages, and the IEEE 754-2008 decimal floating-point standard, are designed to avoid the problems of binary floating-point representations when applied to human-entered exact decimal values, and make the arithmetic always behave as expected when numbers are printed in decimal.

The [7] reference leads here:
http://speleotrove.com/decimal/

--------------
I think we can call the topic closed.
Let's go string baby !
legendary
Activity: 1470
Merit: 1006
Bringing Legendary Har® to you since 1952
Well, OK. You've got a point.
Still, no big deal.

After everybody starts using strings instead of floats (and they will, because floats are seen as VERY unprofessional in the industry), we may remove the old float mode completely.
However no hurry there, it may wait a few years.

If this change was made, any code using the API must first determine the API version, and then handle numbers in two different ways. No thanks.

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.
hero member
Activity: 588
Merit: 500
No, they would just have their single "JSON-RPC value to raw bitcoins" function check the type of the argument and react appropriately. However, using strings is even MORE unprofessional than floats.

The language may not give you a choice in the matter. Hello?
legendary
Activity: 2576
Merit: 1186
No, they would just have their single "JSON-RPC value to raw bitcoins" function check the type of the argument and react appropriately. However, using strings is even MORE unprofessional than floats.
Pages:
Jump to: