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

Discussion in 'C Programming' started by Michel Rouzic, Jun 15, 2005.

  1. 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)
     
    Michel Rouzic, Jun 15, 2005
    #1
    1. Advertising

  2. Michel Rouzic

    Richard Bos Guest

    "Michel Rouzic" <> wrote:

    > 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
     
    Richard Bos, Jun 15, 2005
    #2
    1. Advertising

  3. Richard Bos wrote:
    > "Michel Rouzic" <> wrote:
    >
    > > 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


    so i gotta add .0 at the end of all my numbers in order to make it work?
     
    Michel Rouzic, Jun 15, 2005
    #3
  4. Le 15/06/2005 12:50, dans
    , « Michel Rouzic »
    <> a écrit :

    >
    >
    > Richard Bos wrote:
    >> "Michel Rouzic" <> wrote:
    >>
    >>> 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

    >
    > 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.
     
    Jean-Claude Arbaut, Jun 15, 2005
    #4
  5. Michel Rouzic wrote:
    > Richard Bos wrote:
    > > "Michel Rouzic" <> wrote:
    > >
    > > > 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

    >
    > 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
     
    David Resnick, Jun 15, 2005
    #5
  6. David Resnick wrote:
    > Michel Rouzic wrote:
    > > Richard Bos wrote:
    > > > "Michel Rouzic" <> wrote:
    > > >
    > > > > 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

    > >
    > > 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


    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
     
    Michel Rouzic, Jun 15, 2005
    #6
  7. >Michel Rouzic wrote:
    > > David Resnick wrote:
    > > 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).
    >


    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
     
    David Resnick, Jun 15, 2005
    #7
  8. Michel Rouzic

    pete Guest

    Michel Rouzic wrote:

    > 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);

    --
    pete
     
    pete, Jun 15, 2005
    #8
  9. Michel Rouzic

    akarl Guest

    Michel Rouzic wrote:
    > 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
     
    akarl, Jun 15, 2005
    #9
  10. Michel Rouzic

    pete Guest

    akarl wrote:
    >
    > 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"
    */

    --
    pete
     
    pete, Jun 15, 2005
    #10
  11. pete wrote:
    > Michel Rouzic wrote:
    >
    > > 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);
    >
    > --
    > pete


    thank you, i had never heard of that (double) thing before what you
    want to transtype before.
     
    Michel Rouzic, Jun 15, 2005
    #11
  12. Michel Rouzic wrote:
    > 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;
    }
     
    Martin Ambuhl, Jun 15, 2005
    #12
  13. Michel Rouzic

    pete Guest

    Michel Rouzic wrote:
    >
    > pete wrote:
    > > Michel Rouzic wrote:
    > >
    > > > 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);
    > >
    > > --
    > > pete

    >
    > 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.

    --
    pete
     
    pete, Jun 15, 2005
    #13
  14. In article <N8Wre.140319$>,
    akarl <> wrote:
    :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.
    --
    Beware of bugs in the above code; I have only proved it correct,
    not tried it. -- Donald Knuth
     
    Walter Roberson, Jun 15, 2005
    #14
  15. Re : pow(2, 1/2) != pow(2, 0.5) problem

    Le 15/06/2005 20:35, dans ,
    « Lawrence Kirby » <> a écrit :

    > 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 :)
     
    Jean-Claude Arbaut, Jun 15, 2005
    #15
  16. On Wed, 15 Jun 2005 13:35:41 +0000, akarl wrote:

    > Michel Rouzic wrote:
    >> 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.


    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
     
    Lawrence Kirby, Jun 15, 2005
    #16
  17. Re: Re : pow(2, 1/2) != pow(2, 0.5) problem

    On Wed, 15 Jun 2005 20:23:25 +0200, in comp.lang.c , Jean-Claude
    Arbaut <> wrote:

    >
    >
    >
    >Le 15/06/2005 20:35, dans ,
    >« Lawrence Kirby » <> a écrit :
    >
    >> 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 :)


    Thats the answer.


    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Mark McIntyre, Jun 15, 2005
    #17
  18. Michel Rouzic

    akarl Guest

    Walter Roberson wrote:
    > In article <N8Wre.140319$>,
    > akarl <> wrote:
    > :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

    </cite>

    > 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
     
    akarl, Jun 15, 2005
    #18
  19. <posted & mailed>

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

    C is correct.

    Michel Rouzic wrote:

    > 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)


    --
    Remove '.nospam' from e-mail address to reply by e-mail
     
    James McIninch, Jun 15, 2005
    #19
  20. Michel Rouzic

    akarl Guest

    Lawrence Kirby wrote:
    > When used as an operator in C / always denotes division.


    No. Tell someone on the street that 1/2 equals 0.

    >>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.


    The inexact nature of floating point numbers is a different issue.

    >>but if both operands are integers you will get the
    >>quotient of the division.

    >
    >
    > 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).

    >>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.


    Yes, but then it results in a quotient *and* a remainder. Note that it
    was confusing enough to the original poster.

    >>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.


    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
     
    akarl, Jun 16, 2005
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jimmy zhang

    math.pow rounding problem

    Jimmy zhang, Dec 4, 2004, in forum: Java
    Replies:
    15
    Views:
    3,675
    Chris Smith
    Dec 7, 2004
  2. berthelot samuel

    pow problem

    berthelot samuel, Feb 10, 2004, in forum: C Programming
    Replies:
    3
    Views:
    1,581
    Martin Dickopp
    Feb 10, 2004
  3. Clueless Moron

    math.pow vs pow

    Clueless Moron, Nov 27, 2003, in forum: Python
    Replies:
    5
    Views:
    966
    John J. Lee
    Nov 28, 2003
  4. Shaobo Hou

    pow() problem

    Shaobo Hou, Feb 22, 2005, in forum: C Programming
    Replies:
    13
    Views:
    861
    Eric Sosman
    Feb 23, 2005
  5. Bill Cunningham

    pow type problem

    Bill Cunningham, May 27, 2008, in forum: C Programming
    Replies:
    6
    Views:
    326
    Nick Keighley
    May 27, 2008
Loading...

Share This Page