pow(2, 1/2) != pow(2, 0.5) problem

M

Michel Rouzic

I obtain an unwanted behavior from the pow() function :

when performing pow(2, 0.5), i obtain 1.414214
when performing pow(2, 1/2), i obtain 1.000000
when performing a=0.5; pow(2, a), i obtain 1.414214
when performing a=1/2; pow(2, a), i obtain 1.000000

how come??? and how can i do a pow(x, y) so my y is the fraction of two
other variables? (cuz for now it acts as if that fraction of two
variables in y was truncated)
 
R

Richard Bos

Michel Rouzic said:
I obtain an unwanted behavior from the pow() function :

when performing pow(2, 0.5), i obtain 1.414214
when performing pow(2, 1/2), i obtain 1.000000

Your problem is not with pow(); it is with integer maths. How much is
1/2, again? And 1.0/2?

Richard
 
M

Michel Rouzic

Richard said:
Your problem is not with pow(); it is with integer maths. How much is
1/2, again? And 1.0/2?

Richard

so i gotta add .0 at the end of all my numbers in order to make it work?
 
J

Jean-Claude Arbaut

Le 15/06/2005 12:50, dans
(e-mail address removed), « Michel Rouzic »
so i gotta add .0 at the end of all my numbers in order to make it work?

It's a good habit I would say... Otherwise one day you will forget, and
write 1/2 again, but in a place it will very difficult to find.
 
D

David Resnick

Michel said:
so i gotta add .0 at the end of all my numbers in order to make it work?

You "gotta" do no such thing. You just need to understand how
these things work. Arithmetic is based on the types of the operands.
If you divide an integer by an integer, you get an integer result.
If you divide an integer by a double, the integer is promoted to a
double
and the result is a double. Hence, you could do any of these:

1.0/2
(double)1/2
1/2.0
1/(double)2
1.0/2.0 /* Probably the clearest, but all work */

Don't do this though:
(double)(1/2)
The cast would be applied too late...

If any of the above is wrong, no doubt I'll be corrected :)

-David
 
M

Michel Rouzic

David said:
You "gotta" do no such thing. You just need to understand how
these things work. Arithmetic is based on the types of the operands.
If you divide an integer by an integer, you get an integer result.
If you divide an integer by a double, the integer is promoted to a
double
and the result is a double. Hence, you could do any of these:

1.0/2
(double)1/2
1/2.0
1/(double)2
1.0/2.0 /* Probably the clearest, but all work */

Don't do this though:
(double)(1/2)
The cast would be applied too late...

If any of the above is wrong, no doubt I'll be corrected :)

-David

oh ok, i never know whether i get a float or int result, i mean, in my
case i had to do 1.0/(int variable).

how would i do if i wanted to divide two integers as if they were
floats without using some variable to transtype? just being curious
 
D

David Resnick

Michel said:
oh ok, i never know whether i get a float or int result, i mean, in my
case i had to do 1.0/(int variable).

The result you get is based on the type. If you have constants,
things of the form "1" are integer constants, and things of the
form "1.0" are double constants. If you do an operation on two
integers, the result is an integer. If you do an operation on
a double and an integer, the result is a double. For other
types (and unsigned vs signed stuff), consult the standard
or a text to see how promotions work.
how would i do if i wanted to divide two integers as if they were
floats without using some variable to transtype? just being curious

I showed you 5 ways. What is your queston here? If you
mean a way to interprete 1/2 as division of two floats,
well, you can't. They are integers, and how the division
works is governed by the C standard. You need to cast or do
1.0/2 etc.

Do you mean how to divide a/b with a and b interpreted as doubles?
int a=1;
int b=2;
You just need to cast one of them, as in
double c = (double)a/b;

-David
 
P

pete

Michel said:
oh ok, i never know whether i get a float or int result, i mean, in my
case i had to do 1.0/(int variable).

Actually, 1.0 is of type double.
how would i do if i wanted to divide two integers as if they were
floats without using some variable to transtype? just being curious

printf("%f\n", (double)1 / 2);
 
A

akarl

Michel said:
I obtain an unwanted behavior from the pow() function :

when performing pow(2, 0.5), i obtain 1.414214
when performing pow(2, 1/2), i obtain 1.000000
when performing a=0.5; pow(2, a), i obtain 1.414214
when performing a=1/2; pow(2, a), i obtain 1.000000

how come??? and how can i do a pow(x, y) so my y is the fraction of two
other variables? (cuz for now it acts as if that fraction of two
variables in y was truncated)

In C, `/' is sometimes used to denote division and sometimes not. If at
least one of the operands is a floating point number you will get the
expected result, but if both operands are integers you will get the
quotient of the division. This is one example of how C uses a familiar
symbol and makes it do something unexpected (the assignment operator is
another example). At least some languages got it right (e.g. Oberon) and
use for instance `:=' for assignment and `DIV' for the quotient of
division of integers.

