0

I am writing code to find the distance of a point(25,40000) from a fixed point(47,132000). The distance always printed to be 0.0000. I have tried checking other combinations, giving smaller values of points, and printing them with %d, it works great. But with %ld,%lf,%Lf something is not fine. Kindly help.

#include<stdio.h>
#include<math.h>

int main()
{
   int x=25,y=40000;  
   //printf("Enter x,y");
   //scanf(%d %d,&x,&y) 
   long double dist;
   dist=sqrt((47-x)*(47-x)+(132000-y)*(132000-y));   
   printf(" x= %d y=%d dist=%Lf\n",x,y,dist);
   return 0;
}
  • 1
    Change the type int of the variables from int to the type long long int. – Vlad from Moscow Jun 03 '20 at 19:27
  • Have you looked at the value actually being passed to `sqrt`? I wouldn't be surprised if it's not what you expect. – Thomas Jager Jun 03 '20 at 19:27
  • 1
    you have many typos, you should take care of that. – snatchysquid Jun 03 '20 at 19:27
  • A BIG plus for commenting out the input and replacing it with hard coded values. That's really good. – klutt Jun 03 '20 at 19:31
  • @snatchysquid I only see `dust`->`dist` (on top of missing includes) – Thomas Jager Jun 03 '20 at 19:34
  • 1
    But yeah, copy the code from your editor to make sure that it compiles. Create a [mre] – klutt Jun 03 '20 at 19:35
  • 1
    Please copy/paste your *exact code*, the [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example), the shortest *complete* code that shows the problem. Not something that you think might be the same. – Weather Vane Jun 03 '20 at 19:38
  • @Apoorva Jain Why change the question after a good answer? Now the question no longer makes sense with the answer. Reccomend to rollback your edit. – chux - Reinstate Monica Jun 03 '20 at 20:45
  • @chux-ReinstateMonica, Yes I got your point, but the purpose of doing that was at that time of point I didn't know that code would work fine as it was giving the same wrong answer. Now, it seems that it was a compiler error, and using double instead of long double works perfectly. – Apoorva Jain Jun 03 '20 at 20:54
  • @ApoorvaJain OK, but why accept an answer that does not answer with the `long double/double` issue? – chux - Reinstate Monica Jun 03 '20 at 21:51
  • In case you are using gcc for windows, there are some issues with long double, [see here](https://stackoverflow.com/a/27336581/1505939) – M.M Jun 03 '20 at 21:56
  • By the way, `sqrt(3)` is a function that requires a `double` parameter, and you are passing an expression full of integer values. The compiler does automatic conversion to a `double` but have you had some division and you would get another surprise on integer division. I you are working wiht floating point, please, use floating point literals (`10000` is an integer literal, while `10000.0` is a `double` floating point literal) – Luis Colorado Jun 05 '20 at 14:13

1 Answers1

0

Integer overflow takes place in your code. The below code works -

int main()
{
   long long int x=25,y=40000;       //int was overflowing and causing you error
   long double dist;
   dist=sqrt((47-x)*(47-x)+(132000-y)*(132000-y));   //this will safely compute within range and return the desired result
   printf("After distance\n");
   printf(" x= %lld y=%lld dist=%Lf\n",x,y,dist);
   return 0;
}

You were getting wrong output(-nan when I tried out ) because the expression value inside sqrt() was overflowing and becoming negative. (132000-y)*(132000-y) won't fit in an integer range and give negative value. Since, negative square root is not defined, sqrt() returned nan as the result. Changing the type of y to long long int will solve the error.

Hope this helps !

Abhishek Bhagate
  • 5,583
  • 3
  • 15
  • 32
  • You may want to give more explanation of what's happening. While it's true that a 16-bit `int` can't hold 40000, that's only part of it. The multiplication that involves `y` can also overflow a 32-bit `int`. On most modern platforms, this is probably the issue encountered. – Thomas Jager Jun 03 '20 at 19:37
  • @ThomasJager I added proper explanation. See if it's correct and tell me if I missed adding something. – Abhishek Bhagate Jun 03 '20 at 19:39
  • (I finished writing just before the last edit) Your edited answer isn't quite correct. If the only issue was that `y` was negative, the fact that it's being subtracted from another number would ensure a positive result being passed to `sqrt`. Regardless of the original value of `int y`, `(132000-y)` is a 32-bit integer (on conventional platforms). This result will overflow, leading to UB. This is why simply using `long int` for `x` and `y` isn't enough, since you're only guaranteed the range [−2,147,483,647, +2,147,483,647]. While this can easily hold 40000, it's not enough for the mult. – Thomas Jager Jun 03 '20 at 19:46
  • `long long int` can hold values upto 9223372036854775807 . The overflow isn't because `40000` can't fit into y but rather because it can't hold the product `(132000-y)*(132000-y)`. Making it `long long int` would be enough to hold the value. So, it will **work in most cases** unless you are also willing to work beyond the range `9223372036854775807 ` where you will have to implement big integers. – Abhishek Bhagate Jun 03 '20 at 19:51
  • @Abhishek The edited code you provided is also showing the same output 0.0000. – Apoorva Jain Jun 03 '20 at 20:03
  • @ApoorvaJain Working fine on my IDE. Check here as well - https://ide.geeksforgeeks.org/GqdtuWkUgm – Abhishek Bhagate Jun 03 '20 at 20:04
  • @Abhishek, Yes I checked it. Thank You. It's working fine on GeeksForGeeks IDE, but not on my Dev C++ 5.11 – Apoorva Jain Jun 03 '20 at 20:18
  • @ApoorvaJain Just try assigning something like `dist=1.2;` and check if its still printing 0. – Abhishek Bhagate Jun 03 '20 at 20:24
  • @Abhishek I tried with assigning values, but it didn't work better, it was the same 0.0000, but on changing long double to double and %Lf to %lf, it gave correct result. – Apoorva Jain Jun 03 '20 at 20:39
  • Yes, it's probably due to compiler problem and using double would probably do your job. Check these - http://bytes.com/topic/c/answers/135253-printing-long-double-type-via-printf-mingw-g-3-2-3-a. https://stackoverflow.com/questions/4089174/printf-and-long-double. Switching to different IDE/changing compiler would allow you to use `long double` – Abhishek Bhagate Jun 03 '20 at 20:43
  • `long double` has no code use here as the `sqrt()` takes and returns a `double`. Use `double list;`. – chux - Reinstate Monica Jun 03 '20 at 20:44
  • @chux-ReinstateMonica right! you must use `sqrtl()` if you want to get `long double` – Abhishek Bhagate Jun 03 '20 at 21:07