Number changes when converting Double to Numerics.BigInteger

时光怂恿深爱的人放手 提交于 2019-12-12 03:22:46

问题


using System.Numerics;

double doubleNumber = Math.Pow(1000, 99); // = 1.0E+297
BigInteger bigBase = (BigInteger)bigNumber; // = 1000000000000000017652801462756379714374878780719864776839443139119744823869255243069012222883470359078822072829219411228534934402712624705615450492327979456500795456339201761949451160807447294527656222743617592048849967890105831362861792425329827928397252374398383022243308510390698430058459037696

Why is the BigInteger value not just 1 kagillion (1,000 followed by a bagillion 0's)?


回答1:


The implementation of BigInteger uses a lot of bit shifting, so when you convert a double to a BigInteger, the double representation has a finite set of bits (64 bits in for a double), so not all the bits are there to accurately represent the value.

Instead of using Math.Pow, you should be using

var bigBase = BigInteger.Pow(1000, 99);

Also, explicitly casting a numeric type to a BigInteger is the same as using the BigInteger constructor:

 var bigBase = (BigInteger)doubleNumber;

Is equivalent to:

var bigBase = new BigInteger(doubleNumber);



回答2:


System.Double only has 15 decimal digits of precision, which means the value will be close to the actual value, but might not be precise.

It all has to do with how floating point values are encoded in order to occupy a fixed amount of memory.

This is exactly the same problem which lets 1.0 end up as 0.999999999999999999etc.

If you need absolute precision, you need to use a library/type which has that, double has not.

For your specific code, you might want to do this:

BigInteger bigBase = BigInteger.Pow(1000, 99);


来源:https://stackoverflow.com/questions/9489902/number-changes-when-converting-double-to-numerics-biginteger

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!