Furthermore, when familiar symbols have a classical interpretation and a
"C" interpretation, how do we unambiguously express things like `x = y'
and `1/2' in source code comments?


-- August
 
P

pete

akarl said:
Furthermore, when familiar symbols have a classical
interpretation and a
"C" interpretation,
how do we unambiguously express things like `x = y'
and `1/2' in source code comments?

/*
** You're allowed to use English in source code comments
** and you can say things like "one half"
*/
 
M

Michel Rouzic

pete said:
Actually, 1.0 is of type double.


printf("%f\n", (double)1 / 2);

thank you, i had never heard of that (double) thing before what you
want to transtype before.
 
M

Martin Ambuhl

Michel said:
I obtain an unwanted behavior from the pow() function :

when performing pow(2, 0.5), i obtain 1.414214
when performing pow(2, 1/2), i obtain 1.000000

1/2 = 0
pow(2, 1/2) = pow(2, 0) = 1
pow (2, 1./2) = pow(2, 1/2.) = pow(2, 0.5)
when performing a=0.5; pow(2, a), i obtain 1.414214
when performing a=1/2; pow(2, a), i obtain 1.000000

1/2 = 0
see above.
how come???

When you do arithmetic on integers, the arithmetic is done on integers.
What a surprize.
and how can i do a pow(x, y) so my y is the fraction of two
other variables?

This question is not related to the above.
in pow(2, 1/2) the power is the integer quotient of two integral
constants and has nothing to do with variables.

#include <math.h>
int main(void)
{
double a = 1, b = 2, x = 2, y, z;
y = a / b; /* "my y is the fraction of two other variables" */
z = pow(x, y);
return 0;
}
 
P

pete

Michel said:
thank you, i had never heard of that (double) thing before what you
want to transtype before.

It's a cast.
A cast converts the type and value of an expression to another.
 
W

Walter Roberson

:In C, `/' is sometimes used to denote division and sometimes not. If at
:least one of the operands is a floating point number you will get the
:expected result, but if both operands are integers you will get the
:quotient of the division. This is one example of how C uses a familiar
:symbol and makes it do something unexpected (the assignment operator is
:another example). At least some languages got it right (e.g. Oberon) and
:use for instance `:=' for assignment and `DIV' for the quotient of
:division of integers.

:Furthermore, when familiar symbols have a classical interpretation and a
:"C" interpretation,

The Oberon Report indicates that / is "quotient" and DIV is
"integer quotient". You indicated that in C if both operands are
integers that you will get the "quotient" -- the same word used by
Oberon but with different meaning. What you wrote is thus inconsistant
with Oberon, so if Oberon "got it right" then either:
a) you "got it wrong" or;
b) you must admit that words and symbols are inherently ambiguous
and contextual.

http://www.oberon.ethz.ch/oreport.html#Expressions


If you are going to talk about "classical" interpretations
and "familiar symbols", then Oberon does *not* "get it right".
The "classical" meaning of / (solidus), dating back hundreds of
years, is as a seperator between shilling and pence in writing currency.
The use of solidus as meaning division only goes back a little over
a hundred years according to OED. The use of the solidus as
integer division in C (1972) is directly taken from the same use
in Kerninghan's B (1970) -- predating the decimalization of
UK coinage in 1971. Thus if you want to argue that C should have
adopted "classical" usages, then the use of the solidus should
indicate values in which the first portion is weighted 20 times the
second portion.

But you shouldn't even blame Kerninghan's "B" language. The use
of the solidus for integer division goes at least as far back
as the original FORTRAN specification in 1954. I refer you to
"D. FIXED POINT EXPRESSIONS" in
http://community.computerhistory.org/scc/projects/FORTRAN/BackusEtAl-Preliminary Report-1954.pdf

C's use of the solidus was thus "the familiar symbol" *to programmers*.
And if you read the history of C, you will note that Kerninghan and
Ritchie were not -intending- to write a language to be widely adopted
by the general public -- they weren't -intending- to write an
replacement for (say) Algol 68.
 
J

Jean-Claude Arbaut

Le 15/06/2005 20:35, dans (e-mail address removed),
« Lawrence Kirby » said:
For example some people (based on previous experience in the
newsgroup) expect 1.0/10.0 to give a result of one tenth. On most
implementations out there they would be wrong.

Could you explain ? If it's just the "0.1 is not representable"
problem, forget my question :)
 
L

Lawrence Kirby

In C, `/' is sometimes used to denote division and sometimes not.

When used as an operator in C / always denotes division.
If at
least one of the operands is a floating point number you will get the
expected result,

That depends on what you expect. Expectations on this sort of thing do
vary. For example some people (based on previous experience in the
newsgroup) expect 1.0/10.0 to give a result of one tenth. On most
implementations out there they would be wrong.
but if both operands are integers you will get the
quotient of the division.

And for many people that is the expected result. :)
This is one example of how C uses a familiar
symbol and makes it do something unexpected (the assignment operator is
another example).

As far as I know / is recognised in mathematics for operations on integer
domains, so C isn't doing anything abnormal here.
At least some languages got it right (e.g. Oberon) and
use for instance `:=' for assignment and `DIV' for the quotient of
division of integers.

