Does C have function to get angle?

V

Vol

I think 'atan' can get the angle but it is not the four quadrant angle.
Is there any function that i can get the angle from -pi to pi? or I
have to use some if ... else?
I know in Matlab, we use 'atan2( )'

Also, is there any function to get the round value, similar with floor
and ceil, such like:

round(3.1) = 3
round(3.6) = 4

thanks..

Vol
 
C

Christopher Benson-Manica

Vol said:
I think 'atan' can get the angle but it is not the four quadrant angle.
Is there any function that i can get the angle from -pi to pi? or I
have to use some if ... else?
I know in Matlab, we use 'atan2()'

atan2() also exists in C, although I can't say whether it's identical
to the MatLab function you're referencing.
 
W

William Hughes

Vol said:
I think 'atan' can get the angle but it is not the four quadrant angle.
Is there any function that i can get the angle from -pi to pi? or I
have to use some if ... else?
I know in Matlab, we use 'atan2( )'

Also, is there any function to get the round value, similar with floor
and ceil, such like:

round(3.1) = 3
round(3.6) = 4

thanks..

Vol


atan2(y,x) exists in C (and Matlab and Octave and Python and ...
I think all of these simply call the C function).
Take care because atan2(0,0) is undefined, some
implementations will return 0, some will crash (I think the DS2K does
a Morris Dance).

If you need to round x use floor(x + 0.5). (If you care about why
this is not perfect you already know why)

- William Hughes
 
D

DevarajA

William Hughes ha scritto:
atan2(y,x) exists in C (and Matlab and Octave and Python and ...
I think all of these simply call the C function).
Take care because atan2(0,0) is undefined, some
implementations will return 0, some will crash (I think the DS2K does
a Morris Dance).

If you need to round x use floor(x + 0.5). (If you care about why
this is not perfect you already know why)

Can you tell me why?
 
W

William Hughes

DevarajA said:
William Hughes ha scritto:

Can you tell me why?

It is possible if x is less than 0.5 (but very close) for
x+0.5 to be greater than or equal to 1 in which case
floor(x+0.5) will be 1 rather than 0.

Also, it is not in general possible to represent a decimal
fraction exactly, so an implementation may represent

0.4999999999999999

as a floating point number greater than or equal to 0.5
in which case

floor(0.4999999999999999 + 0.5)

will be 1 rather than 0.

Question. Do you care?

-William Hughes
 
D

DevarajA

William Hughes ha scritto:
[cut]
It is possible if x is less than 0.5 (but very close) for
x+0.5 to be greater than or equal to 1 in which case
floor(x+0.5) will be 1 rather than 0.

Also, it is not in general possible to represent a decimal
fraction exactly, so an implementation may represent

0.4999999999999999

as a floating point number greater than or equal to 0.5
in which case

floor(0.4999999999999999 + 0.5)

will be 1 rather than 0.

Ok, thank you.
Question. Do you care?

Yes. I like precision.
 
W

William Hughes

DevarajA said:
William Hughes ha scritto:
[cut]
It is possible if x is less than 0.5 (but very close) for
x+0.5 to be greater than or equal to 1 in which case
floor(x+0.5) will be 1 rather than 0.

Also, it is not in general possible to represent a decimal
fraction exactly, so an implementation may represent

0.4999999999999999

as a floating point number greater than or equal to 0.5
in which case

floor(0.4999999999999999 + 0.5)

will be 1 rather than 0.

Ok, thank you.
Question. Do you care?

Yes. I like precision.

How much?
 
J

Joe Wright

William said:
It is possible if x is less than 0.5 (but very close) for
x+0.5 to be greater than or equal to 1 in which case
floor(x+0.5) will be 1 rather than 0.

Also, it is not in general possible to represent a decimal
fraction exactly, so an implementation may represent

0.4999999999999999

as a floating point number greater than or equal to 0.5
in which case

floor(0.4999999999999999 + 0.5)

will be 1 rather than 0.

Question. Do you care?

-William Hughes
Your example is a little flawed. First, 0.5 is exactly representable in
binary floating point. Your constant, 0.4999999999999999 looks like
4.9999999999999989e-01 on my machine. Less than 0.5 of course. If you're
curious, the binary of the 64-bit double is..

0011111111011111111111111111111111111111111111111111111111111110

...The binary of 0.5 is..

0011111111100000000000000000000000000000000000000000000000000000

...Close, no cigar.

If you add one more '9' to the constant it will "round up" to 0.5 and
your example will be true. As it is, floor(0.4999999999999999 + 0.5)
yields 0.0, not 1.0 here at my house.

Question. Do you care?
 
W

William Hughes

Joe said:
Your example is a little flawed. First, 0.5 is exactly representable in
binary floating point. Your constant, 0.4999999999999999 looks like
4.9999999999999989e-01 on my machine. Less than 0.5 of course. If you're
curious, the binary of the 64-bit double is..

0011111111011111111111111111111111111111111111111111111111111110

..The binary of 0.5 is..

