Question

I want to avoid any precision errors when doing math on bitcoin values.

1) Is 'decimal' the best option to use for bitcoin currency in C#?

2) When converting from string to number, are there any precision errors I need to be aware of?

Thanks

Was it helpful?

Solution

Bitcoin amounts can range from 1 Satoshi (0.00000001 BTC) to nearly 2,100,000,000,000,000 (21,000,000 BTC). To avoid rounding errors, you must make sure your PHP implementation supports the full range of Bitcoin values without losing precision. Most PHP implementations use IEEE 64-bit double-precision floating point numbers with 53 bits of precision, which is enough to correctly represent the full range of bitcoin values.

Even-though this is related to PHP, it is still relevant. As suggested, you should use Decimal value type.

The last block that will generate coins will be block #6,929,999 which should be generated at or near the year 2140. The total number of coins in circulation will then remain static at 20,999,999.9769 BTC. Even if the allowed precision is expanded from the current 8 decimals, the total BTC in circulation will always be slightly below 21 million (assuming everything else stays the same). For example, with 16 decimals of precision, the end total would be 20,999,999.999999999496 BTC.

An example of a String being converted to Decimal and keeping precision:

var maxBtc = "20999999.999999999496";
var maxBtcDecimal = Decimal.Parse(maxBtc, NumberStyles.AllowDecimalPoint);

Converting back:

var maxBtcString = Convert.ToString(maxBtcDecimal);

Simple math:

var oneBtc = new decimal(1.000000000000);
var newBtcValue = maxBtcDecimal - oneBtc;

OTHER TIPS

Decimal is the best option available.

Take a look at this working C# bitcoin library that uses Decimal for bitcoin values: https://github.com/GeorgeKimionis/BitcoinLib

You need to be aware that in C# Decimal is not fixed-floating so you need to configure your O/RM or your DB to keep exactly 8 decimal points.

From MSDN

Compared to floating-point types, the decimal type has more precision and a smaller range, which makes it appropriate for financial and monetary calculations.

If you are doing mathematical operations on Bitcoin amounts, you should use Decimal.

Decimal.Parse()

should be used to convert from string to Decimal. See also this other Stackoverflow question

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top