I agree that C would have been better off using := for assignment
and = for comparison, but it isn't a big deal. However / seems more
natural for division. Unless you also want create differrent operators for
integer addition, subtraction and multiplication.
Furthermore, when familiar symbols have a classical interpretation and a
"C" interpretation, how do we unambiguously express things like `x = y'
and `1/2' in source code comments?

If you mean x == y then write that, it is unambiguous. In general if there
is a C interpretation that is likely to be taken unless the context
indicates clearly otherwise.

Lawrence
 
M

Mark McIntyre

Le 15/06/2005 20:35, dans (e-mail address removed),


Could you explain ? If it's just the "0.1 is not representable"
problem, forget my question :)

Thats the answer.
 
A

akarl

Walter said:
:In C, `/' is sometimes used to denote division and sometimes not. If at
:least one of the operands is a floating point number you will get the
:expected result, but if both operands are integers you will get the
:quotient of the division. This is one example of how C uses a familiar
:symbol and makes it do something unexpected (the assignment operator is
:another example). At least some languages got it right (e.g. Oberon) and
:use for instance `:=' for assignment and `DIV' for the quotient of
:division of integers.

:Furthermore, when familiar symbols have a classical interpretation and a
:"C" interpretation,

The Oberon Report indicates that / is "quotient" and DIV is
"integer quotient". You indicated that in C if both operands are
integers that you will get the "quotient" -- the same word used by
Oberon but with different meaning. What you wrote is thus inconsistant
with Oberon, so if Oberon "got it right" then either:
a) you "got it wrong" or;
b) you must admit that words and symbols are inherently ambiguous
and contextual.

In the March 1995 edition of "The Programming Language Oberon-2",
section 8.2.2, `/' is called "real quotient". Hence there is no
inconsistency or ambiguity.
(http://control.ee.ethz.ch/edu/ciat1-WS9899/Oberon2.Report.pdf)

According to page 6 in "Abstract Algebra" (second edition) by J. A.
Beachy & W. D. Blair:

<cite>
In familiar terms, the division algorithm states that dividing an
integer a by a positive integer b gives a quotient q and a non-negative
remainder r, such that r is less than b. You might write this as

a / b = q + r / b

If you are going to talk about "classical" interpretations
and "familiar symbols", then Oberon does *not* "get it right".
The "classical" meaning of / (solidus), dating back hundreds of
years, is as a seperator between shilling and pence in writing currency.
The use of solidus as meaning division only goes back a little over
a hundred years according to OED. The use of the solidus as
integer division in C (1972) is directly taken from the same use
in Kerninghan's B (1970) -- predating the decimalization of
UK coinage in 1971. Thus if you want to argue that C should have
adopted "classical" usages, then the use of the solidus should
indicate values in which the first portion is weighted 20 times the
second portion.

Come on! `/' as a currency separator is neither widely known, nor of
current interest in a programming language.
But you shouldn't even blame Kerninghan's "B" language. The use
of the solidus for integer division goes at least as far back
as the original FORTRAN specification in 1954. I refer you to
"D. FIXED POINT EXPRESSIONS" in
http://community.computerhistory.org/scc/projects/FORTRAN/BackusEtAl-Preliminary Report-1954.pdf

C's use of the solidus was thus "the familiar symbol" *to programmers*.
And if you read the history of C, you will note that Kerninghan and
Ritchie were not -intending- to write a language to be widely adopted
by the general public -- they weren't -intending- to write an
replacement for (say) Algol 68.

Ok, this makes some sense.


-- August
 
J

James McIninch

<posted & mailed>

1 and 2 are integers.
So by integer division 1/2 = 0.
2 to the 0 power is 1.

C is correct.
 
A

akarl

Lawrence said:
When used as an operator in C / always denotes division.

No. Tell someone on the street that 1/2 equals 0.
That depends on what you expect. Expectations on this sort of thing do
vary. For example some people (based on previous experience in the
newsgroup) expect 1.0/10.0 to give a result of one tenth. On most
implementations out there they would be wrong.

The inexact nature of floating point numbers is a different issue.
And for many people that is the expected result. :)

No, at least not according to the terminology used in "Abstract Algebra"
(see my previous post).
As far as I know / is recognised in mathematics for operations on integer
domains, so C isn't doing anything abnormal here.

Yes, but then it results in a quotient *and* a remainder. Note that it
was confusing enough to the original poster.
I agree that C would have been better off using := for assignment
and = for comparison, but it isn't a big deal. However / seems more
natural for division.

It is, if it gives a floating point result. On the other hand, if for
instance 1/2 = 0 it's not division, it's something else.
Unless you also want create differrent operators for
integer addition, subtraction and multiplication.

Why would you want to do that?


-- August
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top