0011111111100000000000000000000000000000000000000000000000000000

..Close, no cigar.

If you add one more '9' to the constant it will "round up" to 0.5 and
your example will be true. As it is, floor(0.4999999999999999 + 0.5)
yields 0.0, not 1.0 here at my house.


And this is a counterexample to my statement

so an implementation may represent

0.4999999999999999

as a floating point number greater than or equal to 0.5

how?
 
J

Joe Wright

William said:
And this is a counterexample to my statement

so an implementation may represent

0.4999999999999999

as a floating point number greater than or equal to 0.5

how?
I thought I was clear. Again, evaluation of 0.4999999999999999 does not
evaluate to double >= to 0.5 but if evaluated to float it may round up
to 0.5 but there is no case that I know of where it will be greater than
0.5. Is there such a case?
 
W

William Hughes

Joe said:
I thought I was clear. Again, evaluation of 0.4999999999999999 does not
evaluate to double >= to 0.5 but if evaluated to float it may round up
to 0.5 but there is no case that I know of where it will be greater than
0.5. Is there such a case?

I do not know.

reread carefully

so an implementation may represent

Note that this says may. The word "may" does not indicate that
any given implementation does, or indeed that there exists an
implemenation that does. It just means that according to the
standard this is possible.

Note rounding up to 0.5 will probably cause floor(.49999999999999999 +
0.5)
to be 1, so the question of whether any implementation chooses a value
greater than 0.5 is entirely academic.

-William Hughes
 
J

Joe Wright

William said:
I do not know.

reread carefully

so an implementation may represent

Note that this says may. The word "may" does not indicate that
any given implementation does, or indeed that there exists an
implemenation that does. It just means that according to the
standard this is possible.

Note rounding up to 0.5 will probably cause floor(.49999999999999999 +
0.5)
to be 1, so the question of whether any implementation chooses a value
greater than 0.5 is entirely academic.

-William Hughes
I haven't trimmed this post so that others might see everything. In any
case, this my last comment on the matter. You apparently can't read what
I write. There is no case that I know where 0.4999999999999999 will
result in a value greater than 0.5 . And you don't either. Nor does
anyone else.

Happy Turkey Day.
 
S

slebetman

Joe said:
I haven't trimmed this post so that others might see everything. In any
case, this my last comment on the matter. You apparently can't read what
I write. There is no case that I know where 0.4999999999999999 will
result in a value greater than 0.5 . And you don't either. Nor does
anyone else.

Happy Turkey Day.

I haven't tried this but a float (not double) on a PIC C compiler (such
as HiTech C) might simply because it doesn't use the IEEE floating
point due to optimising for speed/space (hey, the PIC is a very small 8
bit machine).
Other than weird compilers not accurately implementing floats on 8 bit
machines there are also weird machines like the CDC and Cray which has
non IEEE conforming binary representation of floats. On these machines
the result may or may not be correct. Anyone have access to one of
these and print out their binary representation like Joe did?
 
J

Jordan Abel

I haven't tried this but a float (not double) on a PIC C compiler (such
as HiTech C) might simply because it doesn't use the IEEE floating
point due to optimising for speed/space (hey, the PIC is a very small 8
bit machine).
Other than weird compilers not accurately implementing floats on 8 bit
machines there are also weird machines like the CDC and Cray which has
non IEEE conforming binary representation of floats. On these machines
the result may or may not be correct. Anyone have access to one of
these and print out their binary representation like Joe did?

It's still hard to imagine a floating-point format in which 0.5 does not
have an exact representation. Any system based on binary, it's
1*(2**-1), and even with a decimal [bcd] system it's 5*(10**-1).

It's theoretically possible that a very bad system might get .49999... >
..5 due to cumulative rounding error [say, .4+.09+.009+.0009+.00009...],
but unlikely.
 
W

William Hughes

Joe said:
I haven't trimmed this post so that others might see everything. In any
case, this my last comment on the matter. You apparently can't read what
I write. There is no case that I know where 0.4999999999999999 will
result in a value greater than 0.5 . And you don't either. Nor does
anyone else.

Happy Turkey Day.

When discussing putative behaviour of C code there are
four common issues:

1. Behaviour dictated by the standard

2. Behaviour on common hosted implementations

3. Behaviour on non-hosted/embedded implementations

4. Behaviour on my implementation (depressingly often
i386/Microsoft vcc)

Aswers to 1. are important because these must apply to any
conforming implementation. However, in some ways the standard
is quite lax. E.g. RAND_MAX = 15 is legal, but no implementation
would provide such a thing. The answer to 1. is what
is commonly meant by "an implementation may"

Answers to 2. are important because this is what a user
may be expected to see. Of course "common" is context
dependent and a matter of opinoion. Are Cray and CDC
machines common? Should a machine designed in the
60's be considered common?

Answers to 3 can be important because this is a very
important sector for C programming, because
behaviours are often very different here, and because the
requirements of the standard are significantly different
for non-hosted systems.

Answers to 4 are usually irrelevant, and often very
wrong. Usually these take the form of examples
against a more general statment.

