By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,495 Members | 1,280 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,495 IT Pros & Developers. It's quick & easy.

sin (M_PI)

P: n/a
Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Thanks,
Adam
Jul 12 '07 #1
Share this Question
Share on Google+
70 Replies


P: n/a
On 12 Jul, 11:14, Adam <a...@sendnospam.comwrote:
Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why,
The usual issues with floating point accuracy, I'd think.
and what I can do about it?
See if your target implementation has an alternative sin()
implementation (sinl(), which takes and returns long double, may be
available for example) and a suitable definition of PI.

Jul 12 '07 #2

P: n/a
On 12 Jul, 11:26, mark_blue...@pobox.com wrote:
On 12 Jul, 11:14, Adam <a...@sendnospam.comwrote:
Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why,

The usual issues with floating point accuracy, I'd think.
and what I can do about it?

See if your target implementation has an alternative sin()
implementation (sinl(), which takes and returns long double, may be
available for example) and a suitable definition of PI.
I must give up replying to myself...

sinl() is part of the standard and should be available. Finding a good
definition of PI may be more difficult, but a GNU libc header gives:-

# define M_PIl 3.1415926535897932384626433832795029L /*
pi */

Jul 12 '07 #3

P: n/a
Adam wrote:
Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?
Firstly M_PI is not defined in Standard C, though most implementations
define it as an extension. You can also compute it's value at runtime
or define it yourself.

Secondly make sure you include stdio.h and math.h for printf and sin.
And try using the %f format specifier.

Jul 12 '07 #4

P: n/a
santosh wrote:
Adam wrote:
>Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Firstly M_PI is not defined in Standard C, though most implementations
define it as an extension. You can also compute it's value at runtime
or define it yourself.

Secondly make sure you include stdio.h and math.h for printf and sin.
And try using the %f format specifier.
Using %f works, but isn't a suitable solution, as my code is actually
printf("%g", sin(x)), where x could be pi, or something else, and %f
messes up the formatting for the other possibilities for x.
Jul 12 '07 #5

P: n/a
Adam wrote:
santosh wrote:
Adam wrote:
Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?
Firstly M_PI is not defined in Standard C, though most implementations
define it as an extension. You can also compute it's value at runtime
or define it yourself.

Secondly make sure you include stdio.h and math.h for printf and sin.
And try using the %f format specifier.
Using %f works, but isn't a suitable solution, as my code is actually
printf("%g", sin(x)), where x could be pi, or something else, and %f
messes up the formatting for the other possibilities for x.
One possibility is to compare x with M_PI and if they're near enough,
print zero.
Something like:

if(abs(M_PI - x) <= delta) puts("0000e0");

Jul 12 '07 #6

P: n/a
Adam <ad**@sendnospam.comwrote:
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?
Pi is an irrational number, i.e. you can't write it down
exactly without giving an infinite number of digits (what-
ever number system you use). Computers can't deal with
irrational numbers very well (i.e. at all) since in a
computer you can only store a finite number of digits.
Thus what you use for pi is never the true value of pi
but an approximation. So you can't expect more that an
approximation of the value of sin of pi when you use an
approximation of pi to start with.

Whenever you use floating point numbers you must consider
that the computer only stores a limited number of (binary)
digits. In many cases the number of digits that can be
stored is less than the true number of digits of the
floating point number - rather obvious for irrational
numbers like pi, but even a simple looking number like 0.1
becomes a number with infinitely many digits when expressed
in binary (like 1/3 has an infinite number of digits when
written in decimal). Thus in many (if not most) cases you
do calculations with approximations only. And that's not
the end of it. E.g. function like sin are computed using
(clever) approximate algorithms (which tend to be a limi-
ted number of summands of an infinite sum). So you do ap-
proximate calculations of functions on approximate values.
And the result is, of course, that you end up with more or
less good approximate results. And when you think of it,
1e-16 is a rather good approximation for a 0 when you con-
sider the range [-1:1] of the sin function.

Thus if you do floating point calculations you have to be
aware of the approximate nature of such computations. And
you have to be aware that small errors due to the approxi-
mations can sum up considerably - if you aren't careful
you can end up with completely bogus results.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Jul 12 '07 #7

P: n/a
santosh wrote:
Adam wrote:
santosh wrote:
Adam wrote:
>Hi,
>I am using the following code:
>printf("%g", sin(M_PI))
>and getting 1.22461e-16 instead of zero.
>Does anyone have any idea why, and what I can do about it?
>
Firstly M_PI is not defined in Standard C, though most implementations
define it as an extension. You can also compute it's value at runtime
or define it yourself.
>
Secondly make sure you include stdio.h and math.h for printf and sin.
And try using the %f format specifier.
>
Using %f works, but isn't a suitable solution, as my code is actually
printf("%g", sin(x)), where x could be pi, or something else, and %f
messes up the formatting for the other possibilities for x.

