5

I ran this simple program, but when I convert from int to double, the result is zero. The sqrt of the zeros then displays negative values. This is an example from an online tutorial so I'm not sure why this is happening. I tried in Windows and Unix.

/* Hello World program */

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

main()

{  int i;

   printf("\t Number \t\t Square Root of Number\n\n");

   for (i=0; i<=360; ++i)
        printf("\t %d \t\t\t %d \n",i, sqrt((double) i));


}
Borealid
  • 95,191
  • 9
  • 106
  • 122
user994165
  • 9,146
  • 30
  • 98
  • 165
  • 8
    Can you post your code. – hmjd Jan 28 '12 at 19:09
  • 3
    Without the code in question, this cannot be answered meaningfully. – Jonathan Grynspan Jan 28 '12 at 19:17
  • sqrt never returns negative values. Your problems run very deep. The fact that you don't realise that we would need to see your code to answer this is your fundamental problem. I hope you don't think that the computer can do the same! – David Heffernan Jan 28 '12 at 19:26
  • 2
    David, actually you should realize that there is another possibility and that is that I forgot to include the code originally. Please leave your condescending attitude off of this board. – user994165 Jan 28 '12 at 20:14
  • 2
    I'm sorry to have offended you. I was too harsh. But there's a grain of truth in there too. Sometimes it pays to go a bit more slowly. Check and double check when coding, and when writing questions, and, in my case, when writing comments. – David Heffernan Jan 28 '12 at 21:06

3 Answers3

20

Maybe this?

int number;
double dblNumber = (double)number;
Erick Smith
  • 937
  • 7
  • 27
  • This is, indeed, how one converts a number to a double, but that's not the asker's issue. – Borealid Jan 28 '12 at 21:05
  • 13
    Oddly, the title of his question was. Oh well. – Erick Smith Jan 28 '12 at 22:34
  • No need to add the cast `(double)` as you've already annotated the type and the compiler will implicitly do the cast. Alternatively, you could just change the type annotation to `auto dblNumber = (double)number;`, this way you don't have to "maintain" the type in two places (in case you want to change it to say a `float` later). – Michael Hall Jan 18 '23 at 23:42
8

The problem is incorrect use of printf format - use %g/%f instead of %d

BTW - if you are wondering what your code did here is some abridged explanation that may help you in understanding:

printf routine has treated your floating point result of sqrt as integer. Signed, unsigned integers have their underlying bit representations (put simply - it's the way how they are 'encoded' in memory, registers etc). By specifying format to printf you tell it how it should decipher that bit pattern in specific memory area/register (depends on calling conventions etc). For example:

unsigned int myInt = 0xFFFFFFFF;
printf( "as signed=[%i] as unsigned=[%u]\n", myInt, myInt );

gives: "as signed=[-1] as unsigned=[4294967295]"

One bit pattern used but treated as signed first and unsigned later. Same applies to your code. You've told printf to treat bit pattern that was used to 'encode' floating point result of sqrt as integer. See this:

float myFloat = 8.0;
printf( "%08X\n", *((unsigned int*)&myFloat) );

prints: "41000000"

According to single precision floating point encoding format. 8.0 is simply (-1)^0*(1+fraction=0)*2^(exp=130-127)=2*3=8.0 but printed as int looks like just 41000000 (hex of course).

Artur
  • 7,038
  • 2
  • 25
  • 39
3

sqrt() return a value of type double. You cannot print such a value with the conversion specifier "%d".

Try one of these two alternatives

        printf("\t %d \t\t\t %f \n",i, sqrt(i)); /* use "%f" */
        printf("\t %d \t\t\t %d \n",i, (int)sqrt(i)); /* cast to int */

The i argument to sqrt() is converted to double implicitly, as long as there is a prototype in scope. Since you included the proper header, there is no need for an explicit conversion.

pmg
  • 106,608
  • 13
  • 126
  • 198
  • I do not understand why it works with to give an `int` to `sqrt()` tough, because `sqrt()` is declared as to only take a `double` value as an argument. In C99: `double sqrt (double x);` How does that work and my compiler let it pass? – RobertS supports Monica Cellio Dec 12 '19 at 17:37
  • 1
    @RobertS: Because you included `` the compiler knows the argument to `sqrt()` must be `double`, so the compiler does the conversion automatically. Using `sqrt()` (or any function really) without a prototype in scope should be considered an error. – pmg Dec 12 '19 at 22:00
  • Thank you very much. I also posted a question about this issue here: https://stackoverflow.com/questions/59310504/sqrt-why-am-i-allowed-to-provide-an-argument-of-int-and-not-only-double-and . If you want an upvote plus for your answer, which i like to give, you can post your answer also there and make it also available to read for others who have the same issue. – RobertS supports Monica Cellio Dec 13 '19 at 10:10