0

So i read that long double is 128bit But look at this code

long double MaxLatticePaths(int xSize, int ySize)
{
    long double sumMLP = 1;
    long double halfling = xSize;
    long double halfling2 = (xSize + ySize) - xSize;
    for (int i = xSize + ySize; i > 0; i--)
    {
        sumMLP = sumMLP * (i / halfling / halfling2);
        if (halfling > 1)
        {
            halfling--;
        }
        if (halfling2 > 1)
        {
            halfling2--;
        }
    }
    return sumMLP;
}
int main()
{
    cout.precision(2000);
    cout << "\n" << MaxLatticePaths(2141, 2140) << "\n";
}

Output:

16315190298711506445464892598264322618004530270611808484780866384528342404142990947031068675180336432315693066114864362480616838595308779982326735844228704193859747658947455525469514212503972044689315566655370373661400711012020016116439559215383460785418453783899764258637079659818638577531691811097773176843497403749098178590357084265715939224640515837766721249964445425407422907713026146366955975530262422859128904600571726957991140807350490417141873207653107811667562463379032199939454947412011560169185406695112167355329690269203438031734174053765724124238771087854348059881325098161615945676620050984397854854452121645886626946657578990304834766661898136369869041936431091596482074847082061571981466253927611353079662496250812546118348009094113018221097833896823648389238307188213648816781186867374971727011472177232520488240752431293118492945262684802421055224211805518127741826303341935999960697567403126622636027961181349146209938242790709547705154379310869350978424238929211385961129809235418155295715641938448321789932432238943131503779648687971230484265855387248678802953305867827800519050353584130082264868408673861330156408398501291948396647365847353078278930897136242755569528982861528875154727717184788894566681318361398503312000918432261678422910400507459471524759366270976

Any higher than 2141, 2140 and it overflows. But how? This is like 1288 digits, 128bit is only 38digits. Obviously there is something wrong in my code, because i wrote another simple program and assigned a larger but nowhere near this size digit and it overflowed. Can someone point out what's the bug in my code?

  • Most of those digits are not significant in the sense that the next representable values will probably change most of those digits. Your number is not actually as precise as this output makes it seem. – François Andrieux Oct 07 '20 at 13:41
  • If your `long double` is 128-bit IEEE754 value, it can hold numbers up to 4931 decimal digits. – Yksisarvinen Oct 07 '20 at 13:43
  • @Yksisarvinen But how? It's only 128bit how can it hold so many decimals. If you know someplace that explains it can u give me a link? – pagh282 Oct 07 '20 at 13:46
  • @rustyx Then how am i getting this ouput. Also why did you say `113bits`? It's `128bits` – pagh282 Oct 07 '20 at 13:47
  • @pagh282 That comment is misleading. It can represent values whose decimal representation would require that many digits, but it does not store that many digits. Think of it as storing values using scientific notation. 1E5000 would need 5001 digits to be represented completely, but I just represented it with 6 characters instead in exchange for a loss of resolution. – François Andrieux Oct 07 '20 at 13:48
  • @pagh282 Not all 128 bits will be used for the fraction (significant digits), some bits are used for sign and exponent. – François Andrieux Oct 07 '20 at 13:48
  • @rustyx Uh, I guess I need some more vocabulary to talk about that. I meant you can store a number up to `1e4931`, while losing precision the further you go. – Yksisarvinen Oct 07 '20 at 13:49
  • But wouldn't it still need the actual 5000 digits to do computations with it? Because when i print my number without the `cout.precision()` it gives `1.63152e+1288`, But when i enable cout precision, but it also prints non zero numbers well after the 38th digits, so it still does computations on it but how? – pagh282 Oct 07 '20 at 13:51
  • 1
    @pagh282 It would *if* mathematical operations on `double` were exact. They are not, floating point arithmetic are generally approximations. See [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken). Edit : The extra digits are artifacts of the conversion to decimal representation. It is a little bit like if you print `1/3` it can yield infinite digits. Those digits did not require individual storage in the `1/3` expression. I'm not sure of the specifics of how printing IEEE754 works, so I'm not sure exactly how those digits are generated. – François Andrieux Oct 07 '20 at 13:54
  • Maybe [this example](https://godbolt.org/z/PGjGTf) will help clear up the confusion. In the first loop [`std::nextafter`](https://en.cppreference.com/w/cpp/numeric/math/nextafter) produces the next possible value that the type can represent. Notice that most digits are changed between values. The second loop tries to demonstrate that there are no values between those steps. Adding 1 to `x` rounds to the nearest representable value, which is the value `x` already had. Since `x` is too large, `x + 1 == x` in this case. Edit : Fixed the example link. – François Andrieux Oct 07 '20 at 14:07
  • One thing that helped me in understanding why floating points sometimes behave strangely, was finding out that 1/10 = 0.1 is not possible to represent in binary floating point. The closest representation of 0.1 in binary floating point is `0.0001100110011` (repeating infinitely) - remember that in that number, the first 0 after the decimal point represents 1/2, then next is 1/4 and so on. – Frodyne Oct 07 '20 at 14:21
  • 1
    Calculations with floating-point numbers are exact, but they are in the realm of floating point numbers. Floating-point numbers are not real numbers. Most of the intuition you've developed during your life about how numbers work doesn't apply to floating-point numbers. You're comfortable with the notion that 1/3 is 0, because you've been bitten by integers not being real numbers. Same thing for floating-point -- you have to deal with it on its own terms. – Pete Becker Oct 07 '20 at 15:44

0 Answers0