One possibility is to compare x with M_PI and if they're near enough,
print zero.
Something like:

if(abs(M_PI - x) <= delta) puts("0000e0");
Sorry about that. Use fabs instead of abs:

if(fabs(M_PI - x) <= delta) printf("%g\n", 0.0);

Jul 12 '07 #8

P: n/a
Adam wrote:
Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?
Ponder these questions:

1: Is M_PI exactly equal to pi, or is it equal to pi+x
for some small x?

2: What is the value of sin(pi+x)?

--
Eric Sosman
es*****@ieee-dot-org.invalid
Jul 12 '07 #9

P: n/a
Adam wrote:
Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?
As the other responders have pointed out, this is to be expected. If you
had opened up your search engine, you surely would have found some close
references.
As you haven't said anything about your goals for modifying this
behavior, the suggestion about sinl(M_PIl) is as good as any, keeping in
mind that default Windows behavior is for long double to be simply an
alias for double.

Think about the steps you are taking here.
M_PI (not defined in std C) is likely a truncated decimal approximation
to the irrational value of pi.
The argument to sin() is at best the nearest binary value to the decimal
value. It could be as much as DBL_EPSILON larger or smaller than the
ideal value. A little application of high school math should help you
figure out how much difference this makes to the ideal value of sin().

If you are writing the code for a compiler to use in constant
propagation, say for a target processor like x87 which has some built-in
extra precision constants, you could take the position that you should
pick the closest of those built-in constants, when it satisfies the
demands of the C standard for closeness to the value in question. This
would enable the compiler to evaluate sin(M_PI) as 0. at compile time,
but then you would have a discrepancy against the behavior of values
generated at run time. Unless you want to write a sin() function which
searches for a match to certain multiples of the built-in pi before
evaluation. Where do you draw the line? pi/4,..., INT_MAX/4*PI ?

I understand there has been academic work on the precision attainable by
math functions including sin(). When people are building careers on this
subject, can you seriously ask "does anyone have any idea?"
Jul 12 '07 #10

P: n/a
"Jens Thoms Toerring" wrote:
Adam <ad**@sendnospam.comwrote:
>I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Pi is an irrational number, i.e. you can't write it down
exactly without giving an infinite number of digits (what-
ever number system you use)
One nitpick. I think pi is transcendental rather than irrational.

http://en.wikipedia.org/wiki/Lindema...strass_theorem
Jul 12 '07 #11

P: n/a
Tim Prince wrote:
Adam wrote:
>Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

As the other responders have pointed out, this is to be expected. If you
had opened up your search engine, you surely would have found some close
references.
As you haven't said anything about your goals for modifying this
behavior, the suggestion about sinl(M_PIl) is as good as any, keeping in
mind that default Windows behavior is for long double to be simply an
alias for double.
This is wrong. The lcc-win32 compiler features full precision (80 bits
floating point) for long double. The long double equals double
feature is just a feature of one compiler system under windows:
Microsoft MSVC. Other compilers under windows offer more precision.

jacob
Jul 12 '07 #12

P: n/a
"osmium" <r1********@comcast.netwrote:
"Jens Thoms Toerring" wrote:
Adam <ad**@sendnospam.comwrote:
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?
Pi is an irrational number, i.e. you can't write it down
exactly without giving an infinite number of digits (what-
ever number system you use)

One nitpick. I think pi is transcendental rather than irrational.

http://en.wikipedia.org/wiki/Lindema...strass_theorem
Transcendental, and _therefore_ irrational. The transcendental numbers
are a strict subset of the rational ones.

Richard
Jul 12 '07 #13

P: n/a
Adam said:
Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?
Presumably M_PI represents a value close to pi. It cannot represent pi
exactly, because pi is irrational. Given the nature of a sine wave, you
can expect sin(reasonable_approximation_to_pi) to be a reasonable
approximation to 0, and indeed that is what you are getting.

If you want to round the value, decide at which decimal place or
significant figure you wish to round it, and whether you wish to round
it up, down, or nearest. Then write code to do the rounding for you.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 12 '07 #14

P: n/a
"Richard Bos" writes:
"osmium" <r1********@comcast.netwrote:
>"Jens Thoms Toerring" wrote:
Adam <ad**@sendnospam.comwrote:
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Pi is an irrational number, i.e. you can't write it down
exactly without giving an infinite number of digits (what-
ever number system you use)

One nitpick. I think pi is transcendental rather than irrational.

