sqrt() of int type in C
Asked Answered
P

4

5

I am programming in the c language on mac os x. I am using sqrt, from math.h, function like this:

int start = Data -> start_number;
double localSum;

for (start; start <= end; start++) {
    localSum += sqrt(start);
}

This works, but why? and why am I getting no warning? On the man page for sqrt, it takes a double as parameter, but I give it an int - how can it work?

Thanks

Pandora answered 1/11, 2012 at 13:58 Comment(0)
S
11

Type conversions which do not cause a loss in precision might not throw warnings. They are cast implicitly.

int --> double //no loss in precision (e.g 3 became 3.00)
double --> int //loss in precision (e.g. 3.01222 became 3)

What triggers a warning and what doesn't is depends largely upon the compiler and the flags supplied to it, however, most compilers (atleast the ones I've used) don't consider implicit type-conversions dangerous enough to warrant a warning, as it is a feature in the language specification.


To warn or not to warn:

C99 Rationale states it like a guideline

One of the important outcomes of exploring this (implicit casting) problem is the understanding that high-quality compilers might do well to look for such questionable code and offer (optional) diagnostics, and that conscientious instructors might do well to warn programmers of the problems of implicit type conversions.

C99 Rationale (Apr 2003) : Page 45

Sthenic answered 1/11, 2012 at 13:59 Comment(11)
“As it does not list conversion of int to double” It certainly does, for instance in C99's 6.3.1 clause. I do not know what eli-project is, but either you are misinterpreting what it means or it is not an accurate formalization of the C standard(s) yet.Vassal
That was C89 I think, the one referred to as ANSI CSthenic
Ok, I'll try to unravel it. 6.5.2.2:4 An argument may be an expression of any object type. In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument.Vassal
6.5.16.1 Simple assignment 1. One of the following shall hold: the left operand has qualified or unqualified arithmetic type and the right has arithmetic type;Vassal
6.5.16.1:2 In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand. [emphasis mine]Vassal
@PascalCuoq These just say implicit conversions happen. The actual conversions that are allowed implicitly don't seem to be mentioned. Thanks :)Sthenic
6.3 Conversions 1. Several operators convert operand values from one type to another automatically. This subclause [6.3] specifies the result required from such an implicit conversion, as well as those that result from a cast operation (an explicit conversion).Vassal
6.3.1.4:2 When a value of integer type is converted to a real floating type, if the value being converted can be represented exactly in the new type, it is unchanged. If the value being converted is in the range of values that can be represented but cannot be represented exactly, the result is either the nearest higher or nearest lower representable value, chosen in an implementation-defined manner. If the value being converted is outside the range of values that can be represented, the behavior is undefined.Vassal
No, it does not say that the conversion from int to float is any different in philosophy from the conversion from int to double, and any formalization that implies this is not an accurate formalization of C99 or later (I have to admit I am not willing to dig into C90).Vassal
I had thought the Eli project had accurately specified the standard in their OIL specification but turns out they haven't. Thank you for pointing that out.Sthenic
If you are into this sort of thing, one recent and accurate formalization of C11 is code.google.com/p/c-semantics . I haven't read it, but I have used the interpreter derived from its rules.Vassal
C
3

The compiler knows the prototype of sqrt, so it can - and will - produce the code to convert an int argument to double before calling the function.

The same holds the other way round too, if you pass a double to a function (with known prototype) taking an int argument, the compiler will produce the conversion code required.

Whether the compiler warns about such conversions is up to the compiler and the warning-level you requested on the command line.

For the conversion int -> double, which usually (with 32-bit (or 16-bit) ints and 64-bit doubles in IEEE754 format) is lossless, getting a warning for that conversion is probably hard if possible at all.

For the double -> int conversion, with gcc and clang, you need to specifically ask for such warnings using -Wconversion, or they will silently compile the code.

Comminute answered 1/11, 2012 at 14:12 Comment(0)
A
1

Int can be safely upcast automatically to a double because there's no risk of data loss. The reverse is not true. To turn a double to an int, you have to explicitly cast it.

Amur answered 1/11, 2012 at 13:59 Comment(1)
int foo = 42.3; no cast needed. (very often casts are wrong in C)Inadvertent
A
0

C-compilers do some automatic casting with double and int. you could also do the following:

int start = Data -> start_number;
int localSum;

for (start; start <= end; start++) {
   localSum += sqrt(start);
}

Even if the localSum is an int this will still work, but it will always cut of anything beyond the point.
For example if the return value of sqrt() is 1.365, it will be stored as a simple 1.

Airs answered 1/11, 2012 at 14:2 Comment(1)
I said "could" not "should". It would just demonstrate the effect of implicite casting.Airs

© 2022 - 2024 — McMap. All rights reserved.