2

I am trying to calculate

Pow(500.9, 500) 

We have to apply the BigInteger since the result is too big, which cannot be stored in a double number. The function of BigInteger.Pow can only handle the int base. However, if I round up the 500.9 to 501 using BigInteger.Pow, the result is not accurate. Any solutions for this problem? I really appreciate your help.

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
Savannah
  • 17
  • 3

1 Answers1

3

Well, a simple math points that

Pow(500.9, 500) == 
Pow(500.9 * 10 / 10, 500) ==
Pow(5009, 500) / Pow(10, 500) 

To compute this we can find Pow(5009, 500) and then put decimal separator at 500th place from the end:

string result = BigInteger.Pow(5009, 500).ToString();

result = result.Insert(result.Length - 500, ".");

Console.Write(result);

Output:

750785445202605307551253470824557285079346141278253125349630916911102629784128353477046312312139991342483037173482291298447969374891762042213004550901213358906920823544239557942277642992418402027235207483978041724163203346373588053756209213942565309839746527277599653268123724065365736267603060792245369511389263528845304955028803457277541404450374376491026784895296528446631879758096537079470156394038766525798644691360860393275159196110019913158557641568463246836543848010042581862005580178182419159111411274780602462456946017405314984839399675700027333811670420218809911730919098335927962554486605331923267502046059868271480909938360412846494392224098433297979335673495582626311033202777716546962816215115507687918498469675860909461733227525421068802715771021509767836615249121028542984981342453460443523075418990759647964559677485474850638903218226595363531541872512909635249994105022233957793123983861456686877077495391968938174248672172171747206468768722350493285374053243583268519335772918970507587718609210192894955099357133994455750654224318578714399994951501786601269165863137887223331163954437472113772110816826584893190483662068782179976702789430846986139489196790252331369863403232574645627158879279400354165150390251105544837645530114608594348391176662657558839549725079904808639006147551104172868473502336489851592919793073838330652965.53619162155847566828667939093878911641328992161770443232303925735316732676142337778523013482948880367979630680335116340416796542017601634717186990927160028803022480589471690500902042621936161340068475197228470218993384159712513440518292617565712476401913018477651802587875796196911894824156301999091492950154683229359766451353055795532013751196008324853727367989462377366072256612433437992797704997150495960526770895405960457961474456531750042325103620310035959468546595071741128017753593693827720001
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • 1
    @Poul Bak: yes, we can use `BigInteger.DivRem` to obtain both *integer* and *fractional* parts which we can combine into the final answer: `var div = BigInteger.DivRem(BigInteger.Pow(5009, 500), BigInteger.Pow(10, 500), out var rem);` and then `var result = $"{div}.{rem}"`. May be it's a bit faster but i don't think this kind of microoptimisation is that valuable – Dmitry Bychenko Jul 27 '22 at 18:46
  • `ToString()` is slow *because* it has to divide by powers of 10 and round. @PoulBak why would you think that dividing by powers of 10 yourself is faster than dividing by powers of 10 inside `ToString()` ? Plus it isn't "500 too many digits", those are part of the answer. – Ben Voigt Jul 27 '22 at 19:13
  • Yeah, you're right, I now see that he wants the fractional part too. – Poul Bak Jul 27 '22 at 19:18