http://en.wikipedia.org/wiki/Lindema...strass_theorem

Transcendental, and _therefore_ irrational. The transcendental numbers
are a strict subset of the rational ones.
I already said it was a nitpick. But the subject of the thread *is*
precision, so one should use the most precise word. "Apple" is more precise
than "fruit".
Jul 12 '07 #15

P: n/a
osmium wrote:
"Jens Thoms Toerring" wrote:
>Adam <ad**@sendnospam.comwrote:
>>I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Pi is an irrational number, i.e. you can't write it down
exactly without giving an infinite number of digits (what-
ever number system you use)

One nitpick. I think pi is transcendental rather than irrational.
(fx:counter-nitpick)

All the transcendentals are irrational. "Pi isn't just irrational;
it's transcendental" is better than "... rather than ...".

It's certainly a subject one can get one's teeth into.

--
RIP Donald Michie 11 November 1923 - 7 July 2007

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England

Jul 12 '07 #16

P: n/a
osmium wrote:
I already said it was a nitpick. But the subject of the thread *is*
precision, so one should use the most precise word.
That doesn't follow. (Covariance and contravariance come to mind.
Possibly only metaphorically.)

--
RIP Donald Michie 11 November 1923 - 7 July 2007

Hewlett-Packard Limited Cain Road, Bracknell, registered no:
registered office: Berks RG12 1HN 690597 England

Jul 12 '07 #17

P: n/a
Richard Bos wrote:
Transcendental, and _therefore_ irrational. The transcendental numbers
are a strict subset of the rational ones.
s/rat/irrat/?

--
RIP Donald Michie 11 November 1923 - 7 July 2007

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England

Jul 12 '07 #18

P: n/a
>>>>"JT" == Jens Thoms Toerring <jt@toerring.dewrites:

JTPi is an irrational number, i.e. you can't write it down
JTexactly without giving an infinite number of digits (what-
JTever number system you use).

This isn't so. You can use base pi where pi becomes 10 of course 4 is
a problem. :)

See http://mathworld.wolfram.com/Base.html and
http://www.dwheeler.com/essays/bases.html

Jul 12 '07 #19

P: n/a
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
"osmium" <r1********@comcast.netwrote:
>"Jens Thoms Toerring" wrote:
Adam <ad**@sendnospam.comwrote:
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Pi is an irrational number, i.e. you can't write it down
exactly without giving an infinite number of digits (what-
ever number system you use)

One nitpick. I think pi is transcendental rather than irrational.

http://en.wikipedia.org/wiki/Lindema...strass_theorem

Transcendental, and _therefore_ irrational. The transcendental numbers
are a strict subset of the rational ones.
(s/rational/irrational/)

And the relevant point here is that pi cannot be represented exactly
as a floating-point number. That's merely because it's not an integer
multiple of a power of 2.0. The same issue can arise even for
rational numbers. For example, mathematically, sqrt(1.0/9.0) =
1.0/3.0, but neither 1.0/9.0 nor 1.0/3.0 can be represented exactly in
most floating-point systems.