You said that i=1,i++ + i++ was undefined behaviour
but I tried it on my system and it gave 3 just like it
should.


My initial statement was a mix of 1 and 2 (I am
not familiar with the systems in 3). The standard
allows .4999999999999999 to be converted to a floating
point value > 0.5, but this is very unlikely. On the
other hand it is likely that some systems may convert
0.4999999999999999 to 0.5. (It is certain that some
systems will convert 0.49999999999999999 to 0.5)
The upshot is that is is likely that
floor(0.4999999999999999 +0.5) will equal 1 on some
systems (and certain that floor(0.49999999999999999 +0.5)
will equal 1 on some systems).

Your initial statement was pure 4.

You are wrong, You said that 0.4999999999999999
could be converted to a number greater than or equal
to 0.5. but I tried it on my sytem and it wasn't.

Your later statemenst mixed in some irrelevant 2

No system will convert 0.4999999999999999 to
a number greater than 0.5 (irrelevant because
mine was a staetment about legality (1.) not
whether the behaviour was common, and because
an alternate behaviour (converting to 0.5) was
both reasonable and leads to the same
undesirable result).

-William Hughes
 
K

Keith Thompson

I haven't tried this but a float (not double) on a PIC C compiler (such
as HiTech C) might simply because it doesn't use the IEEE floating
point due to optimising for speed/space (hey, the PIC is a very small 8
bit machine).
Other than weird compilers not accurately implementing floats on 8 bit
machines there are also weird machines like the CDC and Cray which has
non IEEE conforming binary representation of floats. On these machines
the result may or may not be correct. Anyone have access to one of
these and print out their binary representation like Joe did?

Note that recent Cray machines use IEEE floating point; I think only
the vector machines (T90, SV1, etc.) use Cray floating point.
 
W

William Hughes

Jordan said:
I haven't tried this but a float (not double) on a PIC C compiler (such
as HiTech C) might simply because it doesn't use the IEEE floating
point due to optimising for speed/space (hey, the PIC is a very small 8
bit machine).
Other than weird compilers not accurately implementing floats on 8 bit
machines there are also weird machines like the CDC and Cray which has
non IEEE conforming binary representation of floats. On these machines
the result may or may not be correct. Anyone have access to one of
these and print out their binary representation like Joe did?

It's still hard to imagine a floating-point format in which 0.5 does not
have an exact representation. Any system based on binary, it's
1*(2**-1), and even with a decimal [bcd] system it's 5*(10**-1).

True, but irrelevant. It is still legal for a system to convert
0.4999999999999999 to a number greater that 0.5, even if
0.5 can be represented exactly. (for quality of implementation
reasons, this will probably not happen)

-William Hughes
 
D

Dik T. Winter

> 1. Behaviour dictated by the standard
> 2. Behaviour on common hosted implementations
> 3. Behaviour on non-hosted/embedded implementations
> 4. Behaviour on my implementation (depressingly often
> i386/Microsoft vcc)
>
> My initial statement was a mix of 1 and 2 (I am
> not familiar with the systems in 3). The standard
> allows .4999999999999999 to be converted to a floating
> point value > 0.5, but this is very unlikely. On the
> other hand it is likely that some systems may convert
> 0.4999999999999999 to 0.5. (It is certain that some
> systems will convert 0.49999999999999999 to 0.5)
> The upshot is that is is likely that
> floor(0.4999999999999999 +0.5) will equal 1 on some
> systems (and certain that floor(0.49999999999999999 +0.5)
> will equal 1 on some systems).

But that is not really the problem, because in that case 0.4999...999 will
compare equal to 0.5 (assuming a well-behaved floating-point system). On
the other hand, it *is* possible that you have a number that compares
smaller than 0.5 but where adding 0.5 to that number results in 1.0.

The following program:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
double d = 0.25, r;
int i = 0;
r = d;
while(d < 0.5) {
if(d + 0.5 == 1.0) {
printf("equal at step %d\n", i);
exit(0);
}
r = r / 2;
i++;
d += r;
}
}

Will print
equal at step 52
on a Sun running Solaris, it will print
equal at step 63
on an Intel machine using gcc with -O3, and it will
print nothing on that same machine using gcc without
optimisation (but will termate). So under some circumstances
we have a number that is smaller than 0.5 but where
floor(x + 0.5) will yield 1.0.
 
D

Dik T. Winter

> Other than weird compilers not accurately implementing floats on 8 bit
> machines there are also weird machines like the CDC and Cray which has
> non IEEE conforming binary representation of floats. On these machines
> the result may or may not be correct. Anyone have access to one of
> these and print out their binary representation like Joe did?

On sane implementations when converting a number from the (decimal)
source format to the (non-decimal) internal format, the result after
conversion will not be larger than the smallest representable number
equal to or larger than the number in the source format. Cray
provided a sane implementation, so on that machine 0.4999999...999
would be <= 0.5 regardless the number of 9's.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,830
Latest member
ZADIva7383

Latest Threads

Top