(Quibble: C doesn't require binary floating-point. A trinary
floating-point system could represent 1.0/3.0 and 1.0/9.0 exactly --
but not 0.5. Conceivably a base-pi system could represent pi exactly,
but not 1.0.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 12 '07 #20

P: n/a
Eric Sosman <es*****@ieee-dot-org.invalidwrites:
Adam wrote:
>Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Ponder these questions:

1: Is M_PI exactly equal to pi, or is it equal to pi+x
for some small x?

2: What is the value of sin(pi+x)?
And if you *wanted* to compute the sine of pi+x, wouldn't you want a
correct non-zero approximation? And how is the sin() function
supposed to know the difference?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 12 '07 #21

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
Adam said:
>I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Presumably M_PI represents a value close to pi. It cannot represent pi
exactly, because pi is irrational. Given the nature of a sine wave, you
can expect sin(reasonable_approximation_to_pi) to be a reasonable
approximation to 0, and indeed that is what you are getting.

If you want to round the value, decide at which decimal place or
significant figure you wish to round it, and whether you wish to round
it up, down, or nearest. Then write code to do the rounding for you.
Or, if you're ambitious, you can do the calculation symbolically.
Rather than storing a numeric approximation to pi, store something
that explicitly refers to the symbol pi. Applying a sine function to
this symbolic value yields exactly zero (if the sine function is
implemented to work properly on symbolic values). Don't convert from
a symbolic value to a numeric value until you need to.

Note that these symbolic values can be arbitrarily complex; they're
(probably) basically expression trees, with facilities for evaluating
certain subexpressions non-numerically.

Implementing something like this would be a lot of work, but it's
useful enough that I'm sure it's already been done.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 12 '07 #22

P: n/a
On Jul 12, 6:16 am, "osmium" <r124c4u...@comcast.netwrote:
"Jens Thoms Toerring" wrote:
Adam <a...@sendnospam.comwrote:
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?
Pi is an irrational number, i.e. you can't write it down
exactly without giving an infinite number of digits (what-
ever number system you use)

One nitpick. I think pi is transcendental rather than irrational.

http://en.wikipedia.org/wiki/Lindema...strass_theorem
Since transcendental is a subset of irrational, "rather than" is not
correct.
IOW, all transcendental numbers are irrational numbers.
So you might rather have said: "The number pi is transcendental in
addition to being irrational."

Jul 12 '07 #23

P: n/a
On Jul 12, 6:30 am, "osmium" <r124c4u...@comcast.netwrote:
"Richard Bos" writes:
"osmium" <r124c4u...@comcast.netwrote:
"Jens Thoms Toerring" wrote:
Adam <a...@sendnospam.comwrote:
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?
Pi is an irrational number, i.e. you can't write it down
exactly without giving an infinite number of digits (what-
ever number system you use)
One nitpick. I think pi is transcendental rather than irrational.
>http://en.wikipedia.org/wiki/Lindema...strass_theorem
Transcendental, and _therefore_ irrational. The transcendental numbers
are a strict subset of the rational ones.

I already said it was a nitpick. But the subject of the thread *is*
precision, so one should use the most precise word. "Apple" is more precise
than "fruit".
That is true, but what he said was "It isn't a fruit. It's an apple."
Jul 12 '07 #24

P: n/a
On Thu, 12 Jul 2007 13:24:48 GMT, rl*@hoekstra-uitgeverij.nl (Richard
Bos) wrote:
>"osmium" <r1********@comcast.netwrote:
>"Jens Thoms Toerring" wrote:
Adam <ad**@sendnospam.comwrote:
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Pi is an irrational number, i.e. you can't write it down
exactly without giving an infinite number of digits (what-
ever number system you use)

One nitpick. I think pi is transcendental rather than irrational.

http://en.wikipedia.org/wiki/Lindema...strass_theorem

Transcendental, and _therefore_ irrational. The transcendental numbers
are a strict subset of the rational ones.
^^^^^^^^
in the little it seems i know the above is
"irrational"
e and pi are not element of Q but of R-Q
>Richard
Jul 12 '07 #25

P: n/a
On Jul 12, 3:14 am, Adam <a...@sendnospam.comwrote:
Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?
Since you supplied a weak approximation of pi, you got a weak
approximation of zero.

And if you had supplied an exact (infinite digits) version of pi, we
still cannot expect any floating point function to be better than +/-
0.5 ulp.

Jul 12 '07 #26

P: n/a
user923005 <dc*****@connx.comwrites:
On Jul 12, 3:14 am, Adam <a...@sendnospam.comwrote:
>Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Since you supplied a weak approximation of pi, you got a weak
approximation of zero.

And if you had supplied an exact (infinite digits) version of pi, we
still
[...]
would be waiting for you to finish writing it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 12 '07 #27

P: n/a

"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
Richard Heathfield <rj*@see.sig.invalidwrites:
>Adam said:
>>I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Presumably M_PI represents a value close to pi. It cannot represent pi
exactly, because pi is irrational. Given the nature of a sine wave, you
can expect sin(reasonable_approximation_to_pi) to be a reasonable
approximation to 0, and indeed that is what you are getting.

If you want to round the value, decide at which decimal place or
significant figure you wish to round it, and whether you wish to round
it up, down, or nearest. Then write code to do the rounding for you.

Or, if you're ambitious, you can do the calculation symbolically.
Rather than storing a numeric approximation to pi, store something
that explicitly refers to the symbol pi. Applying a sine function to
this symbolic value yields exactly zero (if the sine function is
implemented to work properly on symbolic values). Don't convert from
a symbolic value to a numeric value until you need to.

Note that these symbolic values can be arbitrarily complex; they're
(probably) basically expression trees, with facilities for evaluating
certain subexpressions non-numerically.

Implementing something like this would be a lot of work, but it's
useful enough that I'm sure it's already been done.
Check out lisp.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Jul 12 '07 #28

P: n/a

"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
>"osmium" <r1********@comcast.netwrote:
>>"Jens Thoms Toerring" wrote:
Adam <ad**@sendnospam.comwrote:
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Pi is an irrational number, i.e. you can't write it down
exactly without giving an infinite number of digits (what-
ever number system you use)

One nitpick. I think pi is transcendental rather than irrational.

http://en.wikipedia.org/wiki/Lindema...strass_theorem

Transcendental, and _therefore_ irrational. The transcendental numbers
are a strict subset of the rational ones.

(s/rational/irrational/)

And the relevant point here is that pi cannot be represented exactly
as a floating-point number. That's merely because it's not an integer
multiple of a power of 2.0. The same issue can arise even for
rational numbers. For example, mathematically, sqrt(1.0/9.0) =
1.0/3.0, but neither 1.0/9.0 nor 1.0/3.0 can be represented exactly in
most floating-point systems.

(Quibble: C doesn't require binary floating-point. A trinary
floating-point system could represent 1.0/3.0 and 1.0/9.0 exactly --
but not 0.5. Conceivably a base-pi system could represent pi exactly,
but not 1.0.)
PI^0 = 1.
The problem comes when you try to represent 4.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Jul 12 '07 #29

P: n/a

"Dale Henderson" <ni****@hotpop.comwrote in message
news:87************@hotpop.com...
>>>>>"JT" == Jens Thoms Toerring <jt@toerring.dewrites:

JTPi is an irrational number, i.e. you can't write it down
JTexactly without giving an infinite number of digits (what-
JTever number system you use).

This isn't so. You can use base pi where pi becomes 10 of course 4 is
a problem. :)
More subtly you can use base i (sqrt -1), and allow imaginary digits.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Jul 12 '07 #30

P: n/a
Keith Thompson wrote On 07/12/07 15:18,:
Eric Sosman <es*****@ieee-dot-org.invalidwrites:
>>Adam wrote:
>>>Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why, and what I can do about it?

Ponder these questions:

1: Is M_PI exactly equal to pi, or is it equal to pi+x
for some small x?

2: What is the value of sin(pi+x)?


And if you *wanted* to compute the sine of pi+x, wouldn't you want a
correct non-zero approximation? And how is the sin() function
supposed to know the difference?
Well, er, that's what I wanted his pondering to
reveal to him. He's computing

sin(pi+x)
= cos(pi)*sin(x) + sin(pi)*cos(x)
= -1*sin(x) + 0*cos(x)
= -sin(x)
= sin(-x)

.... for some small, non-zero x. Even if the sin()
implementation is extremely accurate -- in fact,
*especially* if sin() is extremely accurate! -- this
will not be zero.

Very slightly deeper analysis: with round-to-nearest,
an arbitrary real number R (in a representable range) will
be approximated by a double value D somewhere in

R * (1 +- DBL_EPSILON/2)

On most machines nowadays, DBL_EPSILON is ~= 2.2e-16 and
M_PI (if it's defined) is ~= 3.1. So the rounding error
should be no worse than about 3.1 * 2.2e-16 / 2 ~= 3.4e-16;
the 'x' is between about -3.4e-16 and +3.4e-16. For such
small values, x and sin(x) are very nearly identical; he
reports sin(-x) ~= 1.2e-16, so we can work backwards to
deduce that x was pretty close to -1.2e-16 (or else x was
huge and M_PI was grossly in error). The observed error
is thus well within the expected bounds, only about one-
third as bad as it might have been. He has no reason to
complain.

--
Er*********@sun.com
Jul 12 '07 #31

P: n/a
"Malcolm McLean" <re*******@btinternet.comwrites:
"Keith Thompson" <ks***@mib.orgwrote in message
[...]
>(Quibble: C doesn't require binary floating-point. A trinary
floating-point system could represent 1.0/3.0 and 1.0/9.0 exactly --
but not 0.5. Conceivably a base-pi system could represent pi exactly,
but not 1.0.)
PI^0 = 1.
Good point.
The problem comes when you try to represent 4.
It's approximately
10.22012202112111030100001011001001121221111110011 0222202120012203002130001

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 12 '07 #32

P: n/a
On Thu, 12 Jul 2007 22:14:22 +1200, in comp.lang.c , Adam
<ad**@sendnospam.comwrote:
>Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why,
STFW for "Goldberg floating point".
>and what I can do about it?
Don't print doubles to a precision larger than the storage limits of
your system. Doubles are only guaranteed to typically 15 significant
figures, you're printing 16.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jul 12 '07 #33

P: n/a
Mark McIntyre <ma**********@spamcop.netwrites:
On Thu, 12 Jul 2007 22:14:22 +1200, in comp.lang.c , Adam
<ad**@sendnospam.comwrote:
>>Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why,

STFW for "Goldberg floating point".
>>and what I can do about it?

Don't print doubles to a precision larger than the storage limits of
your system. Doubles are only guaranteed to typically 15 significant
figures, you're printing 16.
No, he's using "%g", which prints only 6 significant digits. It
happens that the number he's printing, because of the way he computed
it, contains very little valid information, but that's not the fault
of printf or of the format he chose.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 12 '07 #34

P: n/a
user923005 <dc*****@connx.comwrote:
Imagine if you will, an ideal rope. This rope has no sag or stretch
whatsoever.
Now, imagine three handsome, well-bearded Israelite men standing
around a giant, round brass bathtub.
For the sake of argument, we will assume that the bathtub is perfectly
circular.
Assume (further) that the bathtub does not expand or contract due to
temperature differences in sun/shadow but holds its perfect circular
shape perfectly.
Assume (finally) that these six bearded guys are exactly evenly spaced
around the bowl.
Is there some wondrous doubling of the handsome, well-bearded" men
going on? Just three sentences ago there seemed to be three of them
and now it's already six! Or didn't you count in the less-handsome,
less-well-bearded three at first? And are there some others, perhaps
ugly or non-beared (or both) still not mentioned, waiting for their
entrance?
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Jul 12 '07 #35

P: n/a
Jens Thoms Toerring said:
user923005 <dc*****@connx.comwrote:
>Imagine if you will, an ideal rope. This rope has no sag or stretch
whatsoever.
Now, imagine three handsome, well-bearded Israelite men standing
around a giant, round brass bathtub.
For the sake of argument, we will assume that the bathtub is
perfectly circular.
Assume (further) that the bathtub does not expand or contract due to
temperature differences in sun/shadow but holds its perfect circular
shape perfectly.
Assume (finally) that these six bearded guys are exactly evenly
spaced around the bowl.

Is there some wondrous doubling of the handsome, well-bearded" men
going on? Just three sentences ago there seemed to be three of them
and now it's already six! Or didn't you count in the less-handsome,
less-well-bearded three at first? And are there some others, perhaps
ugly or non-beared (or both) still not mentioned, waiting for their
entrance?
If the number of bearded men doubles every three sentences, how many
bearded men will there be after the last article to this thread has
been posted? And will this exceed the number of non-beared men
desperately searching the wilderness for bears? And if they find them,
will they arm them? If not, does that mean that the bears are armless,
or that the men are?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 12 '07 #36

P: n/a
On Jul 12, 3:58 pm, j...@toerring.de (Jens Thoms Toerring) wrote:
user923005 <dcor...@connx.comwrote:
Imagine if you will, an ideal rope. This rope has no sag or stretch
whatsoever.
Now, imagine three handsome, well-bearded Israelite men standing
around a giant, round brass bathtub.
For the sake of argument, we will assume that the bathtub is perfectly
circular.
Assume (further) that the bathtub does not expand or contract due to
temperature differences in sun/shadow but holds its perfect circular
shape perfectly.
Assume (finally) that these six bearded guys are exactly evenly spaced
around the bowl.

Is there some wondrous doubling of the handsome, well-bearded" men
going on? Just three sentences ago there seemed to be three of them
and now it's already six! Or didn't you count in the less-handsome,
less-well-bearded three at first? And are there some others, perhaps
ugly or non-beared (or both) still not mentioned, waiting for their
entrance?
It's their wives. A strange, genetic condition.
'Guys' is just a euphemism.

Jul 12 '07 #37

P: n/a
user923005 <dc*****@connx.comwrote:
On Jul 12, 3:58 pm, j...@toerring.de (Jens Thoms Toerring) wrote:
user923005 <dcor...@connx.comwrote:
Imagine if you will, an ideal rope. This rope has no sag or stretch
whatsoever.
Now, imagine three handsome, well-bearded Israelite men standing
around a giant, round brass bathtub.
For the sake of argument, we will assume that the bathtub is perfectly
circular.
Assume (further) that the bathtub does not expand or contract due to
temperature differences in sun/shadow but holds its perfect circular
shape perfectly.
Assume (finally) that these six bearded guys are exactly evenly spaced
around the bowl.
Is there some wondrous doubling of the handsome, well-bearded" men
going on? Just three sentences ago there seemed to be three of them
and now it's already six! Or didn't you count in the less-handsome,
less-well-bearded three at first? And are there some others, perhaps
ugly or non-beared (or both) still not mentioned, waiting for their
entrance?
It's their wives. A strange, genetic condition.
'Guys' is just a euphemism.
Ah, I see, these "Israelite men" are really diskworld dwarfs in
disguise. That explains a lot, including pi being equal to 3.

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Jul 12 '07 #38

P: n/a
Keith Thompson wrote:
Mark McIntyre <ma**********@spamcop.netwrites:
>On Thu, 12 Jul 2007 22:14:22 +1200, in comp.lang.c , Adam
<ad**@sendnospam.comwrote:
>>Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why,
STFW for "Goldberg floating point".
>>and what I can do about it?
Don't print doubles to a precision larger than the storage limits of
your system. Doubles are only guaranteed to typically 15 significant
figures, you're printing 16.

No, he's using "%g", which prints only 6 significant digits. It
happens that the number he's printing, because of the way he computed
it, contains very little valid information, but that's not the fault
of printf or of the format he chose.
I suggest the information is completely valid, if approximate.

sin(M_PI) here gives..

%.16e 1.2246467991473532e-16
%.16g 1.224646799147353e-16
%.16f 0.0000000000000001

...which is real close to zero. In fact the result is actually the error
in the calculation. Off by 1.2246467991473532e-16 for example.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Jul 12 '07 #39

P: n/a
jt@toerring.de (Jens Thoms Toerring) writes:
[...]
Ah, I see, these "Israelite men" are really diskworld dwarfs in
disguise. That explains a lot, including pi being equal to 3.
Quoting a line from one of Douglas Hofstadter's books:

"If pi were 3, this sentence would look like this."

except that each letter 'o' was a hexagon.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 12 '07 #40

P: n/a
On Jul 12, 4:49 pm, Keith Thompson <ks...@mib.orgwrote:
j...@toerring.de (Jens Thoms Toerring) writes:
[...]
Ah, I see, these "Israelite men" are really diskworld dwarfs in
disguise. That explains a lot, including pi being equal to 3.

Quoting a line from one of Douglas Hofstadter's books:

"If pi were 3, this sentence would look like this."

except that each letter 'o' was a hexagon.
What book was that? Someone as funny as that definitely deserves a
read.
(What is funny to me is not necessarily nearly so funny to other
people).

Jul 12 '07 #41

P: n/a
user923005 <dc*****@connx.comwrites:
On Jul 12, 4:49 pm, Keith Thompson <ks...@mib.orgwrote:
>j...@toerring.de (Jens Thoms Toerring) writes:
[...]
Ah, I see, these "Israelite men" are really diskworld dwarfs in
disguise. That explains a lot, including pi being equal to 3.

Quoting a line from one of Douglas Hofstadter's books:

"If pi were 3, this sentence would look like this."

except that each letter 'o' was a hexagon.

What book was that? Someone as funny as that definitely deserves a
read.
(What is funny to me is not necessarily nearly so funny to other
people).
I think it was "Metamagical Themas". (The other book of his that I've
read is "Godel, Escher, Bach", but I don't think it was there.)

And this has now gone *completely* off-topic. Rather than adding an
"OT:" tag, I'll just stop posting.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 13 '07 #42

P: n/a
Joe Wright wrote:
I suggest the information is completely valid, if approximate.

sin(M_PI) here gives..

%.16e 1.2246467991473532e-16
%.16g 1.224646799147353e-16
%.16f 0.0000000000000001

..which is real close to zero. In fact the result is actually the error
in the calculation. Off by 1.2246467991473532e-16 for example.
So why do sin(M_PI/2.0) and sin(M_PI_2) both give exactly 1?
%.30e 1.000000000000000000000000000000e+00
%.30g 1
%.30f 1.000000000000000000000000000000
Jul 13 '07 #43

P: n/a
"Malcolm McLean" <re*******@btinternet.comwrote:
>
"Dale Henderson" <ni****@hotpop.comwrote in message
news:87************@hotpop.com...
>>>>"JT" == Jens Thoms Toerring <jt@toerring.dewrites:
JTPi is an irrational number, i.e. you can't write it down
JTexactly without giving an infinite number of digits (what-
JTever number system you use).

This isn't so. You can use base pi where pi becomes 10 of course 4 is
a problem. :)
More subtly you can use base i (sqrt -1), and allow imaginary digits.
No, you can't. And you can't use pi, either.

# 5.2.4.2.2 Characteristics of floating types <float.h>
...
# b base or radix of exponent representation (an integer 1)

Note: integer. Ternary floating point arithmetic is allowed in C, as is
(probably more commonly; IIRC at least one implementation actually used
it) hexadecimal-based FP. But bases pi and i are not integral.

Of course, in mathematics, matters are different. But mathematics deals
with infinite precision, while C deals with the real world, where
everything exists only in quanta.

Richard
Jul 13 '07 #44

P: n/a
Adam said:
Joe Wright wrote:
>I suggest the information is completely valid, if approximate.

sin(M_PI) here gives..

%.16e 1.2246467991473532e-16
%.16g 1.224646799147353e-16
%.16f 0.0000000000000001

..which is real close to zero. In fact the result is actually the
error in the calculation. Off by 1.2246467991473532e-16 for example.

So why do sin(M_PI/2.0) and sin(M_PI_2) both give exactly 1?
What is the lowest value lower than but close to M_PI / 2.0 that gives
exactly 1 as a result? What is the highest value higher than but close
to M_PI / 2.0 that gives exactly 1 as a result?

Once you've found out this information, you will probably find that it
answers your question.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jul 13 '07 #45

P: n/a
Adam <ad**@sendnospam.comwrites:
Joe Wright wrote:
>I suggest the information is completely valid, if approximate.
sin(M_PI) here gives..
%.16e 1.2246467991473532e-16
%.16g 1.224646799147353e-16
%.16f 0.0000000000000001
..which is real close to zero. In fact the result is actually the
error in the calculation. Off by 1.2246467991473532e-16 for example.

So why do sin(M_PI/2.0) and sin(M_PI_2) both give exactly 1?
%.30e 1.000000000000000000000000000000e+00
%.30g 1
%.30f 1.000000000000000000000000000000
Think about the shape of the graph for the sin function (it looks
remarkably similar to a sine curve). For arguments near pi, the curve
has a slope near -1; a small change in the argument creates a nearly
equal change in the result, in the opposite direction. For example,
sin(pi + 0.001) is very close to -0.001. And values *very* close to
0.0 can be represented in floating-point.

On the other hand the slope for arguments near pi/2 is 0 (the curve is
locally horizontal), so a small change in the argument produces a
*very* small change in the result. Furthermore, floating-point
represents values very close to 1.0 with much less precision than
values very close to 0.0. (Take a look at values of cos(x) for values
of x near 0.0.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 13 '07 #46

P: n/a
On Thu, 12 Jul 2007 15:18:13 -0700, in comp.lang.c , Keith Thompson
<ks***@mib.orgwrote:
>Mark McIntyre <ma**********@spamcop.netwrites:
>On Thu, 12 Jul 2007 22:14:22 +1200, in comp.lang.c , Adam
<ad**@sendnospam.comwrote:
>>>Hi,
I am using the following code:
printf("%g", sin(M_PI))
and getting 1.22461e-16 instead of zero.
Does anyone have any idea why,

STFW for "Goldberg floating point".
>>>and what I can do about it?

Don't print doubles to a precision larger than the storage limits of
your system. Doubles are only guaranteed to typically 15 significant
figures, you're printing 16.

No, he's using "%g", which prints only 6 significant digits.
Indeed. I should have said 'decimal places' not SF.
>It
happens that the number he's printing, because of the way he computed
it, contains very little valid information, but that's not the fault
of printf or of the format he chose.
In fact it is ALSO the fault of the print format he used since %g
prints significant figures if the %f form is excessively long. Had he
printed it with %f, he'd either have got the answer he expected (eg
0.000000) or had to massively increase the digits to see the delta.


--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jul 13 '07 #47

P: n/a
On Fri, 13 Jul 2007 18:06:14 +1200, in comp.lang.c , Adam
<ad**@sendnospam.comwrote:
>So why do sin(M_PI/2.0) and sin(M_PI_2) both give exactly 1?
If I were implementing a sin() function, I'd check for special
cases...

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jul 13 '07 #48

P: n/a
On Jul 12, 11:06 pm, Adam <a...@sendnospam.comwrote:
Joe Wright wrote:
I suggest the information is completely valid, if approximate.
sin(M_PI) here gives..
%.16e 1.2246467991473532e-16
%.16g 1.224646799147353e-16
%.16f 0.0000000000000001
..which is real close to zero. In fact the result is actually the error
in the calculation. Off by 1.2246467991473532e-16 for example.

So why do sin(M_PI/2.0) and sin(M_PI_2) both give exactly 1?
%.30e 1.000000000000000000000000000000e+00
%.30g 1
%.30f 1.000000000000000000000000000000
Probably compiler magic. It's the *wrong* answer. Think about it --
neither M_PI nor M_PI_2 is equal to pi or pi/2 (for obvious reasons --
it's literally impossible for them to contain the right answer).
Jul 13 '07 #49

P: n/a
Mark McIntyre wrote:
On Fri, 13 Jul 2007 18:06:14 +1200, in comp.lang.c , Adam
<ad**@sendnospam.comwrote:
>So why do sin(M_PI/2.0) and sin(M_PI_2) both give exactly 1?

If I were implementing a sin() function, I'd check for special
cases...
How about this:

y = sin(x)
answer = (fabs(y)<1e-15) ? 0 : y ;
Jul 13 '07 #50

70 Replies

This discussion thread is closed

Replies have been disabled for this discussion.